diff --git a/src/file-viewer/bin/scan3.ts b/src/file-viewer/bin/scan3.ts index 469b703f816ca68389ec7e59aa239f75c6f53682..cfa40cd0f561de7413870e17f09ccf3983734a98 100644 --- a/src/file-viewer/bin/scan3.ts +++ b/src/file-viewer/bin/scan3.ts @@ -123,6 +123,8 @@ export async function main() { dimensions: mediaFile?.dimensions ?? "", contents: mediaFile?.contents ?? "", }); + const parent = mediaFile.getParent(); + if (parent) parent.setProcessed(0); node.text = `${label}`; await queueProcessors({ @@ -263,7 +265,12 @@ export async function main() { } } } - if (node.estimate > 0) errorHandler.move(); + if (node.estimate > 0) { + errorHandler.move(); + + const parent = mediaFile.getParent(); + if (parent) parent.setProcessed(0); + } } // Add the root & recursively iterate! @@ -322,6 +329,19 @@ export async function main() { } } + // Project Date + const dateFile = children.find((x) => x.basename === ".date"); + if (dateFile) { + const date = new Date(dateFile.contents); + newestDate = date; + dir.setProcessors( + 0, + JSON.stringify({ hideChildrenDates: true }), + ); + } else { + dir.setProcessors(0, ""); + } + const dirHash = crypto .createHash("sha1") .update(dir.path + allHashes) @@ -846,12 +866,13 @@ function skipBasename(basename: string): boolean { // dot files must be incrementally tracked if (basename === ".dirsort") return false; if (basename === ".friends") return false; + if (basename === ".date") return false; return ( basename.startsWith(".") || - basename.startsWith("._") || - basename.startsWith(".tmp") || - basename === ".DS_Store" || + // basename.startsWith("._") || + // basename.startsWith(".tmp") || + // basename === ".DS_Store" || basename.toLowerCase() === "thumbs.db" || basename.toLowerCase() === "desktop.ini" ); diff --git a/src/file-viewer/models/MediaFile.ts b/src/file-viewer/models/MediaFile.ts index f9e75d4a64925e4306602ba7162bedbeb5c1f2d7..5b4a5a4dbe3d75c99f8530c7b1321c18658a32bc 100644 --- a/src/file-viewer/models/MediaFile.ts +++ b/src/file-viewer/models/MediaFile.ts @@ -440,7 +440,7 @@ const deleteCascadeQuery = db.prepare<[{ id: number }]>(/* SQL */ ` ) ) delete from media_files - where id in (select id from items) + where id in (select id from items order by parent_id nulls last) `); const getDirectoriesToReindexQuery = db.prepare(` with recursive directory_chain as ( diff --git a/src/file-viewer/rsync.ts b/src/file-viewer/rsync.ts index d6cafa002d5038e53cd6421330afbcd4008f2ff9..925695d1af872dac7ef7e846f0aba347cedc6830 100644 --- a/src/file-viewer/rsync.ts +++ b/src/file-viewer/rsync.ts @@ -25,7 +25,7 @@ export interface SpawnOptions { args: string[]; rsync?: string; progress: progress.Node; - cwd: string; + cwd?: string; } export async function spawn(options: SpawnOptions) { diff --git a/src/file-viewer/rules.ts b/src/file-viewer/rules.ts index 07e12cfb27924181060e1b88e39a27f6132d2a01..859024ed5bbeeda36a652a456378cb961f4aa7c0 100644 --- a/src/file-viewer/rules.ts +++ b/src/file-viewer/rules.ts @@ -73,7 +73,7 @@ export const extsDuration = new Set([...extsAudio, ...extsVideo]); export const extsDimensions = new Set([...extsImage, ...extsVideo, ".gif"]); /** These files read file contents into `contents`, as-is */ -export const extsReadContents = new Set([".txt", ".chat", ".dirsort"]); +export const extsReadContents = new Set([".txt", ".chat", ".dirsort", ".date"]); export const extsArchive = new Set([ ".zip", diff --git a/src/file-viewer/transcode-rules.ts b/src/file-viewer/transcode-rules.ts index 802c917115c680ff6788b8d8d5035d1e0e08cb5c..81ec31093dd5c4bc5711d52456ae3a32a8bebe37 100644 --- a/src/file-viewer/transcode-rules.ts +++ b/src/file-viewer/transcode-rules.ts @@ -98,7 +98,8 @@ export const imagePresets = [ ]; export async function getVideoInputArgs(path: Path): Promise { - const config = await path.replaceExt(".json").readIfExists("json"); + const config = await path.parent!.join("." + path.replaceExt(".json").base) + .readIfExists("json"); if (config) { if (config.encoder && typeof config.encoder.videoSrc === "string") { const { videoSrc, audioSrc, rate } = config.encoder; diff --git a/src/file-viewer/views/clofi.css b/src/file-viewer/views/clofi.css index 4131638f85d83fed519cda1f2530132fd38ba0d0..664d4eae050c2c4c5d6b01b4d0003396d7579305 100644 --- a/src/file-viewer/views/clofi.css +++ b/src/file-viewer/views/clofi.css @@ -695,6 +695,9 @@ h3 { text-decoration: underline; } } +.nodate { + padding-left: 0.5rem; +} /* MOBILE */ @media (max-width: 1000px) { diff --git a/src/file-viewer/views/clofi.tsx b/src/file-viewer/views/clofi.tsx index 0871f8dcce6751cce75fce31f64579d9ff9783d3..11fe8369e1e2cbf693f836b304df61e36de6b7b0 100644 --- a/src/file-viewer/views/clofi.tsx +++ b/src/file-viewer/views/clofi.tsx @@ -330,6 +330,10 @@ const sortOverrides: Record number> = { "/2017": sortChronologicalStartToEnd, }; +interface DirConfig { + hideChildrenDates?: boolean; +} + function DirView({ dir, activeFilename, @@ -363,12 +367,21 @@ function DirView({ const sortedFiles = unsortedFiles.sort(sorter); const readme = sortedFiles.find((f) => f.basename === readmeFile); if (readme && isLast) activeFilename ||= readmeFile; + + const extraConfig: DirConfig = dir.processors + ? JSON.parse(dir.processors) + : {}; + const main = (
    {sortedFiles.map((file) => { return ( - + ); })}
@@ -434,7 +447,7 @@ function ListItem({