ink-framework-files 0.1.0-alpha.10 → 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.
Files changed (2) hide show
  1. package/package.json +3 -3
  2. 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.10",
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",
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.10"
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
- for (const item of items.filter(item => selected.has(item.id))) {
106
- const file = decodeFileRef(await callNative("files", "media-import", { id: item.id }, { signal, timeoutMs: 600_000 }));
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: () => setSelected(previous => { const next = new Set(previous); if (next.has(item.id)) next.delete(item.id); else next.add(item.id); return next; }),
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 && (() => setSelected(previous => {
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
  }