feat(notes): banner when viewing an older shared version
All checks were successful
CI / verify (push) Successful in 1m3s
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:
6
src/modules/note/cache/prepareNoteCache.ts
vendored
6
src/modules/note/cache/prepareNoteCache.ts
vendored
@@ -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) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
23
src/modules/note/snapshotStatus.spec.ts
Normal file
23
src/modules/note/snapshotStatus.spec.ts
Normal 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()
|
||||
})
|
||||
})
|
||||
25
src/modules/note/snapshotStatus.ts
Normal file
25
src/modules/note/snapshotStatus.ts
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user