@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.
Files changed (179) hide show
  1. package/lib/commonjs/index.js +1 -1
  2. package/lib/commonjs/ui/client.js +1 -1
  3. package/lib/commonjs/ui/components/FontLoader.js +18 -145
  4. package/lib/commonjs/ui/components/FontLoader.js.map +1 -1
  5. package/lib/commonjs/ui/components/FontLoader.native.js +88 -0
  6. package/lib/commonjs/ui/components/FontLoader.native.js.map +1 -0
  7. package/lib/commonjs/ui/components/OxyProvider.js +1 -1
  8. package/lib/commonjs/ui/components/fileManagement/FileDetailsModal.js +34 -41
  9. package/lib/commonjs/ui/components/fileManagement/FileDetailsModal.js.map +1 -1
  10. package/lib/commonjs/ui/components/fileManagement/UploadPreview.js.map +1 -1
  11. package/lib/commonjs/ui/components/fileManagement/styles.js +1 -225
  12. package/lib/commonjs/ui/components/fileManagement/styles.js.map +1 -1
  13. package/lib/commonjs/ui/components/photogrid/JustifiedPhotoGrid.js +0 -2
  14. package/lib/commonjs/ui/components/photogrid/JustifiedPhotoGrid.js.map +1 -1
  15. package/lib/commonjs/ui/context/hooks/useAuthOperations.js +5 -2
  16. package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
  17. package/lib/commonjs/ui/context/useOxyAccountGraph.js +7 -0
  18. package/lib/commonjs/ui/context/useOxyAccountGraph.js.map +1 -1
  19. package/lib/commonjs/ui/hooks/queries/useAccountQueries.js +10 -4
  20. package/lib/commonjs/ui/hooks/queries/useAccountQueries.js.map +1 -1
  21. package/lib/commonjs/ui/hooks/queries/userCache.js +33 -9
  22. package/lib/commonjs/ui/hooks/queries/userCache.js.map +1 -1
  23. package/lib/commonjs/ui/hooks/useAvatarPicker.js +23 -8
  24. package/lib/commonjs/ui/hooks/useAvatarPicker.js.map +1 -1
  25. package/lib/commonjs/ui/hooks/useFileDownloadUrl.js +7 -21
  26. package/lib/commonjs/ui/hooks/useFileDownloadUrl.js.map +1 -1
  27. package/lib/commonjs/ui/hooks/useResolvedFileUrls.js +163 -0
  28. package/lib/commonjs/ui/hooks/useResolvedFileUrls.js.map +1 -0
  29. package/lib/commonjs/ui/index.js +1 -1
  30. package/lib/commonjs/ui/screens/FileManagementScreen.js +51 -22
  31. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
  32. package/lib/commonjs/ui/screens/fileManagement/PhotoPickerSection.js +227 -204
  33. package/lib/commonjs/ui/screens/fileManagement/PhotoPickerSection.js.map +1 -1
  34. package/lib/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.js +26 -9
  35. package/lib/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.js.map +1 -1
  36. package/lib/commonjs/ui/screens/fileManagement/photoGridLayout.js +44 -0
  37. package/lib/commonjs/ui/screens/fileManagement/photoGridLayout.js.map +1 -0
  38. package/lib/commonjs/ui/session/tokenTransport.js +21 -10
  39. package/lib/commonjs/ui/session/tokenTransport.js.map +1 -1
  40. package/lib/commonjs/ui/utils/fileManagement.js +3 -43
  41. package/lib/commonjs/ui/utils/fileManagement.js.map +1 -1
  42. package/lib/module/index.js +1 -1
  43. package/lib/module/index.js.map +1 -1
  44. package/lib/module/ui/client.js +1 -1
  45. package/lib/module/ui/client.js.map +1 -1
  46. package/lib/module/ui/components/FontLoader.js +18 -146
  47. package/lib/module/ui/components/FontLoader.js.map +1 -1
  48. package/lib/module/ui/components/FontLoader.native.js +83 -0
  49. package/lib/module/ui/components/FontLoader.native.js.map +1 -0
  50. package/lib/module/ui/components/OxyProvider.js +1 -1
  51. package/lib/module/ui/components/OxyProvider.js.map +1 -1
  52. package/lib/module/ui/components/fileManagement/FileDetailsModal.js +34 -41
  53. package/lib/module/ui/components/fileManagement/FileDetailsModal.js.map +1 -1
  54. package/lib/module/ui/components/fileManagement/UploadPreview.js.map +1 -1
  55. package/lib/module/ui/components/fileManagement/styles.js +0 -224
  56. package/lib/module/ui/components/fileManagement/styles.js.map +1 -1
  57. package/lib/module/ui/components/photogrid/JustifiedPhotoGrid.js +0 -2
  58. package/lib/module/ui/components/photogrid/JustifiedPhotoGrid.js.map +1 -1
  59. package/lib/module/ui/context/hooks/useAuthOperations.js +5 -2
  60. package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
  61. package/lib/module/ui/context/useOxyAccountGraph.js +7 -0
  62. package/lib/module/ui/context/useOxyAccountGraph.js.map +1 -1
  63. package/lib/module/ui/hooks/queries/useAccountQueries.js +10 -4
  64. package/lib/module/ui/hooks/queries/useAccountQueries.js.map +1 -1
  65. package/lib/module/ui/hooks/queries/userCache.js +33 -9
  66. package/lib/module/ui/hooks/queries/userCache.js.map +1 -1
  67. package/lib/module/ui/hooks/useAvatarPicker.js +23 -8
  68. package/lib/module/ui/hooks/useAvatarPicker.js.map +1 -1
  69. package/lib/module/ui/hooks/useFileDownloadUrl.js +7 -21
  70. package/lib/module/ui/hooks/useFileDownloadUrl.js.map +1 -1
  71. package/lib/module/ui/hooks/useResolvedFileUrls.js +157 -0
  72. package/lib/module/ui/hooks/useResolvedFileUrls.js.map +1 -0
  73. package/lib/module/ui/index.js +1 -1
  74. package/lib/module/ui/index.js.map +1 -1
  75. package/lib/module/ui/screens/FileManagementScreen.js +52 -23
  76. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
  77. package/lib/module/ui/screens/fileManagement/PhotoPickerSection.js +229 -206
  78. package/lib/module/ui/screens/fileManagement/PhotoPickerSection.js.map +1 -1
  79. package/lib/module/ui/screens/fileManagement/hooks/useFileUploadState.js +26 -9
  80. package/lib/module/ui/screens/fileManagement/hooks/useFileUploadState.js.map +1 -1
  81. package/lib/module/ui/screens/fileManagement/photoGridLayout.js +39 -0
  82. package/lib/module/ui/screens/fileManagement/photoGridLayout.js.map +1 -0
  83. package/lib/module/ui/session/tokenTransport.js +21 -10
  84. package/lib/module/ui/session/tokenTransport.js.map +1 -1
  85. package/lib/module/ui/utils/fileManagement.js +3 -42
  86. package/lib/module/ui/utils/fileManagement.js.map +1 -1
  87. package/lib/typescript/commonjs/ui/components/FontLoader.d.ts +14 -5
  88. package/lib/typescript/commonjs/ui/components/FontLoader.d.ts.map +1 -1
  89. package/lib/typescript/commonjs/ui/components/FontLoader.native.d.ts +13 -0
  90. package/lib/typescript/commonjs/ui/components/FontLoader.native.d.ts.map +1 -0
  91. package/lib/typescript/commonjs/ui/components/fileManagement/FileDetailsModal.d.ts.map +1 -1
  92. package/lib/typescript/commonjs/ui/components/fileManagement/styles.d.ts +0 -218
  93. package/lib/typescript/commonjs/ui/components/fileManagement/styles.d.ts.map +1 -1
  94. package/lib/typescript/commonjs/ui/components/photogrid/JustifiedPhotoGrid.d.ts.map +1 -1
  95. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  96. package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts.map +1 -1
  97. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts +2 -2
  98. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  99. package/lib/typescript/commonjs/ui/hooks/queries/useAccountQueries.d.ts +9 -0
  100. package/lib/typescript/commonjs/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
  101. package/lib/typescript/commonjs/ui/hooks/queries/userCache.d.ts +3 -0
  102. package/lib/typescript/commonjs/ui/hooks/queries/userCache.d.ts.map +1 -1
  103. package/lib/typescript/commonjs/ui/hooks/useAvatarPicker.d.ts.map +1 -1
  104. package/lib/typescript/commonjs/ui/hooks/useFileDownloadUrl.d.ts +3 -2
  105. package/lib/typescript/commonjs/ui/hooks/useFileDownloadUrl.d.ts.map +1 -1
  106. package/lib/typescript/commonjs/ui/hooks/useResolvedFileUrls.d.ts +48 -0
  107. package/lib/typescript/commonjs/ui/hooks/useResolvedFileUrls.d.ts.map +1 -0
  108. package/lib/typescript/commonjs/ui/screens/FileManagementScreen.d.ts.map +1 -1
  109. package/lib/typescript/commonjs/ui/screens/fileManagement/PhotoPickerSection.d.ts +1 -1
  110. package/lib/typescript/commonjs/ui/screens/fileManagement/PhotoPickerSection.d.ts.map +1 -1
  111. package/lib/typescript/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
  112. package/lib/typescript/commonjs/ui/screens/fileManagement/photoGridLayout.d.ts +37 -0
  113. package/lib/typescript/commonjs/ui/screens/fileManagement/photoGridLayout.d.ts.map +1 -0
  114. package/lib/typescript/commonjs/ui/session/tokenTransport.d.ts +15 -8
  115. package/lib/typescript/commonjs/ui/session/tokenTransport.d.ts.map +1 -1
  116. package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts +4 -11
  117. package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts.map +1 -1
  118. package/lib/typescript/module/index.d.ts +1 -1
  119. package/lib/typescript/module/index.d.ts.map +1 -1
  120. package/lib/typescript/module/ui/client.d.ts +1 -1
  121. package/lib/typescript/module/ui/client.d.ts.map +1 -1
  122. package/lib/typescript/module/ui/components/FontLoader.d.ts +14 -5
  123. package/lib/typescript/module/ui/components/FontLoader.d.ts.map +1 -1
  124. package/lib/typescript/module/ui/components/FontLoader.native.d.ts +13 -0
  125. package/lib/typescript/module/ui/components/FontLoader.native.d.ts.map +1 -0
  126. package/lib/typescript/module/ui/components/fileManagement/FileDetailsModal.d.ts.map +1 -1
  127. package/lib/typescript/module/ui/components/fileManagement/styles.d.ts +0 -218
  128. package/lib/typescript/module/ui/components/fileManagement/styles.d.ts.map +1 -1
  129. package/lib/typescript/module/ui/components/photogrid/JustifiedPhotoGrid.d.ts.map +1 -1
  130. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  131. package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts.map +1 -1
  132. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts +2 -2
  133. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  134. package/lib/typescript/module/ui/hooks/queries/useAccountQueries.d.ts +9 -0
  135. package/lib/typescript/module/ui/hooks/queries/useAccountQueries.d.ts.map +1 -1
  136. package/lib/typescript/module/ui/hooks/queries/userCache.d.ts +3 -0
  137. package/lib/typescript/module/ui/hooks/queries/userCache.d.ts.map +1 -1
  138. package/lib/typescript/module/ui/hooks/useAvatarPicker.d.ts.map +1 -1
  139. package/lib/typescript/module/ui/hooks/useFileDownloadUrl.d.ts +3 -2
  140. package/lib/typescript/module/ui/hooks/useFileDownloadUrl.d.ts.map +1 -1
  141. package/lib/typescript/module/ui/hooks/useResolvedFileUrls.d.ts +48 -0
  142. package/lib/typescript/module/ui/hooks/useResolvedFileUrls.d.ts.map +1 -0
  143. package/lib/typescript/module/ui/index.d.ts +1 -1
  144. package/lib/typescript/module/ui/index.d.ts.map +1 -1
  145. package/lib/typescript/module/ui/screens/FileManagementScreen.d.ts.map +1 -1
  146. package/lib/typescript/module/ui/screens/fileManagement/PhotoPickerSection.d.ts +1 -1
  147. package/lib/typescript/module/ui/screens/fileManagement/PhotoPickerSection.d.ts.map +1 -1
  148. package/lib/typescript/module/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
  149. package/lib/typescript/module/ui/screens/fileManagement/photoGridLayout.d.ts +37 -0
  150. package/lib/typescript/module/ui/screens/fileManagement/photoGridLayout.d.ts.map +1 -0
  151. package/lib/typescript/module/ui/session/tokenTransport.d.ts +15 -8
  152. package/lib/typescript/module/ui/session/tokenTransport.d.ts.map +1 -1
  153. package/lib/typescript/module/ui/utils/fileManagement.d.ts +4 -11
  154. package/lib/typescript/module/ui/utils/fileManagement.d.ts.map +1 -1
  155. package/package.json +5 -10
  156. package/src/ui/components/FontLoader.native.tsx +88 -0
  157. package/src/ui/components/FontLoader.tsx +16 -151
  158. package/src/ui/components/fileManagement/FileDetailsModal.tsx +29 -28
  159. package/src/ui/components/fileManagement/UploadPreview.tsx +1 -1
  160. package/src/ui/components/fileManagement/styles.ts +0 -225
  161. package/src/ui/components/photogrid/JustifiedPhotoGrid.tsx +0 -1
  162. package/src/ui/context/hooks/useAuthOperations.ts +5 -2
  163. package/src/ui/context/useOxyAccountGraph.ts +5 -0
  164. package/src/ui/hooks/queries/__tests__/userCache.test.ts +29 -0
  165. package/src/ui/hooks/queries/useAccountQueries.ts +10 -4
  166. package/src/ui/hooks/queries/userCache.ts +31 -8
  167. package/src/ui/hooks/useAvatarPicker.ts +27 -7
  168. package/src/ui/hooks/useFileDownloadUrl.ts +7 -23
  169. package/src/ui/hooks/useResolvedFileUrls.ts +170 -0
  170. package/src/ui/screens/FileManagementScreen.tsx +55 -27
  171. package/src/ui/screens/__tests__/photoGridLayout.test.ts +57 -0
  172. package/src/ui/screens/fileManagement/PhotoPickerSection.tsx +229 -215
  173. package/src/ui/screens/fileManagement/hooks/useFileUploadState.ts +27 -3
  174. package/src/ui/screens/fileManagement/photoGridLayout.ts +45 -0
  175. package/src/ui/session/__tests__/tokenTransport.test.ts +25 -10
  176. package/src/ui/session/tokenTransport.ts +21 -10
  177. package/src/ui/utils/fileManagement.ts +8 -49
  178. package/lib/typescript/types/expo-vector-icons.d.ts +0 -22
  179. package/src/types/expo-vector-icons.d.ts +0 -22
@@ -38,6 +38,9 @@ var _authStore = require("../../stores/authStore.js");
38
38
  * marked stale — it is already managed).
39
39
  * - Nested objects (`name`, `_count`, `relationship`) merge field-by-field, so
40
40
  * a partial `name`/`_count`/`relationship` never replaces a fuller one.
41
+ * - `relationship` is written ONLY under the viewer-scoped by-username key —
42
+ * the viewer-independent by-id key never stores it (prevents one viewer's
43
+ * follow state from leaking into every other viewer's identity cache).
41
44
  * - Anti-degradation: a good `username` / `name.displayName` / `avatar` is
42
45
  * never overwritten by a degraded/empty one (empty username, the
43
46
  * `'Unknown user'` ghost-author sentinel, `null` avatar).
@@ -167,8 +170,13 @@ function mergeRelationship(existing, incoming) {
167
170
  /**
168
171
  * Merge a (normalized) incoming user over an existing cache entry: keep every
169
172
  * existing field, override only with the meaningful fields of `incoming`.
173
+ *
174
+ * When `includeRelationship` is false (the viewer-independent by-id key), the
175
+ * viewer-relative `relationship` field is never read, written, or preserved —
176
+ * only the by-username key carries it (`useUserByUsername`).
170
177
  */
171
- function mergeUsers(existing, incoming) {
178
+ function mergeUsers(existing, incoming, options) {
179
+ const includeRelationship = options?.includeRelationship ?? true;
172
180
  const merged = {
173
181
  ...existing
174
182
  };
@@ -184,25 +192,35 @@ function mergeUsers(existing, incoming) {
184
192
  if (name !== undefined) merged.name = name;
185
193
  const count = mergeCount(existing._count, incoming._count);
186
194
  if (count !== undefined) merged._count = count;
187
- const relationship = mergeRelationship(existing.relationship, incoming.relationship);
188
- if (relationship !== undefined) merged.relationship = relationship;
195
+ if (includeRelationship) {
196
+ const relationship = mergeRelationship(existing.relationship, incoming.relationship);
197
+ if (relationship !== undefined) merged.relationship = relationship;
198
+ } else {
199
+ delete merged.relationship;
200
+ }
189
201
  return merged;
190
202
  }
191
203
 
192
204
  /** Merge-upsert a normalized user into one cache key (see module docs for semantics). */
193
- function upsertOneKey(queryClient, key, incoming) {
205
+ function upsertOneKey(queryClient, key, incoming, options) {
206
+ const mergeOpts = {
207
+ includeRelationship: options.includeRelationship
208
+ };
194
209
  const existing = queryClient.getQueryData(key);
195
210
  if (existing === undefined) {
196
211
  // Cold slot: seed the full incoming object, STALE, so react-query refetches
197
212
  // the full authoritative profile (relationship, counts, createdAt, …).
198
- queryClient.setQueryData(key, incoming, {
213
+ const seeded = mergeUsers({
214
+ id: incoming.id
215
+ }, incoming, mergeOpts);
216
+ queryClient.setQueryData(key, seeded, {
199
217
  updatedAt: 0
200
218
  });
201
219
  return;
202
220
  }
203
221
  // Existing entry: merge and leave its freshness lifecycle untouched. The
204
222
  // existing entry is keyed by `incoming.id`, so use it as the fallback id.
205
- const merged = mergeUsers(toCachedUser(existing, incoming.id), incoming);
223
+ const merged = mergeUsers(toCachedUser(existing, incoming.id), incoming, mergeOpts);
206
224
  const dataUpdatedAt = queryClient.getQueryState(key)?.dataUpdatedAt ?? 0;
207
225
  queryClient.setQueryData(key, merged, {
208
226
  updatedAt: dataUpdatedAt
@@ -234,8 +252,12 @@ function upsertCachedUser(queryClient, user, viewerId) {
234
252
  const incoming = normalizeIncoming(user);
235
253
  if (!incoming) return;
236
254
 
237
- // By-id identity entry (read by `useUserById`). Not viewer-scoped.
238
- upsertOneKey(queryClient, _queryKeys.queryKeys.users.detail(incoming.id), incoming);
255
+ // By-id identity entry (read by `useUserById`). Not viewer-scoped — never store
256
+ // the viewer-relative `relationship` here or one viewer's follow state leaks
257
+ // into every other viewer's by-id cache entry.
258
+ upsertOneKey(queryClient, _queryKeys.queryKeys.users.detail(incoming.id), incoming, {
259
+ includeRelationship: false
260
+ });
239
261
  const username = incoming.username;
240
262
  if (typeof username === 'string' && username.trim() !== '') {
241
263
  // By-username entry (read by `useUserByUsername`). Viewer-scoped because the
@@ -243,7 +265,9 @@ function upsertCachedUser(queryClient, user, viewerId) {
243
265
  // the key through the SAME helper the hook uses so username normalization
244
266
  // (`trim().toLowerCase()`) matches byte-for-byte.
245
267
  const key = _queryKeys.queryKeys.users.byUsername(username, resolveViewerId(viewerId));
246
- upsertOneKey(queryClient, key, incoming);
268
+ upsertOneKey(queryClient, key, incoming, {
269
+ includeRelationship: true
270
+ });
247
271
  }
248
272
  }
249
273
 
@@ -1 +1 @@
1
- {"version":3,"names":["_queryKeys","require","_authStore","DEGRADED_DISPLAY_NAME","isMeaningful","value","undefined","trim","isMeaningfulDisplayName","isPlainObject","Array","isArray","normalizeName","name","trimmed","displayName","toCachedUser","user","fallbackId","rawName","rest","id","String","_id","normalized","normalizeIncoming","cached","mergeName","existing","incoming","merged","key","Object","entries","mergeCount","followers","following","mergeRelationship","isFollowing","followsYou","mergeUsers","count","_count","relationship","upsertOneKey","queryClient","getQueryData","setQueryData","updatedAt","dataUpdatedAt","getQueryState","resolveViewerId","viewerId","useAuthStore","getState","upsertCachedUser","queryKeys","users","detail","username","byUsername","upsertCachedUsers","length","resolvedViewerId"],"sourceRoot":"../../../../../src","sources":["ui/hooks/queries/userCache.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_queryKeys","require","_authStore","DEGRADED_DISPLAY_NAME","isMeaningful","value","undefined","trim","isMeaningfulDisplayName","isPlainObject","Array","isArray","normalizeName","name","trimmed","displayName","toCachedUser","user","fallbackId","rawName","rest","id","String","_id","normalized","normalizeIncoming","cached","mergeName","existing","incoming","merged","key","Object","entries","mergeCount","followers","following","mergeRelationship","isFollowing","followsYou","mergeUsers","options","includeRelationship","count","_count","relationship","upsertOneKey","queryClient","mergeOpts","getQueryData","seeded","setQueryData","updatedAt","dataUpdatedAt","getQueryState","resolveViewerId","viewerId","useAuthStore","getState","upsertCachedUser","queryKeys","users","detail","username","byUsername","upsertCachedUsers","length","resolvedViewerId"],"sourceRoot":"../../../../../src","sources":["ui/hooks/queries/userCache.ts"],"mappings":"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","ignoreList":[]}
@@ -68,19 +68,34 @@ function useAvatarPicker({
68
68
  }, [activeSessionId, currentLanguage, oxyServices, queryClient]);
69
69
 
70
70
  /**
71
- * After the user picks a file in the FileManagement sheet, route to the
72
- * crop screen with the file's download URL as the source image.
71
+ * After the user picks a file in the FileManagement sheet, resolve a working
72
+ * source URL and route to the crop screen.
73
+ *
74
+ * The picked file is usually PRIVATE, so the synchronous
75
+ * `getFileDownloadUrl` (public CDN origin) would 404 and the crop screen's
76
+ * `Image.getSize` would fail silently. We resolve the authenticated URL via
77
+ * `assetGetUrl` (which throws on failure — unlike `getFileDownloadUrlAsync`,
78
+ * which swallows errors and falls back to the broken public URL) so a
79
+ * failure surfaces a real user-facing error instead of a blank crop canvas.
80
+ * No variant is requested — cropping needs the original.
73
81
  */
74
- const handleFilePicked = (0, _react.useCallback)(file => {
82
+ const handleFilePicked = (0, _react.useCallback)(async file => {
75
83
  if (!file.contentType?.startsWith('image/')) {
76
84
  _bloom.toast.error((0, _core.translate)(currentLanguage ?? undefined, 'editProfile.toasts.selectImage') || 'Please select an image file');
77
85
  return;
78
86
  }
79
-
80
- // Use the public download URL of the picked file as the crop source.
81
- // The OxyServices file URL endpoints accept image variants, but for
82
- // cropping we want the original — passing no variant returns it.
83
- const sourceUri = oxyServices.getFileDownloadUrl(file.id);
87
+ let sourceUri;
88
+ try {
89
+ const resolved = await oxyServices.assetGetUrl(file.id);
90
+ if (!resolved?.url) {
91
+ throw new Error('No download URL returned for the selected image');
92
+ }
93
+ sourceUri = resolved.url;
94
+ } catch (e) {
95
+ const message = e instanceof Error ? e.message : undefined;
96
+ _bloom.toast.error(message || (0, _core.translate)(currentLanguage ?? undefined, 'editProfile.toasts.cropMeasureFailed') || 'Could not load the selected image');
97
+ return;
98
+ }
84
99
  showBottomSheet({
85
100
  screen: 'AvatarCrop',
86
101
  props: {
@@ -1 +1 @@
1
- {"version":3,"names":["_react","require","_core","_bloom","_avatarUtils","extractUploadedFileId","result","undefined","id","file","first","files","useAvatarPicker","oxyServices","currentLanguage","activeSessionId","queryClient","showBottomSheet","finalizeCroppedAvatar","useCallback","cropped","uploadResult","assetUpload","uri","type","mime","name","Date","now","newFileId","Error","updateAvatarVisibility","updateProfileWithAvatar","avatar","toast","success","translate","e","message","error","handleFilePicked","contentType","startsWith","sourceUri","getFileDownloadUrl","screen","props","imageUri","onConfirm","openAvatarPicker","selectMode","multiSelect","disabledMimeTypes","afterSelect","onSelect"],"sourceRoot":"../../../../src","sources":["ui/hooks/useAvatarPicker.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_react","require","_core","_bloom","_avatarUtils","extractUploadedFileId","result","undefined","id","file","first","files","useAvatarPicker","oxyServices","currentLanguage","activeSessionId","queryClient","showBottomSheet","finalizeCroppedAvatar","useCallback","cropped","uploadResult","assetUpload","uri","type","mime","name","Date","now","newFileId","Error","updateAvatarVisibility","updateProfileWithAvatar","avatar","toast","success","translate","e","message","error","handleFilePicked","contentType","startsWith","sourceUri","resolved","assetGetUrl","url","screen","props","imageUri","onConfirm","openAvatarPicker","selectMode","multiSelect","disabledMimeTypes","afterSelect","onSelect"],"sourceRoot":"../../../../src","sources":["ui/hooks/useAvatarPicker.ts"],"mappings":";;;;;;AAgBA,IAAAA,MAAA,GAAAC,OAAA;AAEA,IAAAC,KAAA,GAAAD,OAAA;AAEA,IAAAE,MAAA,GAAAF,OAAA;AAEA,IAAAG,YAAA,GAAAH,OAAA;AAtBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAmBA;;AAOA,SAASI,qBAAqBA,CAACC,MAAqC,EAAsB;EACxF,IAAI,CAACA,MAAM,EAAE,OAAOC,SAAS;EAC7B,IAAI,OAAOD,MAAM,CAACE,EAAE,KAAK,QAAQ,EAAE,OAAOF,MAAM,CAACE,EAAE;EACnD,IAAIF,MAAM,CAACG,IAAI,EAAED,EAAE,EAAE,OAAOF,MAAM,CAACG,IAAI,CAACD,EAAE;EAC1C,MAAME,KAAK,GAAGJ,MAAM,CAACK,KAAK,GAAG,CAAC,CAAC;EAC/B,IAAID,KAAK,EAAEF,EAAE,EAAE,OAAOE,KAAK,CAACF,EAAE;EAC9B,OAAOD,SAAS;AAClB;AAEO,SAASK,eAAeA,CAAC;EAC9BC,WAAW;EACXC,eAAe;EACfC,eAAe;EACfC,WAAW;EACXC;AACsB,CAAC,EAAE;EACzB;AACF;AACA;AACA;EACE,MAAMC,qBAAqB,GAAG,IAAAC,kBAAW,EACvC,MAAOC,OAAyB,IAAK;IACnC,IAAI;MACF,MAAMC,YAAY,GAAI,MAAMR,WAAW,CAACS,WAAW,CACjD;QACEC,GAAG,EAAEH,OAAO,CAACG,GAAG;QAChBC,IAAI,EAAEJ,OAAO,CAACK,IAAI;QAClBC,IAAI,EAAE,UAAUC,IAAI,CAACC,GAAG,CAAC,CAAC;MAC5B,CAAC,EACD,QACF,CAAuB;MAEvB,MAAMC,SAAS,GAAGxB,qBAAqB,CAACgB,YAAY,CAAC;MACrD,IAAI,CAACQ,SAAS,EAAE;QACd,MAAM,IAAIC,KAAK,CAAC,qDAAqD,CAAC;MACxE;MAEA,MAAM,IAAAC,4BAAsB,EAACF,SAAS,EAAEhB,WAAW,EAAE,iBAAiB,CAAC;MACvE,MAAM,IAAAmB,oCAAuB,EAC3B;QAAEC,MAAM,EAAEJ;MAAU,CAAC,EACrBhB,WAAW,EACXE,eAAe,EACfC,WACF,CAAC;MAEDkB,YAAK,CAACC,OAAO,CACX,IAAAC,eAAS,EAACtB,eAAe,IAAIP,SAAS,EAAE,kCAAkC,CAAC,IACzE,gBACJ,CAAC;IACH,CAAC,CAAC,OAAO8B,CAAU,EAAE;MACnB,MAAMC,OAAO,GAAGD,CAAC,YAAYP,KAAK,GAAGO,CAAC,CAACC,OAAO,GAAG/B,SAAS;MAC1D2B,YAAK,CAACK,KAAK,CACTD,OAAO,IACL,IAAAF,eAAS,EAACtB,eAAe,IAAIP,SAAS,EAAE,uCAAuC,CAAC,IAChF,yBACJ,CAAC;IACH;EACF,CAAC,EACD,CAACQ,eAAe,EAAED,eAAe,EAAED,WAAW,EAAEG,WAAW,CAC7D,CAAC;;EAED;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;EACE,MAAMwB,gBAAgB,GAAG,IAAArB,kBAAW,EAClC,MAAOV,IAAkB,IAAK;IAC5B,IAAI,CAACA,IAAI,CAACgC,WAAW,EAAEC,UAAU,CAAC,QAAQ,CAAC,EAAE;MAC3CR,YAAK,CAACK,KAAK,CACT,IAAAH,eAAS,EAACtB,eAAe,IAAIP,SAAS,EAAE,gCAAgC,CAAC,IACvE,6BACJ,CAAC;MACD;IACF;IAEA,IAAIoC,SAAiB;IACrB,IAAI;MACF,MAAMC,QAAQ,GAAG,MAAM/B,WAAW,CAACgC,WAAW,CAACpC,IAAI,CAACD,EAAE,CAAC;MACvD,IAAI,CAACoC,QAAQ,EAAEE,GAAG,EAAE;QAClB,MAAM,IAAIhB,KAAK,CAAC,iDAAiD,CAAC;MACpE;MACAa,SAAS,GAAGC,QAAQ,CAACE,GAAG;IAC1B,CAAC,CAAC,OAAOT,CAAU,EAAE;MACnB,MAAMC,OAAO,GAAGD,CAAC,YAAYP,KAAK,GAAGO,CAAC,CAACC,OAAO,GAAG/B,SAAS;MAC1D2B,YAAK,CAACK,KAAK,CACTD,OAAO,IACL,IAAAF,eAAS,EAACtB,eAAe,IAAIP,SAAS,EAAE,sCAAsC,CAAC,IAC/E,mCACJ,CAAC;MACD;IACF;IAEAU,eAAe,CAAC;MACd8B,MAAM,EAAE,YAAY;MACpBC,KAAK,EAAE;QACLC,QAAQ,EAAEN,SAAS;QACnBO,SAAS,EAAEhC;MACb;IACF,CAAC,CAAC;EACJ,CAAC,EACD,CAACJ,eAAe,EAAEI,qBAAqB,EAAEL,WAAW,EAAEI,eAAe,CACvE,CAAC;EAED,MAAMkC,gBAAgB,GAAG,IAAAhC,kBAAW,EAAC,MAAM;IACzCF,eAAe,CAAC;MACd8B,MAAM,EAAE,gBAAgB;MACxBC,KAAK,EAAE;QACLI,UAAU,EAAE,IAAI;QAChBC,WAAW,EAAE,KAAK;QAClBC,iBAAiB,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,CAAC;QAC1DC,WAAW,EAAE,MAAM;QACnBC,QAAQ,EAAEhB;MACZ;IACF,CAAC,CAAC;EACJ,CAAC,EAAE,CAACA,gBAAgB,EAAEvB,eAAe,CAAC,CAAC;EAEvC,OAAO;IAAEkC;EAAiB,CAAC;AAC7B","ignoreList":[]}
@@ -8,8 +8,9 @@ var _react = require("react");
8
8
  /**
9
9
  * Hook to resolve a file's download URL asynchronously.
10
10
  *
11
- * Uses `getFileDownloadUrlAsync` first, falling back to the synchronous
12
- * `getFileDownloadUrl` if the async call fails.
11
+ * Uses `getFileDownloadUrlAsync`, which returns a scoped media-token stream URL
12
+ * for private assets. There is no sync CDN fallback — the synchronous
13
+ * `getFileDownloadUrl` is public-CDN-only and 404s for private uploads.
13
14
  */
14
15
  const useFileDownloadUrl = (oxyServices, fileId, options) => {
15
16
  const [url, setUrl] = (0, _react.useState)(null);
@@ -37,31 +38,16 @@ const useFileDownloadUrl = (oxyServices, fileId, options) => {
37
38
  setLoading(true);
38
39
  setError(null);
39
40
  try {
40
- let resolvedUrl = null;
41
- if (typeof instance.getFileDownloadUrlAsync === 'function') {
42
- resolvedUrl = await instance.getFileDownloadUrlAsync(targetFileId, variant, expiresIn);
43
- }
44
- if (!resolvedUrl && typeof instance.getFileDownloadUrl === 'function') {
45
- resolvedUrl = instance.getFileDownloadUrl(targetFileId, variant, expiresIn);
41
+ if (typeof instance.getFileDownloadUrlAsync !== 'function') {
42
+ throw new Error('getFileDownloadUrlAsync is not available on this OxyServices instance');
46
43
  }
44
+ const resolvedUrl = await instance.getFileDownloadUrlAsync(targetFileId, variant, expiresIn);
47
45
  if (!cancelled) {
48
46
  setUrl(resolvedUrl || null);
49
47
  }
50
48
  } catch (err) {
51
- // Fallback to sync URL on error where possible
52
- try {
53
- if (typeof instance.getFileDownloadUrl === 'function') {
54
- const fallbackUrl = instance.getFileDownloadUrl(targetFileId, variant, expiresIn);
55
- if (!cancelled) {
56
- setUrl(fallbackUrl || null);
57
- setError(err instanceof Error ? err : new Error(String(err)));
58
- }
59
- return;
60
- }
61
- } catch {
62
- // Secondary failure: surface the original error below.
63
- }
64
49
  if (!cancelled) {
50
+ setUrl(null);
65
51
  setError(err instanceof Error ? err : new Error(String(err)));
66
52
  }
67
53
  } finally {
@@ -1 +1 @@
1
- {"version":3,"names":["_react","require","useFileDownloadUrl","oxyServices","fileId","options","url","setUrl","useState","loading","setLoading","error","setError","variant","expiresIn","useEffect","Error","cancelled","instance","targetFileId","load","resolvedUrl","getFileDownloadUrlAsync","getFileDownloadUrl","err","fallbackUrl","String","exports"],"sourceRoot":"../../../../src","sources":["ui/hooks/useFileDownloadUrl.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_react","require","useFileDownloadUrl","oxyServices","fileId","options","url","setUrl","useState","loading","setLoading","error","setError","variant","expiresIn","useEffect","Error","cancelled","instance","targetFileId","load","getFileDownloadUrlAsync","resolvedUrl","err","String","exports"],"sourceRoot":"../../../../src","sources":["ui/hooks/useFileDownloadUrl.ts"],"mappings":";;;;;;AAAA,IAAAA,MAAA,GAAAC,OAAA;AAcA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,MAAMC,kBAAkB,GAAGA,CAChCC,WAA2C,EAC3CC,MAAiC,EACjCC,OAAmC,KACN;EAC7B,MAAM,CAACC,GAAG,EAAEC,MAAM,CAAC,GAAG,IAAAC,eAAQ,EAAgB,IAAI,CAAC;EACnD,MAAM,CAACC,OAAO,EAAEC,UAAU,CAAC,GAAG,IAAAF,eAAQ,EAAC,KAAK,CAAC;EAC7C,MAAM,CAACG,KAAK,EAAEC,QAAQ,CAAC,GAAG,IAAAJ,eAAQ,EAAe,IAAI,CAAC;EAEtD,MAAMK,OAAO,GAAGR,OAAO,EAAEQ,OAAO;EAChC,MAAMC,SAAS,GAAGT,OAAO,EAAES,SAAS;EAEpC,IAAAC,gBAAS,EAAC,MAAM;IACd,IAAI,CAACX,MAAM,EAAE;MACXG,MAAM,CAAC,IAAI,CAAC;MACZG,UAAU,CAAC,KAAK,CAAC;MACjBE,QAAQ,CAAC,IAAI,CAAC;MACd;IACF;IAEA,IAAI,CAACT,WAAW,EAAE;MAChBI,MAAM,CAAC,IAAI,CAAC;MACZG,UAAU,CAAC,KAAK,CAAC;MACjBE,QAAQ,CAAC,IAAII,KAAK,CAAC,4DAA4D,CAAC,CAAC;MACjF;IACF;IAEA,IAAIC,SAAS,GAAG,KAAK;IACrB,MAAMC,QAAQ,GAAGf,WAAW;IAC5B,MAAMgB,YAAY,GAAGf,MAAM;IAE3B,MAAMgB,IAAI,GAAG,MAAAA,CAAA,KAAY;MACvBV,UAAU,CAAC,IAAI,CAAC;MAChBE,QAAQ,CAAC,IAAI,CAAC;MAEd,IAAI;QACF,IAAI,OAAOM,QAAQ,CAACG,uBAAuB,KAAK,UAAU,EAAE;UAC1D,MAAM,IAAIL,KAAK,CAAC,uEAAuE,CAAC;QAC1F;QAEA,MAAMM,WAAW,GAAG,MAAMJ,QAAQ,CAACG,uBAAuB,CAACF,YAAY,EAAEN,OAAO,EAAEC,SAAS,CAAC;QAE5F,IAAI,CAACG,SAAS,EAAE;UACdV,MAAM,CAACe,WAAW,IAAI,IAAI,CAAC;QAC7B;MACF,CAAC,CAAC,OAAOC,GAAY,EAAE;QACrB,IAAI,CAACN,SAAS,EAAE;UACdV,MAAM,CAAC,IAAI,CAAC;UACZK,QAAQ,CAACW,GAAG,YAAYP,KAAK,GAAGO,GAAG,GAAG,IAAIP,KAAK,CAACQ,MAAM,CAACD,GAAG,CAAC,CAAC,CAAC;QAC/D;MACF,CAAC,SAAS;QACR,IAAI,CAACN,SAAS,EAAE;UACdP,UAAU,CAAC,KAAK,CAAC;QACnB;MACF;IACF,CAAC;IAEDU,IAAI,CAAC,CAAC;IAEN,OAAO,MAAM;MACXH,SAAS,GAAG,IAAI;IAClB,CAAC;EACH,CAAC,EAAE,CAACb,MAAM,EAAED,WAAW,EAAEU,OAAO,EAAEC,SAAS,CAAC,CAAC;EAE7C,OAAO;IAAER,GAAG;IAAEG,OAAO;IAAEE;EAAM,CAAC;AAChC,CAAC;AAACc,OAAA,CAAAvB,kBAAA,GAAAA,kBAAA","ignoreList":[]}
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ASSET_DOWNLOAD_URLS_QUERY_KEY = void 0;
7
+ exports.fileThumbSource = fileThumbSource;
8
+ exports.isOptimisticFile = isOptimisticFile;
9
+ exports.useResolvedFileUrls = useResolvedFileUrls;
10
+ var _react = require("react");
11
+ var _reactQuery = require("@tanstack/react-query");
12
+ /**
13
+ * The variant-aware batch resolver contract (`@oxyhq/core`).
14
+ *
15
+ * `getFileDownloadUrls` takes a per-file `{ fileId, variant }` list and returns
16
+ * a map keyed by `fileId`; ids that are denied or missing are OMITTED (never an
17
+ * empty string), and PRIVATE assets resolve to a working scoped-media-token
18
+ * stream URL. Typed here rather than `Pick<OxyServices, …>` so this file states
19
+ * the exact contract it depends on.
20
+ */
21
+
22
+ /**
23
+ * Private-safe grid/thumbnail URL resolution.
24
+ *
25
+ * The synchronous `oxyServices.getFileDownloadUrl(id, variant)` always yields
26
+ * the public CDN origin (`cloud.oxy.so/<id>`), which 404s for PRIVATE assets —
27
+ * and uploads default to private. Thumbnails and previews therefore have to be
28
+ * resolved through the authenticated batch endpoint, which returns a working
29
+ * `/assets/:id/stream?…&mt=<scoped media token>` URL for private files.
30
+ *
31
+ * This hook resolves an ENTIRE page of files in ONE (chunked) batch request
32
+ * rather than N per-tile calls, and caches the result in React Query keyed by
33
+ * the (fileId, variant) set. `staleTime` is deliberately shorter than the
34
+ * server media-token TTL so a tile never renders a URL whose token has already
35
+ * expired.
36
+ *
37
+ * Optimistic (`temp-…` / `uploading`) entries are NEVER resolved here — an
38
+ * asset URL must never be built from an id the server does not yet know. Their
39
+ * preview comes from the locally-picked uri (see {@link fileThumbSource}).
40
+ */
41
+
42
+ /** Server media-token lifetime we request for each resolved URL (seconds). */
43
+ const ASSET_URL_TTL_SECONDS = 600; // 10 minutes
44
+ /**
45
+ * Refresh window. Kept below {@link ASSET_URL_TTL_SECONDS} so React Query
46
+ * re-resolves in the background before a rendered URL's token can die.
47
+ */
48
+ const ASSET_URL_STALE_MS = 5 * 60 * 1000; // 5 minutes
49
+ const ASSET_URL_GC_MS = 30 * 60 * 1000;
50
+ /** Server-side batch cap for `POST /assets/batch-access` — chunk beyond this. */
51
+ const BATCH_CAP = 100;
52
+
53
+ /** React Query prefix — scoped media URLs must never leak across accounts. */
54
+ const ASSET_DOWNLOAD_URLS_QUERY_KEY = exports.ASSET_DOWNLOAD_URLS_QUERY_KEY = 'assetDownloadUrls';
55
+
56
+ /**
57
+ * True when a file is an optimistic placeholder that has not been persisted by
58
+ * the server yet — either its id is still the client-minted `temp-…` id, or it
59
+ * carries the `uploading` flag. Mirrors the `temp-` id guard precedent in
60
+ * `@oxyhq/core`'s `avatarUtils.updateAvatarVisibility`.
61
+ */
62
+ function isOptimisticFile(file) {
63
+ if (typeof file.id === 'string' && file.id.startsWith('temp-')) return true;
64
+ return file.metadata?.uploading === true;
65
+ }
66
+
67
+ /** Grid thumbnail variant for a file, or `undefined` when it needs no URL. */
68
+ function thumbVariantFor(file) {
69
+ if (file.contentType.startsWith('video/')) return 'poster';
70
+ if (file.contentType.startsWith('image/')) return 'thumb';
71
+ return undefined;
72
+ }
73
+
74
+ /**
75
+ * Locally-picked preview uri stashed on an optimistic entry's metadata by the
76
+ * upload flow, if present.
77
+ */
78
+ function localPreviewUri(file) {
79
+ const uri = file.metadata?.localPreviewUri;
80
+ return typeof uri === 'string' && uri.length > 0 ? uri : undefined;
81
+ }
82
+
83
+ /**
84
+ * Resolve the image source for a grid tile.
85
+ *
86
+ * - Optimistic entry → its locally-picked preview uri (never an asset URL).
87
+ * - Persisted entry → the private-safe URL from {@link useResolvedFileUrls},
88
+ * or `undefined` while it is still resolving / was denied (tile shows a
89
+ * placeholder instead of a guaranteed-404 CDN URL).
90
+ */
91
+ function fileThumbSource(file, resolved) {
92
+ if (isOptimisticFile(file)) {
93
+ return localPreviewUri(file);
94
+ }
95
+ return resolved.get(file.id);
96
+ }
97
+
98
+ /**
99
+ * Batch-resolve private-safe thumbnail URLs for the given files.
100
+ *
101
+ * Only image/video, non-optimistic files are resolved (documents render an
102
+ * icon, optimistic entries render their local preview). Returns a stable
103
+ * `Map<fileId, url>`; missing entries mean "not resolved yet or access denied".
104
+ */
105
+ function useResolvedFileUrls(oxyServices, files, /** Active viewer account id — media tokens are minted per user; must be in the query key. */
106
+ viewerId) {
107
+ const viewerKey = viewerId ?? '';
108
+ const requests = (0, _react.useMemo)(() => {
109
+ const list = [];
110
+ for (const file of files) {
111
+ if (isOptimisticFile(file)) continue;
112
+ const variant = thumbVariantFor(file);
113
+ if (!variant) continue;
114
+ list.push({
115
+ fileId: file.id,
116
+ variant
117
+ });
118
+ }
119
+ return list;
120
+ }, [files]);
121
+
122
+ // A content signature so the query key is stable across renders while the
123
+ // resolvable set is unchanged (the `files` array is a fresh reference every
124
+ // render). Sorted so ordering churn does not force a refetch.
125
+ const signature = (0, _react.useMemo)(() => requests.map(r => `${r.fileId}:${r.variant ?? ''}`).sort().join('|'), [requests]);
126
+ const query = (0, _reactQuery.useQuery)({
127
+ queryKey: [ASSET_DOWNLOAD_URLS_QUERY_KEY, viewerKey, signature],
128
+ enabled: requests.length > 0 && viewerKey.length > 0,
129
+ staleTime: ASSET_URL_STALE_MS,
130
+ gcTime: ASSET_URL_GC_MS,
131
+ // Keep previously-resolved URLs on screen while the SAME viewer's file set
132
+ // grows (pagination), but never carry another account's scoped media tokens
133
+ // across a switch — `keepPreviousData` alone would do that.
134
+ placeholderData: (previousData, previousQuery) => {
135
+ if (!previousData || !previousQuery) return undefined;
136
+ const prevViewer = previousQuery.queryKey[1];
137
+ if (prevViewer !== viewerKey) return undefined;
138
+ return previousData;
139
+ },
140
+ queryFn: async () => {
141
+ const merged = {};
142
+ for (let i = 0; i < requests.length; i += BATCH_CAP) {
143
+ const chunk = requests.slice(i, i + BATCH_CAP);
144
+ const urls = await oxyServices.getFileDownloadUrls(chunk, {
145
+ expiresIn: ASSET_URL_TTL_SECONDS
146
+ });
147
+ Object.assign(merged, urls);
148
+ }
149
+ return merged;
150
+ }
151
+ });
152
+ return (0, _react.useMemo)(() => {
153
+ const map = new Map();
154
+ const data = query.data;
155
+ if (data) {
156
+ for (const [id, url] of Object.entries(data)) {
157
+ if (typeof url === 'string' && url.length > 0) map.set(id, url);
158
+ }
159
+ }
160
+ return map;
161
+ }, [query.data]);
162
+ }
163
+ //# sourceMappingURL=useResolvedFileUrls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_react","require","_reactQuery","ASSET_URL_TTL_SECONDS","ASSET_URL_STALE_MS","ASSET_URL_GC_MS","BATCH_CAP","ASSET_DOWNLOAD_URLS_QUERY_KEY","exports","isOptimisticFile","file","id","startsWith","metadata","uploading","thumbVariantFor","contentType","undefined","localPreviewUri","uri","length","fileThumbSource","resolved","get","useResolvedFileUrls","oxyServices","files","viewerId","viewerKey","requests","useMemo","list","variant","push","fileId","signature","map","r","sort","join","query","useQuery","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":[]}
@@ -173,7 +173,7 @@ var _LogoText = require("./components/logo/LogoText.js");
173
173
  var _RequireOxyAuth = require("./components/RequireOxyAuth.js");
174
174
  var _FollowButton = _interopRequireDefault(require("./components/FollowButton.js"));
175
175
  var _OxyPayButton = _interopRequireDefault(require("./components/OxyPayButton.js"));
176
- var _FontLoader = require("./components/FontLoader.js");
176
+ var _FontLoader = require("./components/FontLoader");
177
177
  var _ProfileButton = _interopRequireDefault(require("./components/ProfileButton.js"));
178
178
  var _OxyContext = require("./context/OxyContext.js");
179
179
  var _useAuth = require("./hooks/useAuth.js");
@@ -17,6 +17,7 @@ var _OxyContext = require("../context/OxyContext.js");
17
17
  var _useI18n = require("../hooks/useI18n.js");
18
18
  var _useAccountMutations = require("../hooks/mutations/useAccountMutations.js");
19
19
  var _fileManagement = require("../utils/fileManagement.js");
20
+ var _useResolvedFileUrls = require("../hooks/useResolvedFileUrls.js");
20
21
  var _FileViewer = require("../components/fileManagement/FileViewer.js");
21
22
  var _FileDetailsModal = require("../components/fileManagement/FileDetailsModal.js");
22
23
  var _UploadPreview = require("../components/fileManagement/UploadPreview.js");
@@ -310,10 +311,16 @@ const FileManagementScreen = ({
310
311
  onClose?.();
311
312
  }, [selectMode, multiSelect, selectedIds, files, onConfirmSelection, onClose, defaultVisibility, oxyServices, linkContext]);
312
313
 
313
- // Helper to safely request a thumbnail variant only for image mime types.
314
- const getSafeDownloadUrlCallback = (0, _react.useCallback)((file, variant = 'thumb') => {
315
- return (0, _fileManagement.getSafeDownloadUrl)(file, variant, (fileId, variant) => oxyServices.getFileDownloadUrl(fileId, variant));
316
- }, [oxyServices]);
314
+ // Private-safe thumbnail URLs for the currently-shown files, resolved in
315
+ // ONE batch per page (not N per-tile) and cached by React Query. Uploads
316
+ // default to private, so the synchronous public-CDN URL would 404 for
317
+ // every private thumbnail.
318
+ const resolvedThumbUrls = (0, _useResolvedFileUrls.useResolvedFileUrls)(oxyServices, filteredFiles, user?.id);
319
+
320
+ // Image source for a grid tile: the resolved private-safe URL for a
321
+ // persisted file, or the locally-picked preview for an in-flight optimistic
322
+ // entry. Never builds an asset URL from a `temp-…`/uploading id.
323
+ const thumbSourceFor = (0, _react.useCallback)(file => (0, _useResolvedFileUrls.fileThumbSource)(file, resolvedThumbUrls), [resolvedThumbUrls]);
317
324
  const bloomTheme = (0, _theme.useTheme)();
318
325
  const {
319
326
  colors
@@ -442,7 +449,14 @@ const FileManagementScreen = ({
442
449
  try {
443
450
  await Promise.all(photosToLoad.map(async photo => {
444
451
  try {
445
- const downloadUrl = getSafeDownloadUrlCallback(photo, 'thumb');
452
+ const downloadUrl = thumbSourceFor(photo);
453
+ // URL not resolved yet — skip (do NOT record fallback
454
+ // dims) so this photo is re-measured once its private-safe
455
+ // URL resolves. Measuring the broken public URL is exactly
456
+ // the bug we are fixing.
457
+ if (!downloadUrl) {
458
+ return;
459
+ }
446
460
 
447
461
  // Unified approach using Image.getSize (works on all platforms)
448
462
  await new Promise(resolve => {
@@ -480,7 +494,19 @@ const FileManagementScreen = ({
480
494
  } finally {
481
495
  setLoadingDimensions(false);
482
496
  }
483
- }, [getSafeDownloadUrlCallback, photoDimensions]);
497
+ }, [thumbSourceFor, photoDimensions]);
498
+
499
+ // Re-measure photo dimensions when their private-safe URLs resolve. The
500
+ // justified grid's own trigger fires on the photo SET, not on URL
501
+ // availability, so newly-resolved private tiles would otherwise keep their
502
+ // skipped (unmeasured) state and render with fallback geometry.
503
+ (0, _react.useEffect)(() => {
504
+ if (viewMode !== 'photos') return;
505
+ const photos = filteredFiles.filter(file => file.contentType.startsWith('image/'));
506
+ if (photos.length > 0) {
507
+ loadPhotoDimensions(photos);
508
+ }
509
+ }, [resolvedThumbUrls, viewMode, filteredFiles, loadPhotoDimensions]);
484
510
 
485
511
  // Create justified rows from photos with responsive algorithm
486
512
  const createJustifiedRows = (0, _react.useCallback)((photos, containerWidth) => {
@@ -624,9 +650,10 @@ const FileManagementScreen = ({
624
650
  // Unified download function - works on all platforms
625
651
  const handleFileDownload = async (fileId, filename) => {
626
652
  try {
627
- // Try to use the download URL with a simple approach
628
- // On web, this creates a download link. On mobile, it opens the URL.
629
- const downloadUrl = oxyServices.getFileDownloadUrl(fileId);
653
+ // Resolve an authenticated, private-safe URL. The synchronous
654
+ // `getFileDownloadUrl` yields the public CDN origin, which 404s for
655
+ // private assets (the default visibility).
656
+ const downloadUrl = await oxyServices.getFileDownloadUrlAsync(fileId);
630
657
 
631
658
  // For web platforms, use link download
632
659
  if (typeof window !== 'undefined' && window.document) {
@@ -678,8 +705,10 @@ const FileManagementScreen = ({
678
705
  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/')) {
679
706
  try {
680
707
  if (file.contentType.startsWith('image/') || file.contentType.includes('pdf') || file.contentType.startsWith('video/') || file.contentType.startsWith('audio/')) {
681
- // For images, PDFs, videos, and audio, we'll use the URL directly
682
- const downloadUrl = oxyServices.getFileDownloadUrl(file.id);
708
+ // For images, PDFs, videos, and audio, we render the URL
709
+ // directly. Resolve the authenticated, private-safe URL —
710
+ // the synchronous public-CDN URL 404s for private assets.
711
+ const downloadUrl = await oxyServices.getFileDownloadUrlAsync(file.id);
683
712
  setFileContent(downloadUrl);
684
713
  } else {
685
714
  // For text files, get the content using authenticated request
@@ -715,7 +744,7 @@ const FileManagementScreen = ({
715
744
  fileDetailsControl.open();
716
745
  };
717
746
  const renderSimplePhotoItem = (0, _react.useCallback)((photo, index) => {
718
- const downloadUrl = getSafeDownloadUrlCallback(photo, 'thumb');
747
+ const downloadUrl = thumbSourceFor(photo);
719
748
 
720
749
  // Calculate photo item width based on actual container size from bottom sheet
721
750
  let itemsPerRow = 3; // Default for mobile
@@ -763,9 +792,9 @@ const FileManagementScreen = ({
763
792
  })]
764
793
  })
765
794
  }, photo.id);
766
- }, [oxyServices, safeContainerWidth, selectMode, selectedIds, colors.primary, colors.text]);
795
+ }, [thumbSourceFor, safeContainerWidth, selectMode, selectedIds, colors.primary, colors.text]);
767
796
  const renderJustifiedPhotoItem = (0, _react.useCallback)((photo, width, height, isLast) => {
768
- const downloadUrl = getSafeDownloadUrlCallback(photo, 'thumb');
797
+ const downloadUrl = thumbSourceFor(photo);
769
798
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
770
799
  style: [_styles.fileManagementStyles.justifiedPhotoItem, {
771
800
  width,
@@ -804,7 +833,7 @@ const FileManagementScreen = ({
804
833
  })]
805
834
  })
806
835
  }, photo.id);
807
- }, [oxyServices, selectMode, selectedIds, multiSelect, colors.primary, colors.text]);
836
+ }, [thumbSourceFor, selectMode, selectedIds, multiSelect, colors.primary, colors.text]);
808
837
 
809
838
  // Run initial load once per targetUserId change to avoid accidental loops
810
839
  const lastLoadedFor = (0, _react.useRef)(undefined);
@@ -840,7 +869,7 @@ const FileManagementScreen = ({
840
869
  style: _styles.fileManagementStyles.filePreview,
841
870
  children: [isImage && /*#__PURE__*/(0, _jsxRuntime.jsx)(_expoImage.Image, {
842
871
  source: {
843
- uri: getSafeDownloadUrlCallback(file, 'thumb')
872
+ uri: thumbSourceFor(file)
844
873
  },
845
874
  style: _styles.fileManagementStyles.previewImage,
846
875
  contentFit: "cover",
@@ -866,7 +895,7 @@ const FileManagementScreen = ({
866
895
  style: _styles.fileManagementStyles.videoPreviewWrapper,
867
896
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_expoImage.Image, {
868
897
  source: {
869
- uri: getSafeDownloadUrlCallback(file, 'thumb')
898
+ uri: thumbSourceFor(file)
870
899
  },
871
900
  style: _styles.fileManagementStyles.videoPosterImage,
872
901
  contentFit: "cover",
@@ -995,7 +1024,7 @@ const FileManagementScreen = ({
995
1024
  },
996
1025
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_expoImage.Image, {
997
1026
  source: {
998
- uri: getSafeDownloadUrlCallback(file, 'thumb')
1027
+ uri: thumbSourceFor(file)
999
1028
  },
1000
1029
  style: {
1001
1030
  width: 36,
@@ -1022,7 +1051,7 @@ const FileManagementScreen = ({
1022
1051
  },
1023
1052
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_expoImage.Image, {
1024
1053
  source: {
1025
- uri: getSafeDownloadUrlCallback(file, 'thumb')
1054
+ uri: thumbSourceFor(file)
1026
1055
  },
1027
1056
  style: {
1028
1057
  width: 36,
@@ -1130,7 +1159,7 @@ const FileManagementScreen = ({
1130
1159
  }) : undefined
1131
1160
  };
1132
1161
  });
1133
- }, [filteredFiles, theme, deleting, handleFileDownload, confirmFileDelete, handleFileOpen, getSafeDownloadUrlCallback, selectMode, selectedIds]);
1162
+ }, [filteredFiles, theme, deleting, handleFileDownload, confirmFileDelete, handleFileOpen, thumbSourceFor, selectMode, selectedIds]);
1134
1163
 
1135
1164
  // Scroll to selected file after selection
1136
1165
  (0, _react.useEffect)(() => {
@@ -1214,7 +1243,7 @@ const FileManagementScreen = ({
1214
1243
  }
1215
1244
  }, [lastSelectedFileId]);
1216
1245
  const renderPhotoItem = (photo, index) => {
1217
- const downloadUrl = getSafeDownloadUrlCallback(photo, 'thumb');
1246
+ const downloadUrl = thumbSourceFor(photo);
1218
1247
 
1219
1248
  // Calculate photo item width based on actual container size from bottom sheet
1220
1249
  let itemsPerRow = 3; // Default for mobile
@@ -1617,7 +1646,7 @@ const FileManagementScreen = ({
1617
1646
  hasMore: paging.hasMore,
1618
1647
  loadingMore: paging.loadingMore,
1619
1648
  reduceMotion: reduceMotion,
1620
- getThumbUrl: getSafeDownloadUrlCallback,
1649
+ getThumbUrl: thumbSourceFor,
1621
1650
  primaryColor: colors.primary,
1622
1651
  isOwner: isOwner,
1623
1652
  onTogglePhoto: toggleSelect,