feat(file-viewer): browse a versioned file's git history
Nightly Build / build (push) Successful in 8m5s
Nightly Build / build (push) Successful in 8m5s
A clock button in the file viewer header lists the versions of a file whose project keeps a git history; picking one shows the file as of that commit, read-only, with a banner back to the current version. A past version is never served from the working tree: the whole repository is materialized at that revision (git archive streamed through tar into a size-bounded, immutable-by-rev cache) and every fetch — content, compiled LaTeX, markdown images, downloads — resolves inside that tree, so dependencies are contemporaneous with the file: a .tex compiles against its \input's and images of that moment. Backend: new git_versions module (repo discovery bounded by the workspace mount, host-git log/rev-parse/archive, extraction cache with oldest-first prune) + GET /api/file/versions and a rev param on GET /api/file (rev is the ETag; never X-Writable). Frontend: history mode in FileViewerBase shared by the desktop and mobile viewers — popover, banner, watcher paused while browsing, rev propagated to every /api/file URL it builds.
This commit is contained in:
@@ -260,6 +260,102 @@
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* ── History mode (git versions) ───────────────────────────────────────────── */
|
||||
|
||||
.fv-history {
|
||||
position: relative;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
/* Transparent click-catcher that closes the popover on outside click. */
|
||||
.fv-history-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 1040;
|
||||
}
|
||||
|
||||
.fv-history-pop {
|
||||
position: absolute;
|
||||
top: calc(100% + 6px);
|
||||
right: 0;
|
||||
z-index: 1050;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 2px;
|
||||
min-width: 260px;
|
||||
max-width: min(340px, 80vw);
|
||||
max-height: 320px;
|
||||
overflow-y: auto;
|
||||
padding: 4px;
|
||||
background: var(--card-bg);
|
||||
border: 1px solid var(--card-border);
|
||||
border-radius: var(--radius-md);
|
||||
box-shadow: var(--card-shadow);
|
||||
}
|
||||
|
||||
.fv-history-row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1px;
|
||||
padding: 0.45rem 0.6rem;
|
||||
text-align: left;
|
||||
background: none;
|
||||
border: 0;
|
||||
border-radius: var(--radius-sm);
|
||||
color: var(--bs-body-color);
|
||||
cursor: pointer;
|
||||
}
|
||||
.fv-history-row:hover { background: var(--sidebar-hover); }
|
||||
.fv-history-row.active { background: var(--sidebar-active-bg); }
|
||||
|
||||
.fv-history-date {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.4rem;
|
||||
font-size: 0.72rem;
|
||||
color: var(--bs-secondary-color);
|
||||
}
|
||||
|
||||
.fv-history-current {
|
||||
padding: 0 0.35rem;
|
||||
font-size: 0.66rem;
|
||||
border-radius: 999px;
|
||||
background: var(--accent-soft);
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.fv-history-subject {
|
||||
font-size: 0.8rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* Banner shown between header and body while viewing a past revision. */
|
||||
.fv-version-banner {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 0.6rem;
|
||||
padding: 0.45rem 0.85rem;
|
||||
background: var(--bs-info-bg-subtle, #cff4fc);
|
||||
border-bottom: 1px solid var(--bs-info-border-subtle, #9eeaf9);
|
||||
color: var(--bs-emphasis-color, inherit);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.fv-version-banner > .bi {
|
||||
color: var(--bs-info-text-emphasis, #055160);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.fv-version-text {
|
||||
flex: 1 1 200px;
|
||||
min-width: 0;
|
||||
font-size: 0.82rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* ── PDF preview ─────────────────────────────────────────────────────────────── */
|
||||
|
||||
/* PDFs are drawn by <pdf-view> (web/components/shared/pdf-view.js) on canvas, not
|
||||
|
||||
Reference in New Issue
Block a user