diff --git a/Frontend/public/OpenVCS-40.png b/Frontend/public/OpenVCS-40.png
new file mode 100644
index 00000000..6ad1758e
--- /dev/null
+++ b/Frontend/public/OpenVCS-40.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bbeae2ec07c2a22e4ef8f282c0f375b6307e88ba1970f34771c6ef3e75c0fb51
+size 2996
diff --git a/Frontend/src/modals/about.html b/Frontend/src/modals/about.html
index 6d609298..40be8362 100644
--- a/Frontend/src/modals/about.html
+++ b/Frontend/src/modals/about.html
@@ -8,12 +8,16 @@
About OpenVCS
-
- OV
-
+
diff --git a/Frontend/src/scripts/features/about.ts b/Frontend/src/scripts/features/about.ts
index c0d8f26f..7ac46898 100644
--- a/Frontend/src/scripts/features/about.ts
+++ b/Frontend/src/scripts/features/about.ts
@@ -9,6 +9,24 @@ function q(sel: string, root: ParentNode): T | null {
return root.querySelector(sel) as T | null;
}
+/** Sets an element's text content and hides it when the value is empty. */
+function setOptionalText(element: HTMLElement | null, value: string): void {
+ if (!element) return;
+
+ element.textContent = value;
+ element.style.display = value ? "" : "none";
+}
+
+/** Sets an optional link and hides it when no URL is available. */
+function setOptionalLink(element: HTMLAnchorElement | null, href: string): void {
+ if (!element) return;
+
+ element.href = href;
+ element.toggleAttribute("disabled", !href);
+ element.style.display = href ? "" : "none";
+}
+
+/** Opens the About modal and hydrates its build metadata. */
export async function openAbout(): Promise {
// Ensure the fragment is injected & visible
openModal("about-modal");
@@ -21,35 +39,43 @@ export async function openAbout(): Promise {
| {
version?: string;
build?: string;
+ authors?: string;
homepage?: string;
repository?: string;
}
| null;
+ const aboutLogo = q("#about-logo", modal);
const aboutVersion = q("#about-version", modal);
const aboutBuild = q("#about-build", modal);
+ const aboutAuthor = q("#about-author", modal);
const aboutHome = q("#about-home", modal);
const aboutRepo = q("#about-repo", modal);
const aboutLicenses = q("#about-licenses", modal);
+ const authors = info?.authors
+ ?.split(":")
+ .map((author) => author.trim())
+ .filter(Boolean)
+ .join(", ");
+ if (aboutLogo) {
+ aboutLogo.onerror = () => {
+ aboutLogo.style.display = "none";
+ };
+ aboutLogo.src = `${import.meta.env.BASE_URL}OpenVCS-40.png`;
+ }
if (aboutVersion) aboutVersion.textContent = info?.version ? `v${info.version}` : "";
- if (aboutBuild) aboutBuild.textContent = info?.build ?? "";
+ setOptionalText(aboutBuild, info?.build ?? "");
+ setOptionalText(aboutAuthor, authors ? `By ${authors}` : "");
- if (aboutHome) {
- aboutHome.href = info?.homepage || "#";
- aboutHome.toggleAttribute("disabled", !info?.homepage);
- }
- if (aboutRepo) {
- aboutRepo.href = info?.repository || "#";
- aboutRepo.toggleAttribute("disabled", !info?.repository);
- }
+ setOptionalLink(aboutHome, info?.homepage || "");
+ setOptionalLink(aboutRepo, info?.repository || "");
if (aboutLicenses) {
const rawRepo = info?.repository || "";
const repo = rawRepo.replace(/\.git$/, "").replace(/\/+$/, "");
- const licenseUrl = repo ? `${repo}/blob/HEAD/LICENSE` : "#";
- aboutLicenses.href = licenseUrl;
- aboutLicenses.toggleAttribute("disabled", !repo);
+ const licenseUrl = repo ? `${repo}/blob/HEAD/LICENSE` : "";
+ setOptionalLink(aboutLicenses, licenseUrl);
}
} catch {
notify("Unable to load About");
diff --git a/docs/images/logos/OpenVCS-40.png b/docs/images/logos/OpenVCS-40.png
new file mode 100644
index 00000000..6ad1758e
--- /dev/null
+++ b/docs/images/logos/OpenVCS-40.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bbeae2ec07c2a22e4ef8f282c0f375b6307e88ba1970f34771c6ef3e75c0fb51
+size 2996