Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
/>
);
case "ascii":
case "xp":
return (
<TextAreaField
label="Value"
Expand Down Expand Up @@ -106,7 +107,7 @@
/>
{exifAddEditor.values.slice(1).map((value, index) => (
<RationalInput
key={index}

Check warning on line 110 in apps/client/src/features/exif-editor/components/entries/add/ExifEntryAddEditorFields.tsx

View workflow job for this annotation

GitHub Actions / Build

Do not use item index in the array as its key
aria-label={`${label} ${index + 1}`}
initialRational={value}
setRational={(rational) =>
Expand All @@ -129,7 +130,7 @@
{exifAddEditor.values.slice(1).map((value, index) => (
<NumberField
aria-label={`${label} ${index + 1}`}
key={index}

Check warning on line 133 in apps/client/src/features/exif-editor/components/entries/add/ExifEntryAddEditorFields.tsx

View workflow job for this annotation

GitHub Actions / Build

Do not use item index in the array as its key
value={value}
onChange={(value) =>
exifAddEditor.onValueChange(value, index + 1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import { useExifEntryDraftContext } from "#features/exif-editor/contexts/ExifEntryDraftContext";
import { EXIF_TAG_MAP } from "#lib/exif/exifTagMap";
import { XP_TAGS } from "#lib/exif/xp/constants";
import { Button } from "@exifi/ui/components/Button";
import { NumberField } from "@exifi/ui/components/NumberField";

Expand All @@ -20,8 +21,10 @@
exifEntryObject.format === "SRATIONAL" ||
exifEntryObject.format === "RATIONAL";

// TODO: Explicitly return null
return (
(exifEntryObject.format === "ASCII" ||
XP_TAGS.includes(exifEntryObject.tag) ||
isRationalOrSRational ||
exifEntryObject.tag === "USER_COMMENT") && (
<Disclosure {...props}>
Expand All @@ -43,7 +46,7 @@
<div className="grid grid-cols-[repeat(auto-fit,minmax(--spacing(20),1fr))] gap-2">
{draft.map((value, index) => (
<NumberField
key={index}

Check warning on line 49 in apps/client/src/features/exif-editor/components/entries/edit/ExifEntryByteEditor.tsx

View workflow job for this annotation

GitHub Actions / Build

Do not use item index in the array as its key
value={value}
onChange={(newValue) =>
setDraft((prevValue) => prevValue.with(index, newValue))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
case "rational":
return exifAdvancedEditor.values.map((value, index) => (
<RationalInput
key={index}

Check warning on line 27 in apps/client/src/features/exif-editor/components/entries/edit/ExifEntryEditor.tsx

View workflow job for this annotation

GitHub Actions / Build

Do not use item index in the array as its key
aria-label={`${label} ${index + 1}`}
initialRational={value}
setRational={(rational) =>
Expand All @@ -33,6 +33,7 @@
/>
));
case "ascii":
case "xp":
return (
<TextAreaField
aria-label={label}
Expand All @@ -44,7 +45,7 @@
return exifAdvancedEditor.values.map((value, index) => (
<NumberField
aria-label={`${label} ${index + 1}`}
key={index}

Check warning on line 48 in apps/client/src/features/exif-editor/components/entries/edit/ExifEntryEditor.tsx

View workflow job for this annotation

GitHub Actions / Build

Do not use item index in the array as its key
value={value}
onChange={(value) => exifAdvancedEditor.onValueChange(value, index)}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ const ValueCell = ({ row, getValue, table }: ValueCellProps) => {
/>
);
case "ascii":
case "xp":
return (
<TextField
aria-label={label}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { resolveRational } from "./resolvers/resolveRational";
import { resolveTimeStamp } from "./resolvers/resolveTimeStamp";
import { resolveUserComment } from "./resolvers/resolveUserComment";
import { resolveVersionId } from "./resolvers/resolveVersionId";
import { resolveXp } from "./resolvers/resolveXp";
import type { AddEditorResolver } from "./types";

const resolvers: AddEditorResolver[] = [
Expand All @@ -20,6 +21,7 @@ const resolvers: AddEditorResolver[] = [
resolveVersionId, // tag === "VERSION_ID"
resolveTimeStamp, // tag === "TIME_STAMP"
resolveUserComment, // tag === "USER_COMMENT"
resolveXp, // tag is in XP_TAGS
resolveAscii, // format === "ASCII"
resolveNumeric, // format is numeric
resolveRational, // format is rational
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { XP_TAGS } from "#lib/exif/xp/constants";
import { formatXp } from "#lib/exif/xp/formatXp";
import { parseXp } from "#lib/exif/xp/parseXp";

import type { AddEditorResolver } from "../types";

const resolveXp: AddEditorResolver = (exifEntryObject, onValueChange) => {
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 };
1 change: 1 addition & 0 deletions apps/client/src/features/exif-editor/editors/add/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type AddEditor = (
| ({ kind: "versionId" } & ResolvedAddEditor<number[]>)
| ({ kind: "datetime" } & ResolvedAddEditor<CalendarDateTime | undefined>)
| ({ kind: "ascii" } & ResolvedAddEditor<string>)
| ({ kind: "xp" } & ResolvedAddEditor<string>)
| ({ kind: "exifVersion" } & ResolvedAddEditor<ExifVersion>)
| ({ kind: "timeStamp" } & ResolvedAddEditor<Time | undefined>)
| {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import { resolveAscii } from "./resolvers/resolveAscii";
import { resolveNumeric } from "./resolvers/resolveNumeric";
import { resolveRational } from "./resolvers/resolveRational";
import { resolveUserComment } from "./resolvers/resolveUserComment";
import { resolveXp } from "./resolvers/resolveXp";
import type { AdvancedEditorResolver } from "./types";

const resolvers: AdvancedEditorResolver[] = [
resolveUserComment, // tag === "USER_COMMENT"
resolveXp,
resolveAscii, // format === "ASCII"
resolveNumeric, // format is numeric
resolveRational, // format is rational
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { XP_TAGS } from "#lib/exif/xp/constants";
import { formatXp } from "#lib/exif/xp/formatXp";
import { parseXp } from "#lib/exif/xp/parseXp";

import type { AdvancedEditorResolver } from "../types";

const resolveXp: AdvancedEditorResolver = (exifEntryObject, onValueChange) => {
if (
exifEntryObject.format === "BYTE" &&
XP_TAGS.includes(exifEntryObject.tag)
) {
return {
kind: "xp",
exifEntryObject,
value: parseXp(new Uint8Array(exifEntryObject.value)),
onValueChange: (value) => onValueChange(Array.from(formatXp(value))),
};
}

return null;
};

export { resolveXp };
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ type AdvancedEditor =
value: UserComment;
onValueChange: (value: UserComment) => void;
}
| {
kind: "xp";
exifEntryObject: ExifEntryObject;
value: string;
onValueChange: (value: string) => void;
}
| ({ kind: "rational" } & ResolvedAdvancedEditor<RationalObject>)
| {
kind: "ascii";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { resolveSimpleNumeric } from "./resolvers/resolveSimpleNumeric";
import { resolveSimpleRational } from "./resolvers/resolveSimpleRational";
import { resolveTimeStamp } from "./resolvers/resolveTimeStamp";
import { resolveVersionId } from "./resolvers/resolveVersionId";
import { resolveXp } from "./resolvers/resolveXp";
import type { QuickEditorResolver } from "./types";

const resolvers: QuickEditorResolver[] = [
Expand All @@ -18,6 +19,7 @@ const resolvers: QuickEditorResolver[] = [
resolveExifVersion, // tag === "EXIF_VERSION"
resolveVersionId, // tag === "VERSION_ID"
resolveTimeStamp, // tag === "TIME_STAMP"
resolveXp, // tag is in XP_TAGS
resolveAscii, // format === "ASCII"
resolveSimpleRational, // format === "RATIONAL" && denominator === 1
resolveSimpleNumeric, // format is numeric && components === 1
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { XP_TAGS } from "#lib/exif/xp/constants";
import { formatXp } from "#lib/exif/xp/formatXp";
import { parseXp } from "#lib/exif/xp/parseXp";

import type { QuickEditorResolver } from "../types";

const resolveXp: QuickEditorResolver = (exifEntryObject, onValueChange) => {
if (
exifEntryObject.format === "BYTE" &&
XP_TAGS.includes(exifEntryObject.tag)
) {
return {
kind: "xp",
exifEntryObject,
value: parseXp(new Uint8Array(exifEntryObject.value)),
onValueChange: (value) => onValueChange(formatXp(value)),
};
}

return null;
};

export { resolveXp };
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type QuickEditor =
| ({ kind: "versionId" } & ResolvedQuickEditor<number[]>)
| ({ kind: "datetime" } & ResolvedQuickEditor<CalendarDateTime>)
| ({ kind: "ascii" } & ResolvedQuickEditor<string>)
| ({ kind: "xp" } & ResolvedQuickEditor<string>)
| ({ kind: "exifVersion" } & ResolvedQuickEditor<ExifVersion>)
| ({ kind: "simpleNumeric" } & ResolvedQuickEditor<number>)
| ({ kind: "timeStamp" } & ResolvedQuickEditor<Time>);
Expand Down
11 changes: 11 additions & 0 deletions apps/client/src/lib/exif/xp/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import type { Tag } from "libexif-wasm";

const XP_TAGS: Tag[] = [
"XP_TITLE",
"XP_COMMENT",
"XP_AUTHOR",
"XP_KEYWORDS",
"XP_SUBJECT",
];

export { XP_TAGS };
11 changes: 11 additions & 0 deletions apps/client/src/lib/exif/xp/formatXp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { encode } from "iconv-lite";

const formatXp = (input: string) => {
const inputWithNullTerminator =
input.endsWith("\u0000") ? input : input + "\u0000";
const buffer = encode(inputWithNullTerminator, "utf16le") as Uint8Array;

return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
};

export { formatXp };
13 changes: 13 additions & 0 deletions apps/client/src/lib/exif/xp/parseXp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
const textDecoder = new TextDecoder("utf-16le");

const parseXp = (input: AllowSharedBufferSource) => {
const output = textDecoder.decode(input);

if (output.endsWith("\u0000")) {
return output.slice(0, -1);
}

return output;
};

export { parseXp };
Loading