feat: media page T1

This commit is contained in:
fsylvain committed 2026-10-01 01:36:35 +02:00
1 parent 67d456baf6
commit 008b0dfbb9
46 files changed
+5742 -204

No files matched your search

+42
View File
@@ -0,0 +1,42 @@
import type { MediaItem } from '@/composables/useMedia'
import { formatDimensions, formatSize } from '@/lib/mediaFormat'
export interface DuplicateGroup {
hash: string
copies: MediaItem[]
suggested: MediaItem
header: string
}
function byAge(first: MediaItem, second: MediaItem) {
return Date.parse(first.created_at) - Date.parse(second.created_at) || first.id - second.id
}
function byPreference(first: MediaItem, second: MediaItem) {
return second.used_in - first.used_in || byAge(first, second)
}
export function groupHeader(copies: MediaItem[]) {
const [first] = copies
return `${copies.length} identical images · ${formatSize(first!.size)} each · ${formatDimensions(first!.width, first!.height)}`
}
export function groupDuplicates(items: MediaItem[]): DuplicateGroup[] {
const byHash = new Map<string, MediaItem[]>()
for (const item of items) {
byHash.set(item.sha256, [...(byHash.get(item.sha256) ?? []), item])
}
return [...byHash.entries()]
.filter(([, copies]) => copies.length > 1)
.map(([hash, copies]) => {
const sorted = [...copies].sort(byPreference)
return { hash, copies: sorted, suggested: sorted[0]!, header: groupHeader(sorted) }
})
.sort((first, second) => byAge(first.suggested, second.suggested))
}
export function mergeArticleCount(copies: MediaItem[], keepId: number) {
return copies
.filter((copy) => copy.id !== keepId)
.reduce((total, copy) => total + copy.used_in, 0)
}