Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Frontend/public/OpenVCS-40.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 7 additions & 3 deletions Frontend/src/modals/about.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ <h3 id="about-title" style="margin:0">About OpenVCS</h3>
</div>
<section class="sheet-body" style="display:grid; gap:.8rem;">
<div style="display:flex; align-items:center; gap:.8rem;">
<div style="width:40px; height:40px; border-radius:8px; background:var(--surface-2); display:flex; align-items:center; justify-content:center; font-weight:700;">
OV
</div>
<img
id="about-logo"
src=""
alt="OpenVCS logo"
style="width:40px; height:40px; border-radius:8px; object-fit:cover; display:block;"
/>
<div>
<div style="font-weight:700;">OpenVCS <span id="about-version" style="font-weight:400; color:var(--muted)"></span></div>
<div id="about-build" style="font-size:.85rem; color:var(--muted)"></div>
<div id="about-author" style="font-size:.85rem; color:var(--muted)"></div>
</div>
</div>

Expand Down
50 changes: 38 additions & 12 deletions Frontend/src/scripts/features/about.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@ function q<T extends HTMLElement>(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<void> {
// Ensure the fragment is injected & visible
openModal("about-modal");
Expand All @@ -21,35 +39,43 @@ export async function openAbout(): Promise<void> {
| {
version?: string;
build?: string;
authors?: string;
homepage?: string;
repository?: string;
}
| null;

const aboutLogo = q<HTMLImageElement>("#about-logo", modal);
const aboutVersion = q<HTMLElement>("#about-version", modal);
const aboutBuild = q<HTMLElement>("#about-build", modal);
const aboutAuthor = q<HTMLElement>("#about-author", modal);
const aboutHome = q<HTMLAnchorElement>("#about-home", modal);
const aboutRepo = q<HTMLAnchorElement>("#about-repo", modal);
const aboutLicenses = q<HTMLAnchorElement>("#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");
Expand Down
3 changes: 3 additions & 0 deletions docs/images/logos/OpenVCS-40.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading