diff --git a/web/src/lib/Figure.svelte b/web/src/lib/Figure.svelte index b3c229b..f7e262d 100644 --- a/web/src/lib/Figure.svelte +++ b/web/src/lib/Figure.svelte @@ -4,7 +4,9 @@ import CopyToClipboard from "$lib/components/CopyToClipboard.svelte" import OCRTable from './OCRTable.svelte'; import { marked } from 'marked'; - import { ChevronLeft, ChevronRight, X } from 'lucide-svelte'; + import { ChevronLeft, ChevronRight, X, Hash, Library, Folder, FileClock } from 'lucide-svelte'; + import { appIconMap } from '$lib/utils'; + import LucideIcon from '$lib/components/LucideIcon.svelte'; /** * @type {string} @@ -38,6 +40,7 @@ * @type {string} */ export let title; + export let app_name; /** * @type {Array} */ @@ -47,6 +50,16 @@ * @type {Array<{key: string, source: string, value: any}>} */ export let metadata_entries = []; + + // Remove items with key "timestamp" or "sequence" and sort metadata_entries, placing "ocr_result" at the end + $: sortedMetadataEntries = [...metadata_entries] + .filter(entry => entry.key !== "timestamp" && entry.key !== "sequence" && entry.key !== "active_app" && entry.key !== "active_window") + .sort((a, b) => { + if (a.key === "ocr_result") return 1; + if (b.key === "ocr_result") return -1; + return 0; + }); + /** * @type {any} */ @@ -111,55 +124,68 @@
-
- - {title} - -
- - +
+
+
+ +

{title}

+
+
- ID - {id} - - Library ID - - {library_id} - - Folder ID - - {folder_id} - - DATETIME - - {new Date(created_at).toLocaleString()} + + + {library_id} + + + + + {folder_id} + + + + + {id} + + + + + {new Date(created_at).toLocaleString()} + +
{filepath}
-
Image Title
-

- {title} -

-
TAGS
-
- {#each tags as tag} - {tag} - {/each} + +
+ + + + {#if tags.length > 0} +
+
TAGS
+
+ {#each tags as tag} + {tag} + {/each} +
+
+ {/if}
METADATA
- {#each metadata_entries as entry} + {#each sortedMetadataEntries as entry}
{entry.key} @@ -195,4 +221,4 @@
-
\ No newline at end of file +
diff --git a/web/src/lib/components/Logo.svelte b/web/src/lib/components/Logo.svelte index 31cece2..578f461 100644 --- a/web/src/lib/components/Logo.svelte +++ b/web/src/lib/components/Logo.svelte @@ -8,7 +8,61 @@ export let class_ = ''; export let withBorder = true; - function prepareMatrixFromRandomColors(withBorder: boolean): string[][] { + function prepareMatrixFromFixedIndexAndLittleRadom(withBorder: boolean): string[][] { + const bgColors = ['#f2f2f2', '#e9e9e9', '#d8d8d8'] + // const colors = ['#d0e8ff', '#F2295F', '#E0A0F2', '#F2B705']; + const colors = ['#d0e8ff', '#BF244E', '#8C2685', '#21A650']; + const mShape = withBorder + ? [ + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + [0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 3, 0], + [0, 1, 1, 1, 0, 0, 0, 0, 0, 3, 3, 3, 0], + [0, 1, 1, 1, 2, 0, 0, 0, 2, 3, 3, 3, 0], + [0, 1, 1, 1, 2, 2, 0, 2, 2, 3, 3, 3, 0], + [0, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 0], + [0, 1, 1, 1, 0, 2, 2, 2, 0, 3, 3, 3, 0], + [0, 1, 1, 1, 0, 0, 0, 0, 0, 3, 3, 3, 0], + [0, 1, 1, 1, 0, 0, 0, 0, 0, 3, 3, 3, 0], + [0, 1, 1, 1, 0, 0, 0, 0, 0, 3, 3, 3, 0], + [0, 1, 1, 1, 0, 0, 0, 0, 0, 3, 3, 3, 0], + [0, 1, 1, 1, 0, 0, 0, 0, 0, 3, 3, 3, 0], + [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] + ] + : [ + [1, 1, 0, 0, 0, 0, 0, 0, 0, 3, 3], + [1, 1, 1, 0, 0, 0, 0, 0, 3, 3, 3], + [1, 1, 1, 2, 0, 0, 0, 2, 3, 3, 3], + [1, 1, 1, 2, 2, 0, 2, 2, 3, 3, 3], + [1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3], + [1, 1, 1, 0, 2, 2, 2, 0, 3, 3, 3], + [1, 1, 1, 0, 0, 0, 0, 0, 3, 3, 3], + [1, 1, 1, 0, 0, 0, 0, 0, 3, 3, 3], + [1, 1, 1, 0, 0, 0, 0, 0, 3, 3, 3], + [1, 1, 1, 0, 0, 0, 0, 0, 3, 3, 3], + [1, 1, 1, 0, 0, 0, 0, 0, 3, 3, 3] + ]; + + const gridSize = withBorder ? 13 : 11; + let seed = 42; + const matrix: string[][] = []; + + for (let row = 0; row < gridSize; row++) { + const rowColors: string[] = []; + const bgSize = bgColors.length; + for (let col = 0; col < gridSize; col++) { + if (mShape[row][col] === 0) { + rowColors.push(bgColors[Math.floor(seededRandom(seed++) * bgSize)]); + } else { + rowColors.push(colors[mShape[row][col]]); + } + } + matrix.push(rowColors); + } + + return matrix; + } + + function prepareMatrixFromRandomColors(withBorder: boolean): string[][] { const colors = ['#d0e8ff', '#a1d2ff', '#64b5f6', '#1565c0', '#0d47a1']; const mShape = withBorder ? [ @@ -83,7 +137,7 @@ } function generateMemosLogo(size: number, withBorder: boolean): string { - const matrix = prepareMatrixFromRandomColors(withBorder); + const matrix = prepareMatrixFromFixedIndexAndLittleRadom(withBorder); return generateSvg(matrix, size); } diff --git a/web/src/lib/components/LucideIcon.svelte b/web/src/lib/components/LucideIcon.svelte new file mode 100644 index 0000000..1b4e468 --- /dev/null +++ b/web/src/lib/components/LucideIcon.svelte @@ -0,0 +1,6 @@ + + + \ No newline at end of file diff --git a/web/src/lib/utils.ts b/web/src/lib/utils.ts index 8871245..153466f 100644 --- a/web/src/lib/utils.ts +++ b/web/src/lib/utils.ts @@ -59,4 +59,32 @@ export const flyAndScale = ( }, easing: cubicOut }; -}; \ No newline at end of file +}; + +export const appIconMap: Record = { + "Cursor": "Code", + "Google Chrome": "Chrome", + "IINA": "Youtube", + "微信": "MessageSquareCode", + "预览": "Eye", + "iTerm2": "SquareTerminal", + "企业微信": "MessageSquareCode", + "IntelliJ IDEA": "Code", + "Microsoft Edge": "Globe", + "腾讯会议": "MessagesSquare", + "访达": "Folder", + "邮件": "Mail", + "备忘录": "NotebookTabs", + "日历": "CalendarFold", + "UserNotificationCenter": "Bell", + "Electron": "Atom", + "Firefox": "Globe", + "Safari浏览器": "Compass", + "熊掌记": "NotebookTabs", + "Alacritty": "SquareTerminal", + "系统设置": "Settings", + "股市": "CircleDollarSign", + "活动监视器": "Activity", + "Brave Browser": "Globe", + "Code": "Code", +}; diff --git a/web/src/routes/+page.svelte b/web/src/routes/+page.svelte index b196076..e2964c6 100644 --- a/web/src/routes/+page.svelte +++ b/web/src/routes/+page.svelte @@ -8,6 +8,8 @@ import { formatDistanceToNow } from 'date-fns'; import Logo from '$lib/components/Logo.svelte'; import { onMount } from 'svelte'; + import { appIconMap } from '$lib/utils'; + import LucideIcon from '$lib/components/LucideIcon.svelte'; let searchString = ''; /** @@ -255,6 +257,24 @@ ); } } + + // Add this function near the top of the @@ -330,11 +350,7 @@ >

- {hit.document.metadata_entries && - hit.document.metadata_entries.some((entry) => entry.key === 'active_window') - ? hit.document.metadata_entries.find((entry) => entry.key === 'active_window') - .value - : filename(hit.document.filepath)} + {getEntityTitle(hit.document)}

{formatDistanceToNow(new Date(hit.document.file_created_at * 1000), { @@ -348,11 +364,12 @@ src={`${apiEndpoint}/files/${hit.document.filepath}`} alt="" /> - {#if hit.document.metadata_entries && hit.document.metadata_entries.some((entry) => entry.key === 'active_app')} + {#if getAppName(hit.document)}

- {hit.document.metadata_entries.find((entry) => entry.key === 'active_app').value} + + {getAppName(hit.document)}
{/if} @@ -376,7 +393,8 @@ video={`${apiEndpoint}/files/video/${searchResult.hits[selectedImage].document.filepath}`} created_at={searchResult.hits[selectedImage].document.file_created_at * 1000} filepath={searchResult.hits[selectedImage].document.filepath} - title={filename(searchResult.hits[selectedImage].document.filepath)} + title={getEntityTitle(searchResult.hits[selectedImage].document)} + app_name={getAppName(searchResult.hits[selectedImage].document)} tags={searchResult.hits[selectedImage].document.tags} metadata_entries={searchResult.hits[selectedImage].document.metadata_entries} onClose={closeModal} @@ -396,4 +414,4 @@ Changelog
- \ No newline at end of file + diff --git a/web/static/favicon.png b/web/static/favicon.png index 825b9e6..b3c9ebd 100644 Binary files a/web/static/favicon.png and b/web/static/favicon.png differ