@oxyhq/services 22.5.0 → 22.6.1
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/lib/commonjs/index.js +1 -1
- package/lib/commonjs/ui/client.js +1 -1
- package/lib/commonjs/ui/components/FontLoader.js +18 -145
- package/lib/commonjs/ui/components/FontLoader.js.map +1 -1
- package/lib/commonjs/ui/components/FontLoader.native.js +88 -0
- package/lib/commonjs/ui/components/FontLoader.native.js.map +1 -0
- package/lib/commonjs/ui/components/OxyProvider.js +1 -1
- package/lib/commonjs/ui/components/fileManagement/FileDetailsModal.js +34 -41
- package/lib/commonjs/ui/components/fileManagement/FileDetailsModal.js.map +1 -1
- package/lib/commonjs/ui/components/fileManagement/UploadPreview.js.map +1 -1
- package/lib/commonjs/ui/components/fileManagement/styles.js +1 -225
- package/lib/commonjs/ui/components/fileManagement/styles.js.map +1 -1
- package/lib/commonjs/ui/components/photogrid/JustifiedPhotoGrid.js +0 -2
- package/lib/commonjs/ui/components/photogrid/JustifiedPhotoGrid.js.map +1 -1
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js +5 -2
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/commonjs/ui/context/useOxyAccountGraph.js +7 -0
- package/lib/commonjs/ui/context/useOxyAccountGraph.js.map +1 -1
- package/lib/commonjs/ui/hooks/queries/useAccountQueries.js +10 -4
- package/lib/commonjs/ui/hooks/queries/useAccountQueries.js.map +1 -1
- package/lib/commonjs/ui/hooks/queries/userCache.js +33 -9
- package/lib/commonjs/ui/hooks/queries/userCache.js.map +1 -1
- package/lib/commonjs/ui/hooks/useAvatarPicker.js +23 -8
- package/lib/commonjs/ui/hooks/useAvatarPicker.js.map +1 -1
- package/lib/commonjs/ui/hooks/useFileDownloadUrl.js +7 -21
- package/lib/commonjs/ui/hooks/useFileDownloadUrl.js.map +1 -1
- package/lib/commonjs/ui/hooks/useResolvedFileUrls.js +163 -0
- package/lib/commonjs/ui/hooks/useResolvedFileUrls.js.map +1 -0
- package/lib/commonjs/ui/index.js +1 -1
- package/lib/commonjs/ui/screens/FileManagementScreen.js +51 -22
- package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/fileManagement/PhotoPickerSection.js +227 -204
- package/lib/commonjs/ui/screens/fileManagement/PhotoPickerSection.js.map +1 -1
- package/lib/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.js +26 -9
- package/lib/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.js.map +1 -1
- package/lib/commonjs/ui/screens/fileManagement/photoGridLayout.js +44 -0
- package/lib/commonjs/ui/screens/fileManagement/photoGridLayout.js.map +1 -0
- package/lib/commonjs/ui/session/tokenTransport.js +21 -10
- package/lib/commonjs/ui/session/tokenTransport.js.map +1 -1
- package/lib/commonjs/ui/utils/fileManagement.js +3 -43
- package/lib/commonjs/ui/utils/fileManagement.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/ui/client.js +1 -1
- package/lib/module/ui/client.js.map +1 -1
- package/lib/module/ui/components/FontLoader.js +18 -146
- package/lib/module/ui/components/FontLoader.js.map +1 -1
- package/lib/module/ui/components/FontLoader.native.js +83 -0
- package/lib/module/ui/components/FontLoader.native.js.map +1 -0
- package/lib/module/ui/components/OxyProvider.js +1 -1
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/fileManagement/FileDetailsModal.js +34 -41
- package/lib/module/ui/components/fileManagement/FileDetailsModal.js.map +1 -1
- package/lib/module/ui/components/fileManagement/UploadPreview.js.map +1 -1
- package/lib/module/ui/components/fileManagement/styles.js +0 -224
- package/lib/module/ui/components/fileManagement/styles.js.map +1 -1
- package/lib/module/ui/components/photogrid/JustifiedPhotoGrid.js +0 -2
- package/lib/module/ui/components/photogrid/JustifiedPhotoGrid.js.map +1 -1
- package/lib/module/ui/context/hooks/useAuthOperations.js +5 -2
- package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/module/ui/context/useOxyAccountGraph.js +7 -0
- package/lib/module/ui/context/useOxyAccountGraph.js.map +1 -1
- package/lib/module/ui/hooks/queries/useAccountQueries.js +10 -4
- package/lib/module/ui/hooks/queries/useAccountQueries.js.map +1 -1
- package/lib/module/ui/hooks/queries/userCache.js +33 -9
- package/lib/module/ui/hooks/queries/userCache.js.map +1 -1
- package/lib/module/ui/hooks/useAvatarPicker.js +23 -8
- package/lib/module/ui/hooks/useAvatarPicker.js.map +1 -1
- package/lib/module/ui/hooks/useFileDownloadUrl.js +7 -21
- package/lib/module/ui/hooks/useFileDownloadUrl.js.map +1 -1
- package/lib/module/ui/hooks/useResolvedFileUrls.js +157 -0
- package/lib/module/ui/hooks/useResolvedFileUrls.js.map +1 -0
- package/lib/module/ui/index.js +1 -1
- package/lib/module/ui/index.js.map +1 -1
- package/lib/module/ui/screens/FileManagementScreen.js +52 -23
- package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
- package/lib/module/ui/screens/fileManagement/PhotoPickerSection.js +229 -206
- package/lib/module/ui/screens/fileManagement/PhotoPickerSection.js.map +1 -1
- package/lib/module/ui/screens/fileManagement/hooks/useFileUploadState.js +26 -9
- package/lib/module/ui/screens/fileManagement/hooks/useFileUploadState.js.map +1 -1
- package/lib/module/ui/screens/fileManagement/photoGridLayout.js +39 -0
- package/lib/module/ui/screens/fileManagement/photoGridLayout.js.map +1 -0
- package/lib/module/ui/session/tokenTransport.js +21 -10
- package/lib/module/ui/session/tokenTransport.js.map +1 -1
- package/lib/module/ui/utils/fileManagement.js +3 -42
- package/lib/module/ui/utils/fileManagement.js.map +1 -1
- package/lib/typescript/commonjs/ui/components/FontLoader.d.ts +14 -5
- package/lib/typescript/commonjs/ui/components/FontLoader.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/FontLoader.native.d.ts +13 -0
- package/lib/typescript/commonjs/ui/components/FontLoader.native.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/components/fileManagement/FileDetailsModal.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/fileManagement/styles.d.ts +0 -218
- package/lib/typescript/commonjs/ui/components/fileManagement/styles.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/photogrid/JustifiedPhotoGrid.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts +2 -2
- package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/queries/useAccountQueries.d.ts +9 -0
- package/lib/typescript/commonjs/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/queries/userCache.d.ts +3 -0
- package/lib/typescript/commonjs/ui/hooks/queries/userCache.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useAvatarPicker.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useFileDownloadUrl.d.ts +3 -2
- package/lib/typescript/commonjs/ui/hooks/useFileDownloadUrl.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useResolvedFileUrls.d.ts +48 -0
- package/lib/typescript/commonjs/ui/hooks/useResolvedFileUrls.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/screens/FileManagementScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/fileManagement/PhotoPickerSection.d.ts +1 -1
- package/lib/typescript/commonjs/ui/screens/fileManagement/PhotoPickerSection.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/fileManagement/photoGridLayout.d.ts +37 -0
- package/lib/typescript/commonjs/ui/screens/fileManagement/photoGridLayout.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/session/tokenTransport.d.ts +15 -8
- package/lib/typescript/commonjs/ui/session/tokenTransport.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts +4 -11
- package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +1 -1
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/client.d.ts +1 -1
- package/lib/typescript/module/ui/client.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/FontLoader.d.ts +14 -5
- package/lib/typescript/module/ui/components/FontLoader.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/FontLoader.native.d.ts +13 -0
- package/lib/typescript/module/ui/components/FontLoader.native.d.ts.map +1 -0
- package/lib/typescript/module/ui/components/fileManagement/FileDetailsModal.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/fileManagement/styles.d.ts +0 -218
- package/lib/typescript/module/ui/components/fileManagement/styles.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/photogrid/JustifiedPhotoGrid.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts +2 -2
- package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/queries/useAccountQueries.d.ts +9 -0
- package/lib/typescript/module/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/queries/userCache.d.ts +3 -0
- package/lib/typescript/module/ui/hooks/queries/userCache.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useAvatarPicker.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useFileDownloadUrl.d.ts +3 -2
- package/lib/typescript/module/ui/hooks/useFileDownloadUrl.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useResolvedFileUrls.d.ts +48 -0
- package/lib/typescript/module/ui/hooks/useResolvedFileUrls.d.ts.map +1 -0
- package/lib/typescript/module/ui/index.d.ts +1 -1
- package/lib/typescript/module/ui/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/FileManagementScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/fileManagement/PhotoPickerSection.d.ts +1 -1
- package/lib/typescript/module/ui/screens/fileManagement/PhotoPickerSection.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/fileManagement/photoGridLayout.d.ts +37 -0
- package/lib/typescript/module/ui/screens/fileManagement/photoGridLayout.d.ts.map +1 -0
- package/lib/typescript/module/ui/session/tokenTransport.d.ts +15 -8
- package/lib/typescript/module/ui/session/tokenTransport.d.ts.map +1 -1
- package/lib/typescript/module/ui/utils/fileManagement.d.ts +4 -11
- package/lib/typescript/module/ui/utils/fileManagement.d.ts.map +1 -1
- package/package.json +5 -10
- package/src/ui/components/FontLoader.native.tsx +88 -0
- package/src/ui/components/FontLoader.tsx +16 -151
- package/src/ui/components/fileManagement/FileDetailsModal.tsx +29 -28
- package/src/ui/components/fileManagement/UploadPreview.tsx +1 -1
- package/src/ui/components/fileManagement/styles.ts +0 -225
- package/src/ui/components/photogrid/JustifiedPhotoGrid.tsx +0 -1
- package/src/ui/context/hooks/useAuthOperations.ts +5 -2
- package/src/ui/context/useOxyAccountGraph.ts +5 -0
- package/src/ui/hooks/queries/__tests__/userCache.test.ts +29 -0
- package/src/ui/hooks/queries/useAccountQueries.ts +10 -4
- package/src/ui/hooks/queries/userCache.ts +31 -8
- package/src/ui/hooks/useAvatarPicker.ts +27 -7
- package/src/ui/hooks/useFileDownloadUrl.ts +7 -23
- package/src/ui/hooks/useResolvedFileUrls.ts +170 -0
- package/src/ui/screens/FileManagementScreen.tsx +55 -27
- package/src/ui/screens/__tests__/photoGridLayout.test.ts +57 -0
- package/src/ui/screens/fileManagement/PhotoPickerSection.tsx +229 -215
- package/src/ui/screens/fileManagement/hooks/useFileUploadState.ts +27 -3
- package/src/ui/screens/fileManagement/photoGridLayout.ts +45 -0
- package/src/ui/session/__tests__/tokenTransport.test.ts +25 -10
- package/src/ui/session/tokenTransport.ts +21 -10
- package/src/ui/utils/fileManagement.ts +8 -49
- package/lib/typescript/types/expo-vector-icons.d.ts +0 -22
- package/src/types/expo-vector-icons.d.ts +0 -22
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { useMemo } from 'react';
|
|
4
|
+
import { useQuery } from '@tanstack/react-query';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The variant-aware batch resolver contract (`@oxyhq/core`).
|
|
8
|
+
*
|
|
9
|
+
* `getFileDownloadUrls` takes a per-file `{ fileId, variant }` list and returns
|
|
10
|
+
* a map keyed by `fileId`; ids that are denied or missing are OMITTED (never an
|
|
11
|
+
* empty string), and PRIVATE assets resolve to a working scoped-media-token
|
|
12
|
+
* stream URL. Typed here rather than `Pick<OxyServices, …>` so this file states
|
|
13
|
+
* the exact contract it depends on.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Private-safe grid/thumbnail URL resolution.
|
|
18
|
+
*
|
|
19
|
+
* The synchronous `oxyServices.getFileDownloadUrl(id, variant)` always yields
|
|
20
|
+
* the public CDN origin (`cloud.oxy.so/<id>`), which 404s for PRIVATE assets —
|
|
21
|
+
* and uploads default to private. Thumbnails and previews therefore have to be
|
|
22
|
+
* resolved through the authenticated batch endpoint, which returns a working
|
|
23
|
+
* `/assets/:id/stream?…&mt=<scoped media token>` URL for private files.
|
|
24
|
+
*
|
|
25
|
+
* This hook resolves an ENTIRE page of files in ONE (chunked) batch request
|
|
26
|
+
* rather than N per-tile calls, and caches the result in React Query keyed by
|
|
27
|
+
* the (fileId, variant) set. `staleTime` is deliberately shorter than the
|
|
28
|
+
* server media-token TTL so a tile never renders a URL whose token has already
|
|
29
|
+
* expired.
|
|
30
|
+
*
|
|
31
|
+
* Optimistic (`temp-…` / `uploading`) entries are NEVER resolved here — an
|
|
32
|
+
* asset URL must never be built from an id the server does not yet know. Their
|
|
33
|
+
* preview comes from the locally-picked uri (see {@link fileThumbSource}).
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
/** Server media-token lifetime we request for each resolved URL (seconds). */
|
|
37
|
+
const ASSET_URL_TTL_SECONDS = 600; // 10 minutes
|
|
38
|
+
/**
|
|
39
|
+
* Refresh window. Kept below {@link ASSET_URL_TTL_SECONDS} so React Query
|
|
40
|
+
* re-resolves in the background before a rendered URL's token can die.
|
|
41
|
+
*/
|
|
42
|
+
const ASSET_URL_STALE_MS = 5 * 60 * 1000; // 5 minutes
|
|
43
|
+
const ASSET_URL_GC_MS = 30 * 60 * 1000;
|
|
44
|
+
/** Server-side batch cap for `POST /assets/batch-access` — chunk beyond this. */
|
|
45
|
+
const BATCH_CAP = 100;
|
|
46
|
+
|
|
47
|
+
/** React Query prefix — scoped media URLs must never leak across accounts. */
|
|
48
|
+
export const ASSET_DOWNLOAD_URLS_QUERY_KEY = 'assetDownloadUrls';
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* True when a file is an optimistic placeholder that has not been persisted by
|
|
52
|
+
* the server yet — either its id is still the client-minted `temp-…` id, or it
|
|
53
|
+
* carries the `uploading` flag. Mirrors the `temp-` id guard precedent in
|
|
54
|
+
* `@oxyhq/core`'s `avatarUtils.updateAvatarVisibility`.
|
|
55
|
+
*/
|
|
56
|
+
export function isOptimisticFile(file) {
|
|
57
|
+
if (typeof file.id === 'string' && file.id.startsWith('temp-')) return true;
|
|
58
|
+
return file.metadata?.uploading === true;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Grid thumbnail variant for a file, or `undefined` when it needs no URL. */
|
|
62
|
+
function thumbVariantFor(file) {
|
|
63
|
+
if (file.contentType.startsWith('video/')) return 'poster';
|
|
64
|
+
if (file.contentType.startsWith('image/')) return 'thumb';
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Locally-picked preview uri stashed on an optimistic entry's metadata by the
|
|
70
|
+
* upload flow, if present.
|
|
71
|
+
*/
|
|
72
|
+
function localPreviewUri(file) {
|
|
73
|
+
const uri = file.metadata?.localPreviewUri;
|
|
74
|
+
return typeof uri === 'string' && uri.length > 0 ? uri : undefined;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Resolve the image source for a grid tile.
|
|
79
|
+
*
|
|
80
|
+
* - Optimistic entry → its locally-picked preview uri (never an asset URL).
|
|
81
|
+
* - Persisted entry → the private-safe URL from {@link useResolvedFileUrls},
|
|
82
|
+
* or `undefined` while it is still resolving / was denied (tile shows a
|
|
83
|
+
* placeholder instead of a guaranteed-404 CDN URL).
|
|
84
|
+
*/
|
|
85
|
+
export function fileThumbSource(file, resolved) {
|
|
86
|
+
if (isOptimisticFile(file)) {
|
|
87
|
+
return localPreviewUri(file);
|
|
88
|
+
}
|
|
89
|
+
return resolved.get(file.id);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Batch-resolve private-safe thumbnail URLs for the given files.
|
|
94
|
+
*
|
|
95
|
+
* Only image/video, non-optimistic files are resolved (documents render an
|
|
96
|
+
* icon, optimistic entries render their local preview). Returns a stable
|
|
97
|
+
* `Map<fileId, url>`; missing entries mean "not resolved yet or access denied".
|
|
98
|
+
*/
|
|
99
|
+
export function useResolvedFileUrls(oxyServices, files, /** Active viewer account id — media tokens are minted per user; must be in the query key. */
|
|
100
|
+
viewerId) {
|
|
101
|
+
const viewerKey = viewerId ?? '';
|
|
102
|
+
const requests = useMemo(() => {
|
|
103
|
+
const list = [];
|
|
104
|
+
for (const file of files) {
|
|
105
|
+
if (isOptimisticFile(file)) continue;
|
|
106
|
+
const variant = thumbVariantFor(file);
|
|
107
|
+
if (!variant) continue;
|
|
108
|
+
list.push({
|
|
109
|
+
fileId: file.id,
|
|
110
|
+
variant
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
return list;
|
|
114
|
+
}, [files]);
|
|
115
|
+
|
|
116
|
+
// A content signature so the query key is stable across renders while the
|
|
117
|
+
// resolvable set is unchanged (the `files` array is a fresh reference every
|
|
118
|
+
// render). Sorted so ordering churn does not force a refetch.
|
|
119
|
+
const signature = useMemo(() => requests.map(r => `${r.fileId}:${r.variant ?? ''}`).sort().join('|'), [requests]);
|
|
120
|
+
const query = useQuery({
|
|
121
|
+
queryKey: [ASSET_DOWNLOAD_URLS_QUERY_KEY, viewerKey, signature],
|
|
122
|
+
enabled: requests.length > 0 && viewerKey.length > 0,
|
|
123
|
+
staleTime: ASSET_URL_STALE_MS,
|
|
124
|
+
gcTime: ASSET_URL_GC_MS,
|
|
125
|
+
// Keep previously-resolved URLs on screen while the SAME viewer's file set
|
|
126
|
+
// grows (pagination), but never carry another account's scoped media tokens
|
|
127
|
+
// across a switch — `keepPreviousData` alone would do that.
|
|
128
|
+
placeholderData: (previousData, previousQuery) => {
|
|
129
|
+
if (!previousData || !previousQuery) return undefined;
|
|
130
|
+
const prevViewer = previousQuery.queryKey[1];
|
|
131
|
+
if (prevViewer !== viewerKey) return undefined;
|
|
132
|
+
return previousData;
|
|
133
|
+
},
|
|
134
|
+
queryFn: async () => {
|
|
135
|
+
const merged = {};
|
|
136
|
+
for (let i = 0; i < requests.length; i += BATCH_CAP) {
|
|
137
|
+
const chunk = requests.slice(i, i + BATCH_CAP);
|
|
138
|
+
const urls = await oxyServices.getFileDownloadUrls(chunk, {
|
|
139
|
+
expiresIn: ASSET_URL_TTL_SECONDS
|
|
140
|
+
});
|
|
141
|
+
Object.assign(merged, urls);
|
|
142
|
+
}
|
|
143
|
+
return merged;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
return useMemo(() => {
|
|
147
|
+
const map = new Map();
|
|
148
|
+
const data = query.data;
|
|
149
|
+
if (data) {
|
|
150
|
+
for (const [id, url] of Object.entries(data)) {
|
|
151
|
+
if (typeof url === 'string' && url.length > 0) map.set(id, url);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
return map;
|
|
155
|
+
}, [query.data]);
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=useResolvedFileUrls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["useMemo","useQuery","ASSET_URL_TTL_SECONDS","ASSET_URL_STALE_MS","ASSET_URL_GC_MS","BATCH_CAP","ASSET_DOWNLOAD_URLS_QUERY_KEY","isOptimisticFile","file","id","startsWith","metadata","uploading","thumbVariantFor","contentType","undefined","localPreviewUri","uri","length","fileThumbSource","resolved","get","useResolvedFileUrls","oxyServices","files","viewerId","viewerKey","requests","list","variant","push","fileId","signature","map","r","sort","join","query","queryKey","enabled","staleTime","gcTime","placeholderData","previousData","previousQuery","prevViewer","queryFn","merged","i","chunk","slice","urls","getFileDownloadUrls","expiresIn","Object","assign","Map","data","url","entries","set"],"sourceRoot":"../../../../src","sources":["ui/hooks/useResolvedFileUrls.ts"],"mappings":"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","ignoreList":[]}
|
package/lib/module/ui/index.js
CHANGED
|
@@ -26,7 +26,7 @@ export { LogoText } from "./components/logo/LogoText.js";
|
|
|
26
26
|
export { RequireOxyAuth } from "./components/RequireOxyAuth.js";
|
|
27
27
|
export { default as FollowButton } from "./components/FollowButton.js";
|
|
28
28
|
export { default as OxyPayButton } from "./components/OxyPayButton.js";
|
|
29
|
-
export { FontLoader, setupFonts } from
|
|
29
|
+
export { FontLoader, setupFonts } from './components/FontLoader';
|
|
30
30
|
export { default as ProfileButton } from "./components/ProfileButton.js";
|
|
31
31
|
|
|
32
32
|
// Context + hooks
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["default","OxyProvider","OxySignInButton","OxyAuthPrompt","LogoIcon","LogoText","RequireOxyAuth","FollowButton","OxyPayButton","FontLoader","setupFonts","ProfileButton","useOxy","useAuth","useFollow","useSeedFollowStatuses","useStorage","ProfileScreen","ManageAccountScreen","CreateAccountScreen","AccountMembersScreen","AccountSettingsScreen","useAuthStore","useAccountStore","handleAuthError","isInvalidSessionError","isTimeoutOrNetworkError","extractErrorMessage"],"sourceRoot":"../../../src","sources":["ui/index.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,SAASA,OAAO,IAAIC,WAAW,QAAQ,6BAA0B;AACjE,SAASD,OAAO,IAAIE,eAAe,QAAQ,iCAA8B;AACzE,SAASF,OAAO,IAAIG,aAAa,QAAQ,+BAA4B;AAErE,SAASC,QAAQ,QAAQ,+BAA4B;AACrD,SAASC,QAAQ,QAAQ,+BAA4B;AACrD,SAASC,cAAc,QAAQ,gCAA6B;AAE5D,SAASN,OAAO,IAAIO,YAAY,QAAQ,8BAA2B;AACnE,SAASP,OAAO,IAAIQ,YAAY,QAAQ,8BAA2B;AACnE,SAASC,UAAU,EAAEC,UAAU,QAAQ,
|
|
1
|
+
{"version":3,"names":["default","OxyProvider","OxySignInButton","OxyAuthPrompt","LogoIcon","LogoText","RequireOxyAuth","FollowButton","OxyPayButton","FontLoader","setupFonts","ProfileButton","useOxy","useAuth","useFollow","useSeedFollowStatuses","useStorage","ProfileScreen","ManageAccountScreen","CreateAccountScreen","AccountMembersScreen","AccountSettingsScreen","useAuthStore","useAccountStore","handleAuthError","isInvalidSessionError","isTimeoutOrNetworkError","extractErrorMessage"],"sourceRoot":"../../../src","sources":["ui/index.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA,SAASA,OAAO,IAAIC,WAAW,QAAQ,6BAA0B;AACjE,SAASD,OAAO,IAAIE,eAAe,QAAQ,iCAA8B;AACzE,SAASF,OAAO,IAAIG,aAAa,QAAQ,+BAA4B;AAErE,SAASC,QAAQ,QAAQ,+BAA4B;AACrD,SAASC,QAAQ,QAAQ,+BAA4B;AACrD,SAASC,cAAc,QAAQ,gCAA6B;AAE5D,SAASN,OAAO,IAAIO,YAAY,QAAQ,8BAA2B;AACnE,SAASP,OAAO,IAAIQ,YAAY,QAAQ,8BAA2B;AACnE,SAASC,UAAU,EAAEC,UAAU,QAAQ,yBAAyB;AAChE,SAASV,OAAO,IAAIW,aAAa,QAAQ,+BAA4B;;AAErE;AACA,SAASC,MAAM,QAAQ,yBAAsB;AAC7C,SAASC,OAAO,QAAQ,oBAAiB;AACzC,SAASC,SAAS,EAAEC,qBAAqB,QAAQ,sBAAmB;AACpE,SAASC,UAAU,QAAQ,uBAAoB;AAG/C;AACA,SAAShB,OAAO,IAAIiB,aAAa,QAAQ,4BAAyB;AAClE,SAASjB,OAAO,IAAIkB,mBAAmB,QAAQ,kCAA+B;AAC9E,SAASlB,OAAO,IAAImB,mBAAmB,QAAQ,kCAA+B;AAC9E,SAASnB,OAAO,IAAIoB,oBAAoB,QAAQ,mCAAgC;AAChF,SAASpB,OAAO,IAAIqB,qBAAqB,QAAQ,oCAAiC;;AAElF;AACA,SAASC,YAAY,QAAQ,uBAAoB;AACjD,SAASC,eAAe,QAAQ,0BAAuB;;AAEvD;AACA,SACIC,eAAe,EACfC,qBAAqB,EACrBC,uBAAuB,EACvBC,mBAAmB,QAChB,0BAAuB","ignoreList":[]}
|
|
@@ -12,7 +12,8 @@ import { useTheme } from '@oxyhq/bloom/theme';
|
|
|
12
12
|
import { useOxy } from "../context/OxyContext.js";
|
|
13
13
|
import { useI18n } from "../hooks/useI18n.js";
|
|
14
14
|
import { useUploadFile } from "../hooks/mutations/useAccountMutations.js";
|
|
15
|
-
import { formatFileSize, getFileIcon
|
|
15
|
+
import { formatFileSize, getFileIcon } from "../utils/fileManagement.js";
|
|
16
|
+
import { useResolvedFileUrls, fileThumbSource } from "../hooks/useResolvedFileUrls.js";
|
|
16
17
|
import { FileViewer } from "../components/fileManagement/FileViewer.js";
|
|
17
18
|
import { FileDetailsModal } from "../components/fileManagement/FileDetailsModal.js";
|
|
18
19
|
import { UploadPreview } from "../components/fileManagement/UploadPreview.js";
|
|
@@ -305,10 +306,16 @@ const FileManagementScreen = ({
|
|
|
305
306
|
onClose?.();
|
|
306
307
|
}, [selectMode, multiSelect, selectedIds, files, onConfirmSelection, onClose, defaultVisibility, oxyServices, linkContext]);
|
|
307
308
|
|
|
308
|
-
//
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
309
|
+
// Private-safe thumbnail URLs for the currently-shown files, resolved in
|
|
310
|
+
// ONE batch per page (not N per-tile) and cached by React Query. Uploads
|
|
311
|
+
// default to private, so the synchronous public-CDN URL would 404 for
|
|
312
|
+
// every private thumbnail.
|
|
313
|
+
const resolvedThumbUrls = useResolvedFileUrls(oxyServices, filteredFiles, user?.id);
|
|
314
|
+
|
|
315
|
+
// Image source for a grid tile: the resolved private-safe URL for a
|
|
316
|
+
// persisted file, or the locally-picked preview for an in-flight optimistic
|
|
317
|
+
// entry. Never builds an asset URL from a `temp-…`/uploading id.
|
|
318
|
+
const thumbSourceFor = useCallback(file => fileThumbSource(file, resolvedThumbUrls), [resolvedThumbUrls]);
|
|
312
319
|
const bloomTheme = useTheme();
|
|
313
320
|
const {
|
|
314
321
|
colors
|
|
@@ -437,7 +444,14 @@ const FileManagementScreen = ({
|
|
|
437
444
|
try {
|
|
438
445
|
await Promise.all(photosToLoad.map(async photo => {
|
|
439
446
|
try {
|
|
440
|
-
const downloadUrl =
|
|
447
|
+
const downloadUrl = thumbSourceFor(photo);
|
|
448
|
+
// URL not resolved yet — skip (do NOT record fallback
|
|
449
|
+
// dims) so this photo is re-measured once its private-safe
|
|
450
|
+
// URL resolves. Measuring the broken public URL is exactly
|
|
451
|
+
// the bug we are fixing.
|
|
452
|
+
if (!downloadUrl) {
|
|
453
|
+
return;
|
|
454
|
+
}
|
|
441
455
|
|
|
442
456
|
// Unified approach using Image.getSize (works on all platforms)
|
|
443
457
|
await new Promise(resolve => {
|
|
@@ -475,7 +489,19 @@ const FileManagementScreen = ({
|
|
|
475
489
|
} finally {
|
|
476
490
|
setLoadingDimensions(false);
|
|
477
491
|
}
|
|
478
|
-
}, [
|
|
492
|
+
}, [thumbSourceFor, photoDimensions]);
|
|
493
|
+
|
|
494
|
+
// Re-measure photo dimensions when their private-safe URLs resolve. The
|
|
495
|
+
// justified grid's own trigger fires on the photo SET, not on URL
|
|
496
|
+
// availability, so newly-resolved private tiles would otherwise keep their
|
|
497
|
+
// skipped (unmeasured) state and render with fallback geometry.
|
|
498
|
+
useEffect(() => {
|
|
499
|
+
if (viewMode !== 'photos') return;
|
|
500
|
+
const photos = filteredFiles.filter(file => file.contentType.startsWith('image/'));
|
|
501
|
+
if (photos.length > 0) {
|
|
502
|
+
loadPhotoDimensions(photos);
|
|
503
|
+
}
|
|
504
|
+
}, [resolvedThumbUrls, viewMode, filteredFiles, loadPhotoDimensions]);
|
|
479
505
|
|
|
480
506
|
// Create justified rows from photos with responsive algorithm
|
|
481
507
|
const createJustifiedRows = useCallback((photos, containerWidth) => {
|
|
@@ -619,9 +645,10 @@ const FileManagementScreen = ({
|
|
|
619
645
|
// Unified download function - works on all platforms
|
|
620
646
|
const handleFileDownload = async (fileId, filename) => {
|
|
621
647
|
try {
|
|
622
|
-
//
|
|
623
|
-
//
|
|
624
|
-
|
|
648
|
+
// Resolve an authenticated, private-safe URL. The synchronous
|
|
649
|
+
// `getFileDownloadUrl` yields the public CDN origin, which 404s for
|
|
650
|
+
// private assets (the default visibility).
|
|
651
|
+
const downloadUrl = await oxyServices.getFileDownloadUrlAsync(fileId);
|
|
625
652
|
|
|
626
653
|
// For web platforms, use link download
|
|
627
654
|
if (typeof window !== 'undefined' && window.document) {
|
|
@@ -673,8 +700,10 @@ const FileManagementScreen = ({
|
|
|
673
700
|
if (file.contentType.startsWith('text/') || file.contentType.includes('json') || file.contentType.includes('xml') || file.contentType.includes('javascript') || file.contentType.includes('typescript') || file.contentType.startsWith('image/') || file.contentType.includes('pdf') || file.contentType.startsWith('video/') || file.contentType.startsWith('audio/')) {
|
|
674
701
|
try {
|
|
675
702
|
if (file.contentType.startsWith('image/') || file.contentType.includes('pdf') || file.contentType.startsWith('video/') || file.contentType.startsWith('audio/')) {
|
|
676
|
-
// For images, PDFs, videos, and audio, we
|
|
677
|
-
|
|
703
|
+
// For images, PDFs, videos, and audio, we render the URL
|
|
704
|
+
// directly. Resolve the authenticated, private-safe URL —
|
|
705
|
+
// the synchronous public-CDN URL 404s for private assets.
|
|
706
|
+
const downloadUrl = await oxyServices.getFileDownloadUrlAsync(file.id);
|
|
678
707
|
setFileContent(downloadUrl);
|
|
679
708
|
} else {
|
|
680
709
|
// For text files, get the content using authenticated request
|
|
@@ -710,7 +739,7 @@ const FileManagementScreen = ({
|
|
|
710
739
|
fileDetailsControl.open();
|
|
711
740
|
};
|
|
712
741
|
const renderSimplePhotoItem = useCallback((photo, index) => {
|
|
713
|
-
const downloadUrl =
|
|
742
|
+
const downloadUrl = thumbSourceFor(photo);
|
|
714
743
|
|
|
715
744
|
// Calculate photo item width based on actual container size from bottom sheet
|
|
716
745
|
let itemsPerRow = 3; // Default for mobile
|
|
@@ -758,9 +787,9 @@ const FileManagementScreen = ({
|
|
|
758
787
|
})]
|
|
759
788
|
})
|
|
760
789
|
}, photo.id);
|
|
761
|
-
}, [
|
|
790
|
+
}, [thumbSourceFor, safeContainerWidth, selectMode, selectedIds, colors.primary, colors.text]);
|
|
762
791
|
const renderJustifiedPhotoItem = useCallback((photo, width, height, isLast) => {
|
|
763
|
-
const downloadUrl =
|
|
792
|
+
const downloadUrl = thumbSourceFor(photo);
|
|
764
793
|
return /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
765
794
|
style: [fileManagementStyles.justifiedPhotoItem, {
|
|
766
795
|
width,
|
|
@@ -799,7 +828,7 @@ const FileManagementScreen = ({
|
|
|
799
828
|
})]
|
|
800
829
|
})
|
|
801
830
|
}, photo.id);
|
|
802
|
-
}, [
|
|
831
|
+
}, [thumbSourceFor, selectMode, selectedIds, multiSelect, colors.primary, colors.text]);
|
|
803
832
|
|
|
804
833
|
// Run initial load once per targetUserId change to avoid accidental loops
|
|
805
834
|
const lastLoadedFor = useRef(undefined);
|
|
@@ -835,7 +864,7 @@ const FileManagementScreen = ({
|
|
|
835
864
|
style: fileManagementStyles.filePreview,
|
|
836
865
|
children: [isImage && /*#__PURE__*/_jsx(ExpoImage, {
|
|
837
866
|
source: {
|
|
838
|
-
uri:
|
|
867
|
+
uri: thumbSourceFor(file)
|
|
839
868
|
},
|
|
840
869
|
style: fileManagementStyles.previewImage,
|
|
841
870
|
contentFit: "cover",
|
|
@@ -861,7 +890,7 @@ const FileManagementScreen = ({
|
|
|
861
890
|
style: fileManagementStyles.videoPreviewWrapper,
|
|
862
891
|
children: [/*#__PURE__*/_jsx(ExpoImage, {
|
|
863
892
|
source: {
|
|
864
|
-
uri:
|
|
893
|
+
uri: thumbSourceFor(file)
|
|
865
894
|
},
|
|
866
895
|
style: fileManagementStyles.videoPosterImage,
|
|
867
896
|
contentFit: "cover",
|
|
@@ -990,7 +1019,7 @@ const FileManagementScreen = ({
|
|
|
990
1019
|
},
|
|
991
1020
|
children: /*#__PURE__*/_jsx(ExpoImage, {
|
|
992
1021
|
source: {
|
|
993
|
-
uri:
|
|
1022
|
+
uri: thumbSourceFor(file)
|
|
994
1023
|
},
|
|
995
1024
|
style: {
|
|
996
1025
|
width: 36,
|
|
@@ -1017,7 +1046,7 @@ const FileManagementScreen = ({
|
|
|
1017
1046
|
},
|
|
1018
1047
|
children: [/*#__PURE__*/_jsx(ExpoImage, {
|
|
1019
1048
|
source: {
|
|
1020
|
-
uri:
|
|
1049
|
+
uri: thumbSourceFor(file)
|
|
1021
1050
|
},
|
|
1022
1051
|
style: {
|
|
1023
1052
|
width: 36,
|
|
@@ -1125,7 +1154,7 @@ const FileManagementScreen = ({
|
|
|
1125
1154
|
}) : undefined
|
|
1126
1155
|
};
|
|
1127
1156
|
});
|
|
1128
|
-
}, [filteredFiles, theme, deleting, handleFileDownload, confirmFileDelete, handleFileOpen,
|
|
1157
|
+
}, [filteredFiles, theme, deleting, handleFileDownload, confirmFileDelete, handleFileOpen, thumbSourceFor, selectMode, selectedIds]);
|
|
1129
1158
|
|
|
1130
1159
|
// Scroll to selected file after selection
|
|
1131
1160
|
useEffect(() => {
|
|
@@ -1209,7 +1238,7 @@ const FileManagementScreen = ({
|
|
|
1209
1238
|
}
|
|
1210
1239
|
}, [lastSelectedFileId]);
|
|
1211
1240
|
const renderPhotoItem = (photo, index) => {
|
|
1212
|
-
const downloadUrl =
|
|
1241
|
+
const downloadUrl = thumbSourceFor(photo);
|
|
1213
1242
|
|
|
1214
1243
|
// Calculate photo item width based on actual container size from bottom sheet
|
|
1215
1244
|
let itemsPerRow = 3; // Default for mobile
|
|
@@ -1612,7 +1641,7 @@ const FileManagementScreen = ({
|
|
|
1612
1641
|
hasMore: paging.hasMore,
|
|
1613
1642
|
loadingMore: paging.loadingMore,
|
|
1614
1643
|
reduceMotion: reduceMotion,
|
|
1615
|
-
getThumbUrl:
|
|
1644
|
+
getThumbUrl: thumbSourceFor,
|
|
1616
1645
|
primaryColor: colors.primary,
|
|
1617
1646
|
isOwner: isOwner,
|
|
1618
1647
|
onTogglePhoto: toggleSelect,
|