feat(notes): banner when viewing an older shared version
All checks were successful
CI / verify (push) Successful in 1m3s

Cache the note path on each snapshot so an old shared sha can find its
current version, and show a calm "older shared version — View latest"
banner. The exact snapshot is shown as-is; the banner only offers a jump
to the latest, never swapping content.
This commit is contained in:
Julien Calixte
2026-06-29 01:04:51 +02:00
parent 2f8d3c24a4
commit 9d27aa024f
6 changed files with 106 additions and 2 deletions

View File

@@ -21,7 +21,8 @@ export const buildNoteDocs = (
_id: generateId(DataType.Note, sha),
$type: DataType.Note,
content,
editedSha
editedSha,
path
}
return path
? [base, { ...base, _id: generateId(DataType.Note, path) }]
@@ -71,7 +72,8 @@ export const prepareNoteCache = (sha: string, path?: string) => {
_id: contentId,
$type: DataType.Note,
content,
editedSha: params?.editedSha
editedSha: params?.editedSha,
path: params?.path ?? path
}
if (params && params.path) {

View File

@@ -4,6 +4,9 @@ import { Model } from "@/data/models/Model"
export interface Note extends Model<DataType.Note> {
content: string
editedSha?: string
// The note's path, stored so a cached snapshot can find its latest version
// even when its (old) sha is no longer in the repo file list.
path?: string
}
export interface PublicNoteListItem {

View File

@@ -0,0 +1,23 @@
import { describe, expect, it } from "vitest"
import { latestShaIfOlder } from "./snapshotStatus"
const files = [
{ path: "notes/a.md", sha: "current" },
{ path: "notes/b.md", sha: "other" }
]
describe("latestShaIfOlder", () => {
it("returns the current sha when viewing an older version of a known note", () => {
expect(latestShaIfOlder("old", "notes/a.md", files)).toBe("current")
})
it("returns null when viewing the current version", () => {
expect(latestShaIfOlder("current", "notes/a.md", files)).toBeNull()
})
it("returns null when the path is unknown", () => {
expect(latestShaIfOlder("old", undefined, files)).toBeNull()
expect(latestShaIfOlder("old", "notes/missing.md", files)).toBeNull()
})
})

View File

@@ -0,0 +1,25 @@
/**
* Return the note's current (latest) sha when `viewedSha` is NOT it — i.e. you
* are viewing an older version — otherwise null. "Older" is not inferred from
* the sha (a content hash has no order); it means "not the current sha for this
* path" per the repo file list.
*
* The caller must supply `notePath`. For a current sha it comes from the file
* list; for an older sha it comes from the cached snapshot's stored `path`
* (notes viewed while current carry it). When the path can't be resolved
* (foreign / evicted / pre-upgrade snapshot) this returns null and no banner is
* shown — graceful, never a false claim. Content is never swapped.
*/
export const latestShaIfOlder = (
viewedSha: string,
notePath: string | undefined,
files: ReadonlyArray<{ path?: string; sha?: string }>
): string | null => {
if (!notePath) {
return null
}
const currentSha = files.find((file) => file.path === notePath)?.sha
return currentSha && currentSha !== viewedSha ? currentSha : null
}