ink-framework-files 0.1.0-alpha.1 → 0.1.0-alpha.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -3
- package/src/media.ts +13 -7
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ink-framework-files",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.12",
|
|
4
4
|
"exports": {
|
|
5
5
|
".": "./src/index.ts",
|
|
6
6
|
"./images": "./src/images.ts",
|
|
7
7
|
"./media": "./src/media.ts"
|
|
8
8
|
},
|
|
9
9
|
"peerDependencies": {
|
|
10
|
-
"ink": "npm:ink-framework@0.1.0-alpha.
|
|
10
|
+
"ink": "npm:ink-framework@0.1.0-alpha.12",
|
|
11
11
|
"react": "19.2.8"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@ink/lightos": "npm:ink-framework-lightos@0.1.0-alpha.
|
|
14
|
+
"@ink/lightos": "npm:ink-framework-lightos@0.1.0-alpha.12"
|
|
15
15
|
},
|
|
16
16
|
"license": "MIT",
|
|
17
17
|
"repository": {
|
package/src/media.ts
CHANGED
|
@@ -19,6 +19,8 @@ type MediaPage = { items: MediaItem[]; nextCursor: string | null };
|
|
|
19
19
|
export type MediaPickerProps = {
|
|
20
20
|
kind?: "image" | "video" | "all";
|
|
21
21
|
title?: string;
|
|
22
|
+
selectionOrder?: "library" | "selection";
|
|
23
|
+
multiple?: boolean;
|
|
22
24
|
onSelect: (files: FileRef[]) => void | Promise<void>;
|
|
23
25
|
};
|
|
24
26
|
|
|
@@ -33,9 +35,14 @@ function decodePage(value: string): MediaPage {
|
|
|
33
35
|
return page as MediaPage;
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
export function MediaPicker({ kind = "all", title = kind === "image" ? "Photos" : kind === "video" ? "Videos" : "Photos and videos", onSelect }: MediaPickerProps) {
|
|
38
|
+
export function MediaPicker({ kind = "all", title = kind === "image" ? "Photos" : kind === "video" ? "Videos" : "Photos and videos", selectionOrder = "library", multiple = true, onSelect }: MediaPickerProps) {
|
|
37
39
|
const [items, setItems] = useState<MediaItem[]>([]);
|
|
38
40
|
const [selected, setSelected] = useState<Set<string>>(new Set());
|
|
41
|
+
const toggleSelected = useCallback((id: string) => setSelected(previous => {
|
|
42
|
+
const next = new Set(multiple ? previous : []);
|
|
43
|
+
if (previous.has(id)) next.delete(id); else next.add(id);
|
|
44
|
+
return next;
|
|
45
|
+
}), [multiple]);
|
|
39
46
|
const [permission, setPermission] = useState<PermissionStatus | null>(null);
|
|
40
47
|
const [loading, setLoading] = useState(true);
|
|
41
48
|
const [error, setError] = useState<Error | null>(null);
|
|
@@ -102,8 +109,9 @@ export function MediaPicker({ kind = "all", title = kind === "image" ? "Photos"
|
|
|
102
109
|
const imported: FileRef[] = [];
|
|
103
110
|
let delivered = false;
|
|
104
111
|
try {
|
|
105
|
-
|
|
106
|
-
|
|
112
|
+
const orderedIds = selectionOrder === "selection" ? [...selected] : items.filter(item => selected.has(item.id)).map(item => item.id);
|
|
113
|
+
for (const id of orderedIds) {
|
|
114
|
+
const file = decodeFileRef(await callNative("files", "media-import", { id }, { signal, timeoutMs: 600_000 }));
|
|
107
115
|
if (!file) throw new NativeError("protocol", "Media import returned no file");
|
|
108
116
|
imported.push(file);
|
|
109
117
|
}
|
|
@@ -141,13 +149,11 @@ export function MediaPicker({ kind = "all", title = kind === "image" ? "Photos"
|
|
|
141
149
|
onLoadMore: async () => { if (active.current) await loadPage(active.current.signal); },
|
|
142
150
|
renderItem: nativeListRow((row: MediaItem[]) => createElement("MediaGridRow", null, row.map(item => createElement("MediaCell", {
|
|
143
151
|
key: item.id, src: item.src, selected: selected.has(item.id), video: item.mimeType.startsWith("video/"), checkIcon: checkCircleFilled, videoIcon: videoFileFilled,
|
|
144
|
-
onPress: () =>
|
|
152
|
+
onPress: () => toggleSelected(item.id),
|
|
145
153
|
}))), row => [Array.from({ length: 3 }, (_, index) => {
|
|
146
154
|
const item = row[index];
|
|
147
155
|
return { hidden: !item, src: item?.src ?? row[0].src, selected: !!item && selected.has(item.id),
|
|
148
|
-
video: !!item?.mimeType.startsWith("video/"), onPress: item && (() =>
|
|
149
|
-
const next = new Set(previous); if (next.has(item.id)) next.delete(item.id); else next.add(item.id); return next;
|
|
150
|
-
})) };
|
|
156
|
+
video: !!item?.mimeType.startsWith("video/"), onPress: item && (() => toggleSelected(item.id)) };
|
|
151
157
|
})], mediaTemplate),
|
|
152
158
|
}));
|
|
153
159
|
}
|