From a0abce4a46a692cdf262384e14e0cb8fed185711 Mon Sep 17 00:00:00 2001 From: Jeremy Nguyen Date: Tue, 26 May 2026 19:03:17 -0700 Subject: [PATCH] feat: add XP tags UTF16LE support to advanced, quick, and add editor --- .../entries/add/ExifEntryAddEditorFields.tsx | 1 + .../entries/edit/ExifEntryByteEditor.tsx | 3 ++ .../entries/edit/ExifEntryEditor.tsx | 1 + .../components/table/ValueCell.tsx | 1 + .../editors/add/getExifAddEditor.ts | 2 ++ .../editors/add/resolvers/resolveXp.ts | 33 +++++++++++++++++++ .../features/exif-editor/editors/add/types.ts | 1 + .../editors/advanced/getExifAdvancedEditor.ts | 2 ++ .../editors/advanced/resolvers/resolveXp.ts | 23 +++++++++++++ .../exif-editor/editors/advanced/types.ts | 6 ++++ .../editors/quick/getExifQuickEditor.ts | 2 ++ .../editors/quick/resolvers/resolveXp.ts | 23 +++++++++++++ .../exif-editor/editors/quick/types.ts | 1 + apps/client/src/lib/exif/xp/constants.ts | 11 +++++++ apps/client/src/lib/exif/xp/formatXp.ts | 11 +++++++ apps/client/src/lib/exif/xp/parseXp.ts | 13 ++++++++ 16 files changed, 134 insertions(+) create mode 100644 apps/client/src/features/exif-editor/editors/add/resolvers/resolveXp.ts create mode 100644 apps/client/src/features/exif-editor/editors/advanced/resolvers/resolveXp.ts create mode 100644 apps/client/src/features/exif-editor/editors/quick/resolvers/resolveXp.ts create mode 100644 apps/client/src/lib/exif/xp/constants.ts create mode 100644 apps/client/src/lib/exif/xp/formatXp.ts create mode 100644 apps/client/src/lib/exif/xp/parseXp.ts diff --git a/apps/client/src/features/exif-editor/components/entries/add/ExifEntryAddEditorFields.tsx b/apps/client/src/features/exif-editor/components/entries/add/ExifEntryAddEditorFields.tsx index 6f070be..18779db 100644 --- a/apps/client/src/features/exif-editor/components/entries/add/ExifEntryAddEditorFields.tsx +++ b/apps/client/src/features/exif-editor/components/entries/add/ExifEntryAddEditorFields.tsx @@ -76,6 +76,7 @@ const ExifEntryAddEditorFields = ({ /> ); case "ascii": + case "xp": return ( { exifEntryObject.format === "SRATIONAL" || exifEntryObject.format === "RATIONAL"; + // TODO: Explicitly return null return ( (exifEntryObject.format === "ASCII" || + XP_TAGS.includes(exifEntryObject.tag) || isRationalOrSRational || exifEntryObject.tag === "USER_COMMENT") && ( diff --git a/apps/client/src/features/exif-editor/components/entries/edit/ExifEntryEditor.tsx b/apps/client/src/features/exif-editor/components/entries/edit/ExifEntryEditor.tsx index ecaad24..936d7ea 100644 --- a/apps/client/src/features/exif-editor/components/entries/edit/ExifEntryEditor.tsx +++ b/apps/client/src/features/exif-editor/components/entries/edit/ExifEntryEditor.tsx @@ -33,6 +33,7 @@ const ExifEntryEditor = () => { /> )); case "ascii": + case "xp": return ( { /> ); case "ascii": + case "xp": return ( { + if ( + exifEntryObject.format === "BYTE" && + exifEntryObject.tag !== undefined && + XP_TAGS.includes(exifEntryObject.tag) + ) { + return { + kind: "xp", + exifEntryObject, + value: + exifEntryObject.value.length === 0 ? + undefined + : parseXp(new Uint8Array(exifEntryObject.value)), + onValueChange: (value) => { + if (value === "") { + onValueChange([]); + } + + return onValueChange(Array.from(formatXp(value))); + }, + }; + } + + return null; +}; + +export { resolveXp }; diff --git a/apps/client/src/features/exif-editor/editors/add/types.ts b/apps/client/src/features/exif-editor/editors/add/types.ts index d74d6a4..c0fe878 100644 --- a/apps/client/src/features/exif-editor/editors/add/types.ts +++ b/apps/client/src/features/exif-editor/editors/add/types.ts @@ -29,6 +29,7 @@ type AddEditor = ( | ({ kind: "versionId" } & ResolvedAddEditor) | ({ kind: "datetime" } & ResolvedAddEditor) | ({ kind: "ascii" } & ResolvedAddEditor) + | ({ kind: "xp" } & ResolvedAddEditor) | ({ kind: "exifVersion" } & ResolvedAddEditor) | ({ kind: "timeStamp" } & ResolvedAddEditor