@oxyhq/services 22.10.0 → 22.11.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 (274) hide show
  1. package/lib/commonjs/ui/components/AvatarCameraBadge.js +42 -0
  2. package/lib/commonjs/ui/components/AvatarCameraBadge.js.map +1 -0
  3. package/lib/commonjs/ui/components/OxyAccountDialogScreen.js +41 -19
  4. package/lib/commonjs/ui/components/OxyAccountDialogScreen.js.map +1 -1
  5. package/lib/commonjs/ui/components/OxyAuthChooser.js +640 -168
  6. package/lib/commonjs/ui/components/OxyAuthChooser.js.map +1 -1
  7. package/lib/commonjs/ui/components/ProfileButton.js +14 -0
  8. package/lib/commonjs/ui/components/ProfileButton.js.map +1 -1
  9. package/lib/commonjs/ui/components/ProfileSummaryCard.js +3 -23
  10. package/lib/commonjs/ui/components/ProfileSummaryCard.js.map +1 -1
  11. package/lib/commonjs/ui/components/SurfaceScreen.js +41 -5
  12. package/lib/commonjs/ui/components/SurfaceScreen.js.map +1 -1
  13. package/lib/commonjs/ui/components/oxyAuthChooserStyles.js +78 -26
  14. package/lib/commonjs/ui/components/oxyAuthChooserStyles.js.map +1 -1
  15. package/lib/commonjs/ui/components/photogrid/JustifiedPhotoGrid.js +83 -23
  16. package/lib/commonjs/ui/components/photogrid/JustifiedPhotoGrid.js.map +1 -1
  17. package/lib/commonjs/ui/context/OxyContext.js +73 -37
  18. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  19. package/lib/commonjs/ui/hooks/queries/queryKeys.js +18 -1
  20. package/lib/commonjs/ui/hooks/queries/queryKeys.js.map +1 -1
  21. package/lib/commonjs/ui/hooks/queries/useFileQueries.js +129 -0
  22. package/lib/commonjs/ui/hooks/queries/useFileQueries.js.map +1 -0
  23. package/lib/commonjs/ui/hooks/useAvatarPicker.js +36 -48
  24. package/lib/commonjs/ui/hooks/useAvatarPicker.js.map +1 -1
  25. package/lib/commonjs/ui/hooks/useReduceMotion.js +57 -0
  26. package/lib/commonjs/ui/hooks/useReduceMotion.js.map +1 -0
  27. package/lib/commonjs/ui/hooks/useSurfaceHeader.js +1 -1
  28. package/lib/commonjs/ui/hooks/useSurfaceHeader.js.map +1 -1
  29. package/lib/commonjs/ui/navigation/accountDialogManager.js +22 -0
  30. package/lib/commonjs/ui/navigation/accountDialogManager.js.map +1 -1
  31. package/lib/commonjs/ui/navigation/bottomSheetManager.js +5 -6
  32. package/lib/commonjs/ui/navigation/bottomSheetManager.js.map +1 -1
  33. package/lib/commonjs/ui/navigation/routes.js +1 -0
  34. package/lib/commonjs/ui/navigation/routes.js.map +1 -1
  35. package/lib/commonjs/ui/navigation/surfaceNavStack.js +62 -15
  36. package/lib/commonjs/ui/navigation/surfaceNavStack.js.map +1 -1
  37. package/lib/commonjs/ui/navigation/surfaceRegistry.js +38 -17
  38. package/lib/commonjs/ui/navigation/surfaceRegistry.js.map +1 -1
  39. package/lib/commonjs/ui/navigation/surfaces.js +98 -21
  40. package/lib/commonjs/ui/navigation/surfaces.js.map +1 -1
  41. package/lib/commonjs/ui/screens/AvatarCropScreen.js +281 -279
  42. package/lib/commonjs/ui/screens/AvatarCropScreen.js.map +1 -1
  43. package/lib/commonjs/ui/screens/ChangeAvatarScreen.js +301 -0
  44. package/lib/commonjs/ui/screens/ChangeAvatarScreen.js.map +1 -0
  45. package/lib/commonjs/ui/screens/FileManagementScreen.js +194 -431
  46. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
  47. package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js +16 -48
  48. package/lib/commonjs/ui/screens/WelcomeNewUserScreen.js.map +1 -1
  49. package/lib/commonjs/ui/screens/fileManagement/FileLibraryError.js +63 -0
  50. package/lib/commonjs/ui/screens/fileManagement/FileLibraryError.js.map +1 -0
  51. package/lib/commonjs/ui/screens/fileManagement/PhotoPickerSection.js +71 -39
  52. package/lib/commonjs/ui/screens/fileManagement/PhotoPickerSection.js.map +1 -1
  53. package/lib/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.js +44 -81
  54. package/lib/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.js.map +1 -1
  55. package/lib/commonjs/ui/stores/resetSessionScopedStores.js +8 -3
  56. package/lib/commonjs/ui/stores/resetSessionScopedStores.js.map +1 -1
  57. package/lib/commonjs/ui/utils/avatarUtils.js +11 -2
  58. package/lib/commonjs/ui/utils/avatarUtils.js.map +1 -1
  59. package/lib/commonjs/ui/utils/fileManagement.js +0 -79
  60. package/lib/commonjs/ui/utils/fileManagement.js.map +1 -1
  61. package/lib/module/ui/components/AvatarCameraBadge.js +40 -0
  62. package/lib/module/ui/components/AvatarCameraBadge.js.map +1 -0
  63. package/lib/module/ui/components/OxyAccountDialogScreen.js +41 -19
  64. package/lib/module/ui/components/OxyAccountDialogScreen.js.map +1 -1
  65. package/lib/module/ui/components/OxyAuthChooser.js +642 -171
  66. package/lib/module/ui/components/OxyAuthChooser.js.map +1 -1
  67. package/lib/module/ui/components/ProfileButton.js +15 -1
  68. package/lib/module/ui/components/ProfileButton.js.map +1 -1
  69. package/lib/module/ui/components/ProfileSummaryCard.js +2 -23
  70. package/lib/module/ui/components/ProfileSummaryCard.js.map +1 -1
  71. package/lib/module/ui/components/SurfaceScreen.js +43 -7
  72. package/lib/module/ui/components/SurfaceScreen.js.map +1 -1
  73. package/lib/module/ui/components/oxyAuthChooserStyles.js +78 -26
  74. package/lib/module/ui/components/oxyAuthChooserStyles.js.map +1 -1
  75. package/lib/module/ui/components/photogrid/JustifiedPhotoGrid.js +83 -25
  76. package/lib/module/ui/components/photogrid/JustifiedPhotoGrid.js.map +1 -1
  77. package/lib/module/ui/context/OxyContext.js +74 -38
  78. package/lib/module/ui/context/OxyContext.js.map +1 -1
  79. package/lib/module/ui/hooks/queries/queryKeys.js +16 -0
  80. package/lib/module/ui/hooks/queries/queryKeys.js.map +1 -1
  81. package/lib/module/ui/hooks/queries/useFileQueries.js +120 -0
  82. package/lib/module/ui/hooks/queries/useFileQueries.js.map +1 -0
  83. package/lib/module/ui/hooks/useAvatarPicker.js +37 -49
  84. package/lib/module/ui/hooks/useAvatarPicker.js.map +1 -1
  85. package/lib/module/ui/hooks/useReduceMotion.js +53 -0
  86. package/lib/module/ui/hooks/useReduceMotion.js.map +1 -0
  87. package/lib/module/ui/hooks/useSurfaceHeader.js +1 -1
  88. package/lib/module/ui/hooks/useSurfaceHeader.js.map +1 -1
  89. package/lib/module/ui/navigation/accountDialogManager.js +20 -0
  90. package/lib/module/ui/navigation/accountDialogManager.js.map +1 -1
  91. package/lib/module/ui/navigation/bottomSheetManager.js +6 -7
  92. package/lib/module/ui/navigation/bottomSheetManager.js.map +1 -1
  93. package/lib/module/ui/navigation/routes.js +1 -0
  94. package/lib/module/ui/navigation/routes.js.map +1 -1
  95. package/lib/module/ui/navigation/surfaceNavStack.js +62 -15
  96. package/lib/module/ui/navigation/surfaceNavStack.js.map +1 -1
  97. package/lib/module/ui/navigation/surfaceRegistry.js +38 -17
  98. package/lib/module/ui/navigation/surfaceRegistry.js.map +1 -1
  99. package/lib/module/ui/navigation/surfaces.js +97 -22
  100. package/lib/module/ui/navigation/surfaces.js.map +1 -1
  101. package/lib/module/ui/screens/AvatarCropScreen.js +283 -281
  102. package/lib/module/ui/screens/AvatarCropScreen.js.map +1 -1
  103. package/lib/module/ui/screens/ChangeAvatarScreen.js +298 -0
  104. package/lib/module/ui/screens/ChangeAvatarScreen.js.map +1 -0
  105. package/lib/module/ui/screens/FileManagementScreen.js +196 -433
  106. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
  107. package/lib/module/ui/screens/WelcomeNewUserScreen.js +17 -49
  108. package/lib/module/ui/screens/WelcomeNewUserScreen.js.map +1 -1
  109. package/lib/module/ui/screens/fileManagement/FileLibraryError.js +59 -0
  110. package/lib/module/ui/screens/fileManagement/FileLibraryError.js.map +1 -0
  111. package/lib/module/ui/screens/fileManagement/PhotoPickerSection.js +71 -40
  112. package/lib/module/ui/screens/fileManagement/PhotoPickerSection.js.map +1 -1
  113. package/lib/module/ui/screens/fileManagement/hooks/useFileUploadState.js +45 -81
  114. package/lib/module/ui/screens/fileManagement/hooks/useFileUploadState.js.map +1 -1
  115. package/lib/module/ui/stores/resetSessionScopedStores.js +8 -3
  116. package/lib/module/ui/stores/resetSessionScopedStores.js.map +1 -1
  117. package/lib/module/ui/utils/avatarUtils.js +11 -2
  118. package/lib/module/ui/utils/avatarUtils.js.map +1 -1
  119. package/lib/module/ui/utils/fileManagement.js +0 -78
  120. package/lib/module/ui/utils/fileManagement.js.map +1 -1
  121. package/lib/typescript/commonjs/ui/components/AvatarCameraBadge.d.ts +4 -0
  122. package/lib/typescript/commonjs/ui/components/AvatarCameraBadge.d.ts.map +1 -0
  123. package/lib/typescript/commonjs/ui/components/OxyAccountDialogScreen.d.ts +2 -1
  124. package/lib/typescript/commonjs/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
  125. package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts.map +1 -1
  126. package/lib/typescript/commonjs/ui/components/ProfileButton.d.ts.map +1 -1
  127. package/lib/typescript/commonjs/ui/components/ProfileSummaryCard.d.ts.map +1 -1
  128. package/lib/typescript/commonjs/ui/components/SurfaceScreen.d.ts +1 -4
  129. package/lib/typescript/commonjs/ui/components/SurfaceScreen.d.ts.map +1 -1
  130. package/lib/typescript/commonjs/ui/components/oxyAuthChooserStyles.d.ts +71 -19
  131. package/lib/typescript/commonjs/ui/components/oxyAuthChooserStyles.d.ts.map +1 -1
  132. package/lib/typescript/commonjs/ui/components/photogrid/JustifiedPhotoGrid.d.ts +10 -8
  133. package/lib/typescript/commonjs/ui/components/photogrid/JustifiedPhotoGrid.d.ts.map +1 -1
  134. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
  135. package/lib/typescript/commonjs/ui/hooks/queries/queryKeys.d.ts +9 -0
  136. package/lib/typescript/commonjs/ui/hooks/queries/queryKeys.d.ts.map +1 -1
  137. package/lib/typescript/commonjs/ui/hooks/queries/useFileQueries.d.ts +50 -0
  138. package/lib/typescript/commonjs/ui/hooks/queries/useFileQueries.d.ts.map +1 -0
  139. package/lib/typescript/commonjs/ui/hooks/useAvatarPicker.d.ts +15 -10
  140. package/lib/typescript/commonjs/ui/hooks/useAvatarPicker.d.ts.map +1 -1
  141. package/lib/typescript/commonjs/ui/hooks/useReduceMotion.d.ts +14 -0
  142. package/lib/typescript/commonjs/ui/hooks/useReduceMotion.d.ts.map +1 -0
  143. package/lib/typescript/commonjs/ui/hooks/useSurfaceHeader.d.ts +1 -1
  144. package/lib/typescript/commonjs/ui/hooks/useSurfaceHeader.d.ts.map +1 -1
  145. package/lib/typescript/commonjs/ui/navigation/accountDialogManager.d.ts +13 -0
  146. package/lib/typescript/commonjs/ui/navigation/accountDialogManager.d.ts.map +1 -1
  147. package/lib/typescript/commonjs/ui/navigation/bottomSheetManager.d.ts +4 -5
  148. package/lib/typescript/commonjs/ui/navigation/bottomSheetManager.d.ts.map +1 -1
  149. package/lib/typescript/commonjs/ui/navigation/routes.d.ts +1 -1
  150. package/lib/typescript/commonjs/ui/navigation/routes.d.ts.map +1 -1
  151. package/lib/typescript/commonjs/ui/navigation/surfaceNavStack.d.ts +21 -0
  152. package/lib/typescript/commonjs/ui/navigation/surfaceNavStack.d.ts.map +1 -1
  153. package/lib/typescript/commonjs/ui/navigation/surfaceRegistry.d.ts +73 -13
  154. package/lib/typescript/commonjs/ui/navigation/surfaceRegistry.d.ts.map +1 -1
  155. package/lib/typescript/commonjs/ui/navigation/surfaces.d.ts +42 -11
  156. package/lib/typescript/commonjs/ui/navigation/surfaces.d.ts.map +1 -1
  157. package/lib/typescript/commonjs/ui/screens/AvatarCropScreen.d.ts +18 -5
  158. package/lib/typescript/commonjs/ui/screens/AvatarCropScreen.d.ts.map +1 -1
  159. package/lib/typescript/commonjs/ui/screens/ChangeAvatarScreen.d.ts +34 -0
  160. package/lib/typescript/commonjs/ui/screens/ChangeAvatarScreen.d.ts.map +1 -0
  161. package/lib/typescript/commonjs/ui/screens/FileManagementScreen.d.ts.map +1 -1
  162. package/lib/typescript/commonjs/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -1
  163. package/lib/typescript/commonjs/ui/screens/fileManagement/FileLibraryError.d.ts +23 -0
  164. package/lib/typescript/commonjs/ui/screens/fileManagement/FileLibraryError.d.ts.map +1 -0
  165. package/lib/typescript/commonjs/ui/screens/fileManagement/PhotoPickerSection.d.ts +4 -0
  166. package/lib/typescript/commonjs/ui/screens/fileManagement/PhotoPickerSection.d.ts.map +1 -1
  167. package/lib/typescript/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.d.ts +10 -2
  168. package/lib/typescript/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
  169. package/lib/typescript/commonjs/ui/stores/resetSessionScopedStores.d.ts +8 -1
  170. package/lib/typescript/commonjs/ui/stores/resetSessionScopedStores.d.ts.map +1 -1
  171. package/lib/typescript/commonjs/ui/types/navigation.d.ts +2 -0
  172. package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
  173. package/lib/typescript/commonjs/ui/utils/avatarUtils.d.ts.map +1 -1
  174. package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts +0 -48
  175. package/lib/typescript/commonjs/ui/utils/fileManagement.d.ts.map +1 -1
  176. package/lib/typescript/module/ui/components/AvatarCameraBadge.d.ts +4 -0
  177. package/lib/typescript/module/ui/components/AvatarCameraBadge.d.ts.map +1 -0
  178. package/lib/typescript/module/ui/components/OxyAccountDialogScreen.d.ts +2 -1
  179. package/lib/typescript/module/ui/components/OxyAccountDialogScreen.d.ts.map +1 -1
  180. package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts.map +1 -1
  181. package/lib/typescript/module/ui/components/ProfileButton.d.ts.map +1 -1
  182. package/lib/typescript/module/ui/components/ProfileSummaryCard.d.ts.map +1 -1
  183. package/lib/typescript/module/ui/components/SurfaceScreen.d.ts +1 -4
  184. package/lib/typescript/module/ui/components/SurfaceScreen.d.ts.map +1 -1
  185. package/lib/typescript/module/ui/components/oxyAuthChooserStyles.d.ts +71 -19
  186. package/lib/typescript/module/ui/components/oxyAuthChooserStyles.d.ts.map +1 -1
  187. package/lib/typescript/module/ui/components/photogrid/JustifiedPhotoGrid.d.ts +10 -8
  188. package/lib/typescript/module/ui/components/photogrid/JustifiedPhotoGrid.d.ts.map +1 -1
  189. package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
  190. package/lib/typescript/module/ui/hooks/queries/queryKeys.d.ts +9 -0
  191. package/lib/typescript/module/ui/hooks/queries/queryKeys.d.ts.map +1 -1
  192. package/lib/typescript/module/ui/hooks/queries/useFileQueries.d.ts +50 -0
  193. package/lib/typescript/module/ui/hooks/queries/useFileQueries.d.ts.map +1 -0
  194. package/lib/typescript/module/ui/hooks/useAvatarPicker.d.ts +15 -10
  195. package/lib/typescript/module/ui/hooks/useAvatarPicker.d.ts.map +1 -1
  196. package/lib/typescript/module/ui/hooks/useReduceMotion.d.ts +14 -0
  197. package/lib/typescript/module/ui/hooks/useReduceMotion.d.ts.map +1 -0
  198. package/lib/typescript/module/ui/hooks/useSurfaceHeader.d.ts +1 -1
  199. package/lib/typescript/module/ui/hooks/useSurfaceHeader.d.ts.map +1 -1
  200. package/lib/typescript/module/ui/navigation/accountDialogManager.d.ts +13 -0
  201. package/lib/typescript/module/ui/navigation/accountDialogManager.d.ts.map +1 -1
  202. package/lib/typescript/module/ui/navigation/bottomSheetManager.d.ts +4 -5
  203. package/lib/typescript/module/ui/navigation/bottomSheetManager.d.ts.map +1 -1
  204. package/lib/typescript/module/ui/navigation/routes.d.ts +1 -1
  205. package/lib/typescript/module/ui/navigation/routes.d.ts.map +1 -1
  206. package/lib/typescript/module/ui/navigation/surfaceNavStack.d.ts +21 -0
  207. package/lib/typescript/module/ui/navigation/surfaceNavStack.d.ts.map +1 -1
  208. package/lib/typescript/module/ui/navigation/surfaceRegistry.d.ts +73 -13
  209. package/lib/typescript/module/ui/navigation/surfaceRegistry.d.ts.map +1 -1
  210. package/lib/typescript/module/ui/navigation/surfaces.d.ts +42 -11
  211. package/lib/typescript/module/ui/navigation/surfaces.d.ts.map +1 -1
  212. package/lib/typescript/module/ui/screens/AvatarCropScreen.d.ts +18 -5
  213. package/lib/typescript/module/ui/screens/AvatarCropScreen.d.ts.map +1 -1
  214. package/lib/typescript/module/ui/screens/ChangeAvatarScreen.d.ts +34 -0
  215. package/lib/typescript/module/ui/screens/ChangeAvatarScreen.d.ts.map +1 -0
  216. package/lib/typescript/module/ui/screens/FileManagementScreen.d.ts.map +1 -1
  217. package/lib/typescript/module/ui/screens/WelcomeNewUserScreen.d.ts.map +1 -1
  218. package/lib/typescript/module/ui/screens/fileManagement/FileLibraryError.d.ts +23 -0
  219. package/lib/typescript/module/ui/screens/fileManagement/FileLibraryError.d.ts.map +1 -0
  220. package/lib/typescript/module/ui/screens/fileManagement/PhotoPickerSection.d.ts +4 -0
  221. package/lib/typescript/module/ui/screens/fileManagement/PhotoPickerSection.d.ts.map +1 -1
  222. package/lib/typescript/module/ui/screens/fileManagement/hooks/useFileUploadState.d.ts +10 -2
  223. package/lib/typescript/module/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
  224. package/lib/typescript/module/ui/stores/resetSessionScopedStores.d.ts +8 -1
  225. package/lib/typescript/module/ui/stores/resetSessionScopedStores.d.ts.map +1 -1
  226. package/lib/typescript/module/ui/types/navigation.d.ts +2 -0
  227. package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
  228. package/lib/typescript/module/ui/utils/avatarUtils.d.ts.map +1 -1
  229. package/lib/typescript/module/ui/utils/fileManagement.d.ts +0 -48
  230. package/lib/typescript/module/ui/utils/fileManagement.d.ts.map +1 -1
  231. package/package.json +11 -7
  232. package/src/ui/components/AvatarCameraBadge.tsx +35 -0
  233. package/src/ui/components/OxyAccountDialogScreen.tsx +38 -15
  234. package/src/ui/components/OxyAuthChooser.tsx +722 -185
  235. package/src/ui/components/ProfileButton.tsx +16 -1
  236. package/src/ui/components/ProfileSummaryCard.tsx +2 -25
  237. package/src/ui/components/SurfaceScreen.tsx +48 -14
  238. package/src/ui/components/oxyAuthChooserStyles.ts +75 -23
  239. package/src/ui/components/photogrid/JustifiedPhotoGrid.tsx +158 -84
  240. package/src/ui/components/photogrid/__tests__/chunkPhotos.test.ts +51 -0
  241. package/src/ui/context/OxyContext.tsx +74 -34
  242. package/src/ui/hooks/queries/queryKeys.ts +15 -0
  243. package/src/ui/hooks/queries/useFileQueries.ts +162 -0
  244. package/src/ui/hooks/useAvatarPicker.ts +38 -53
  245. package/src/ui/hooks/useReduceMotion.ts +58 -0
  246. package/src/ui/hooks/useSurfaceHeader.ts +2 -1
  247. package/src/ui/navigation/__tests__/getSurfaceConfig.test.ts +55 -7
  248. package/src/ui/navigation/__tests__/surfaceNavStack.test.ts +81 -0
  249. package/src/ui/navigation/accountDialogManager.ts +28 -0
  250. package/src/ui/navigation/bottomSheetManager.ts +6 -7
  251. package/src/ui/navigation/routes.ts +3 -1
  252. package/src/ui/navigation/surfaceNavStack.ts +72 -9
  253. package/src/ui/navigation/surfaceRegistry.ts +91 -17
  254. package/src/ui/navigation/surfaces.ts +108 -29
  255. package/src/ui/screens/AvatarCropScreen.tsx +336 -298
  256. package/src/ui/screens/ChangeAvatarScreen.tsx +359 -0
  257. package/src/ui/screens/FileManagementScreen.tsx +189 -432
  258. package/src/ui/screens/WelcomeNewUserScreen.tsx +18 -48
  259. package/src/ui/screens/fileManagement/FileLibraryError.tsx +56 -0
  260. package/src/ui/screens/fileManagement/PhotoPickerSection.tsx +73 -44
  261. package/src/ui/screens/fileManagement/hooks/useFileUploadState.ts +55 -71
  262. package/src/ui/stores/resetSessionScopedStores.ts +8 -3
  263. package/src/ui/types/navigation.ts +2 -0
  264. package/src/ui/utils/avatarUtils.ts +11 -2
  265. package/src/ui/utils/fileManagement.ts +1 -101
  266. package/lib/commonjs/ui/stores/fileStore.js +0 -153
  267. package/lib/commonjs/ui/stores/fileStore.js.map +0 -1
  268. package/lib/module/ui/stores/fileStore.js +0 -145
  269. package/lib/module/ui/stores/fileStore.js.map +0 -1
  270. package/lib/typescript/commonjs/ui/stores/fileStore.d.ts +0 -31
  271. package/lib/typescript/commonjs/ui/stores/fileStore.d.ts.map +0 -1
  272. package/lib/typescript/module/ui/stores/fileStore.d.ts +0 -31
  273. package/lib/typescript/module/ui/stores/fileStore.d.ts.map +0 -1
  274. package/src/ui/stores/fileStore.ts +0 -118
@@ -6,18 +6,21 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.default = void 0;
7
7
  var _react = _interopRequireWildcard(require("react"));
8
8
  var _reactNative = require("react-native");
9
+ var _reactQuery = require("@tanstack/react-query");
9
10
  var _expoImage = require("expo-image");
10
11
  var _bloom = require("@oxyhq/bloom");
11
12
  var _surfaces = require("@oxyhq/bloom/surfaces");
12
13
  var Skeleton = _interopRequireWildcard(require("@oxyhq/bloom/skeleton"));
13
14
  var _vectorIcons = require("@expo/vector-icons");
14
- var _fileStore = require("../stores/fileStore.js");
15
+ var _queryKeys = require("../hooks/queries/queryKeys.js");
16
+ var _useFileQueries = require("../hooks/queries/useFileQueries.js");
15
17
  var _useSurfaceHeader = require("../hooks/useSurfaceHeader.js");
16
18
  var _SurfaceHeaderAction = require("../components/SurfaceHeaderAction.js");
17
19
  var _JustifiedPhotoGrid = _interopRequireDefault(require("../components/photogrid/JustifiedPhotoGrid.js"));
18
20
  var _theme = require("@oxyhq/bloom/theme");
19
21
  var _OxyContext = require("../context/OxyContext.js");
20
22
  var _useI18n = require("../hooks/useI18n.js");
23
+ var _useReduceMotion = require("../hooks/useReduceMotion.js");
21
24
  var _useAccountMutations = require("../hooks/mutations/useAccountMutations.js");
22
25
  var _fileManagement = require("../utils/fileManagement.js");
23
26
  var _useResolvedFileUrls = require("../hooks/useResolvedFileUrls.js");
@@ -29,6 +32,7 @@ var _shared = require("./fileManagement/shared.js");
29
32
  var _useFileUploadState = require("./fileManagement/hooks/useFileUploadState.js");
30
33
  var _PhotoPickerSection = _interopRequireDefault(require("./fileManagement/PhotoPickerSection.js"));
31
34
  var _FileListSection = _interopRequireDefault(require("./fileManagement/FileListSection.js"));
35
+ var _FileLibraryError = _interopRequireDefault(require("./fileManagement/FileLibraryError.js"));
32
36
  var _UploadBar = _interopRequireDefault(require("./fileManagement/UploadBar.js"));
33
37
  var _AnimatedButton = require("../components/fileManagement/AnimatedButton.js");
34
38
  var _jsxRuntime = require("react/jsx-runtime");
@@ -61,11 +65,6 @@ const screenStyles = _reactNative.StyleSheet.create({
61
65
  justifyContent: 'center',
62
66
  marginHorizontal: 1
63
67
  },
64
- photoImage: {
65
- width: '100%',
66
- height: '100%',
67
- borderRadius: 8
68
- },
69
68
  justifiedPhotoImage: {
70
69
  width: '100%',
71
70
  height: '100%',
@@ -74,7 +73,6 @@ const screenStyles = _reactNative.StyleSheet.create({
74
73
  });
75
74
  const FileManagementScreen = ({
76
75
  onClose,
77
- theme,
78
76
  goBack,
79
77
  navigate,
80
78
  dismiss,
@@ -103,50 +101,49 @@ const FileManagementScreen = ({
103
101
  const {
104
102
  t
105
103
  } = (0, _useI18n.useI18n)();
104
+ const queryClient = (0, _reactQuery.useQueryClient)();
106
105
  const uploadFileMutation = (0, _useAccountMutations.useUploadFile)();
107
- const files = (0, _fileStore.useFiles)();
106
+
107
+ // Files are owned by the ACTIVE account. `targetUserId` scopes the query key,
108
+ // so switching accounts (or an explicit `userId` prop) shows that account's
109
+ // library with no manual reset.
110
+ const targetUserId = userId || user?.id;
111
+
112
+ // The file list is React Query's, NOT a store: infinite-paginated, fetched on
113
+ // mount + on owner change, edited optimistically via cache helpers. The
114
+ // rendered list is the flattened pages.
115
+ const filesQuery = (0, _useFileQueries.useUserFilesInfinite)(targetUserId);
116
+ const files = (0, _react.useMemo)(() => filesQuery.data?.pages.flatMap(page => page.files) ?? [], [filesQuery.data]);
117
+ // No owner resolved yet reads as "loading" (matches the old skeleton-until-
118
+ // first-load behaviour); `isLoading` is the first-page fetch only.
119
+ const isLoadingFiles = !targetUserId || filesQuery.isLoading;
120
+ const isRefreshingFiles = filesQuery.isRefetching;
121
+ const isFetchingMore = filesQuery.isFetchingNextPage;
122
+ const hasMoreFiles = filesQuery.hasNextPage ?? false;
123
+ // Terminal load failure with nothing cached — render a DISTINCT error state
124
+ // (not the empty state) so a failed load never looks like an empty library.
125
+ const hasLoadError = filesQuery.isError && files.length === 0;
126
+ const invalidateFiles = (0, _react.useCallback)(() => {
127
+ queryClient.invalidateQueries({
128
+ queryKey: _queryKeys.queryKeys.files.list(targetUserId)
129
+ });
130
+ }, [queryClient, targetUserId]);
108
131
  const {
109
132
  width: windowWidth
110
133
  } = (0, _reactNative.useWindowDimensions)();
111
134
  // Prefer an explicit sheet width from the router; fall back to the window
112
135
  // so photo grids never size against a hardcoded 400px default.
113
136
  const safeContainerWidth = typeof containerWidth === 'number' && containerWidth > 0 ? containerWidth : windowWidth;
114
- const uploading = (0, _fileStore.useUploading)();
115
- const uploadProgress = (0, _fileStore.useUploadAggregateProgress)();
116
- const deleting = (0, _fileStore.useDeleting)();
117
- const [loading, setLoading] = (0, _react.useState)(true);
118
- const [refreshing, setRefreshing] = (0, _react.useState)(false);
119
- const [paging, setPaging] = (0, _react.useState)({
120
- offset: 0,
121
- limit: 40,
122
- total: 0,
123
- hasMore: true,
124
- loadingMore: false
125
- });
137
+ // In-flight delete target (local UI state — was in the file store).
138
+ const [deletingId, setDeletingId] = (0, _react.useState)(null);
126
139
  // In selectMode we never open the detailed viewer
127
140
  const [openedFile, setOpenedFile] = (0, _react.useState)(null);
128
141
  const [fileContent, setFileContent] = (0, _react.useState)(null);
129
142
  const [loadingFileContent, setLoadingFileContent] = (0, _react.useState)(false);
130
143
  const [showFileDetailsInViewer, setShowFileDetailsInViewer] = (0, _react.useState)(false);
131
- const [reduceMotion, setReduceMotion] = (0, _react.useState)(false);
132
-
133
- // Detect reduce-motion preference once on mount + subscribe to changes.
134
- // Used by `PhotoPickerView` to skip cell stagger animations.
135
- (0, _react.useEffect)(() => {
136
- let cancelled = false;
137
- _reactNative.AccessibilityInfo.isReduceMotionEnabled().then(enabled => {
138
- if (!cancelled) setReduceMotion(enabled);
139
- }).catch(() => {
140
- // Defaults to false; no action needed.
141
- });
142
- const sub = _reactNative.AccessibilityInfo.addEventListener('reduceMotionChanged', enabled => {
143
- setReduceMotion(enabled);
144
- });
145
- return () => {
146
- cancelled = true;
147
- sub.remove();
148
- };
149
- }, []);
144
+ // Reduce-motion preference, read as an external store (no effect). Passed to
145
+ // `PhotoPickerView` to skip cell stagger animations.
146
+ const reduceMotion = (0, _useReduceMotion.useReduceMotion)();
150
147
 
151
148
  // Image-only picker mode: when the consumer restricts to image MIME types
152
149
  // (e.g. avatar picker), photos grid is the more useful default view.
@@ -198,24 +195,59 @@ const FileManagementScreen = ({
198
195
  });
199
196
  return sorted;
200
197
  }, [files, searchQuery, viewMode, sortBy, sortOrder]);
201
- const [photoDimensions, setPhotoDimensions] = (0, _react.useState)({});
202
- const photoDimensionsRef = (0, _react.useRef)(photoDimensions);
203
- photoDimensionsRef.current = photoDimensions;
204
- const [loadingDimensions, setLoadingDimensions] = (0, _react.useState)(false);
205
- // Selection state
206
- const [selectedIds, setSelectedIds] = (0, _react.useState)(new Set(initialSelectedIds));
207
- const [lastSelectedFileId, setLastSelectedFileId] = (0, _react.useState)(null);
198
+ // Selection state. `initialSelectedIds` is the INITIAL selection only (lazy
199
+ // init) there is no prop→state sync effect, since no caller mutates it
200
+ // after mount.
201
+ const [selectedIds, setSelectedIds] = (0, _react.useState)(() => new Set(initialSelectedIds));
208
202
  const scrollViewRef = (0, _react.useRef)(null);
209
203
  const photoScrollViewRef = (0, _react.useRef)(null);
210
- const containerRef = (0, _react.useRef)(null);
211
- (0, _react.useEffect)(() => {
212
- if (initialSelectedIds?.length) {
213
- setSelectedIds(new Set(initialSelectedIds));
204
+
205
+ // Scroll the browse list/grid to a just-selected file. Driven directly from
206
+ // the selection event handler (double-rAF so the selection re-render has
207
+ // committed first) — not an effect. No-ops in the image-only picker, whose
208
+ // own FlatList is not either ScrollView ref.
209
+ const scrollToSelectedFile = (0, _react.useCallback)(fileId => {
210
+ if (viewMode === 'all' && scrollViewRef.current) {
211
+ const itemIndex = filteredFiles.findIndex(file => file.id === fileId);
212
+ if (itemIndex < 0) return;
213
+ // GroupedItem dense rows are ~65px, +30px when a description wraps.
214
+ const baseItemHeight = 65;
215
+ const descriptionHeight = 30;
216
+ let scrollPosition = 0;
217
+ for (let i = 0; i <= itemIndex && i < filteredFiles.length; i++) {
218
+ scrollPosition += baseItemHeight;
219
+ if (filteredFiles[i].metadata?.description) scrollPosition += descriptionHeight;
220
+ }
221
+ // Offset for the header/controls/search/stats chrome (~250px) so the
222
+ // item lands near the top, not under the chrome.
223
+ const finalScrollPosition = 250 + scrollPosition - 150;
224
+ requestAnimationFrame(() => {
225
+ requestAnimationFrame(() => {
226
+ scrollViewRef.current?.scrollTo({
227
+ y: Math.max(0, finalScrollPosition),
228
+ animated: true
229
+ });
230
+ });
231
+ });
232
+ } else if (viewMode === 'photos' && photoScrollViewRef.current) {
233
+ const photos = filteredFiles.filter(file => file.contentType.startsWith('image/'));
234
+ const photoIndex = photos.findIndex(p => p.id === fileId);
235
+ if (photoIndex < 0) return;
236
+ // Rough estimate for the justified grid (3 photos/row, variable heights).
237
+ const row = Math.floor(photoIndex / 3);
238
+ const finalScrollPosition = row * (150 + 4) - 100;
239
+ requestAnimationFrame(() => {
240
+ requestAnimationFrame(() => {
241
+ photoScrollViewRef.current?.scrollTo({
242
+ y: Math.max(0, finalScrollPosition),
243
+ animated: true
244
+ });
245
+ });
246
+ });
214
247
  }
215
- }, [initialSelectedIds]);
248
+ }, [viewMode, filteredFiles]);
216
249
  const toggleSelect = (0, _react.useCallback)(async file => {
217
- // Allow selection in regular mode for bulk operations
218
- // if (!selectMode) return;
250
+ // Selection is allowed in regular mode too (for bulk operations).
219
251
  if (disabledMimeTypes.length) {
220
252
  const blocked = disabledMimeTypes.some(mt => file.contentType === mt || file.contentType.startsWith(mt.endsWith('/') ? mt : `${mt}/`));
221
253
  if (blocked) {
@@ -234,9 +266,6 @@ const FileManagementScreen = ({
234
266
  }
235
267
  }
236
268
 
237
- // Track the selected file for scrolling
238
- setLastSelectedFileId(file.id);
239
-
240
269
  // Link file to entity if linkContext is provided
241
270
  if (linkContext) {
242
271
  try {
@@ -278,13 +307,14 @@ const FileManagementScreen = ({
278
307
  }
279
308
  return next;
280
309
  });
281
- }, [selectMode, multiSelect, onSelect, onClose, goBack, dismiss, disabledMimeTypes, maxSelection, afterSelect, defaultVisibility, oxyServices, linkContext]);
310
+ scrollToSelectedFile(file.id);
311
+ }, [multiSelect, onSelect, onClose, goBack, dismiss, disabledMimeTypes, maxSelection, afterSelect, defaultVisibility, oxyServices, linkContext, t, scrollToSelectedFile]);
282
312
  const confirmMultiSelection = (0, _react.useCallback)(async () => {
283
313
  if (!selectMode || !multiSelect) return;
284
314
  const map = {};
285
- files.forEach(f => {
315
+ for (const f of files) {
286
316
  map[f.id] = f;
287
- });
317
+ }
288
318
  const chosen = Array.from(selectedIds).map(id => map[id]).filter(Boolean);
289
319
 
290
320
  // Update visibility and link files if needed
@@ -338,81 +368,16 @@ const FileManagementScreen = ({
338
368
  // FileManagementScreen uses a slightly elevated page background.
339
369
  const backgroundColor = colors.backgroundSecondary;
340
370
  const borderColor = colors.border;
341
- const targetUserId = userId || user?.id;
342
- const storeSetDeleting = (0, _fileStore.useFileStore)(s => s.setDeleting);
343
- const loadFiles = (0, _react.useCallback)(async (mode = 'initial') => {
344
- if (!targetUserId) return;
345
- try {
346
- if (mode === 'refresh') {
347
- setRefreshing(true);
348
- } else if (mode === 'initial') {
349
- setLoading(true);
350
- setPaging(p => ({
351
- ...p,
352
- offset: 0,
353
- hasMore: true
354
- }));
355
- } else if (mode === 'more') {
356
- // Prevent duplicate fetches
357
- setPaging(p => ({
358
- ...p,
359
- loadingMore: true
360
- }));
361
- }
362
- const currentPaging = mode === 'more' ? prevPagingRef.current ?? paging : paging;
363
- const effectiveOffset = mode === 'more' ? currentPaging.offset + currentPaging.limit : 0;
364
- const response = await oxyServices.listUserFiles(currentPaging.limit, effectiveOffset);
365
- const assets = (response.files || []).map(f => ({
366
- id: f.id,
367
- filename: f.originalName ?? f.sha256 ?? '',
368
- contentType: f.mime ?? '',
369
- length: f.size ?? 0,
370
- chunkSize: 0,
371
- uploadDate: f.createdAt ?? '',
372
- metadata: f.metadata ?? {},
373
- variants: f.variants ?? []
374
- }));
375
- if (mode === 'more') {
376
- // append
377
- _fileStore.useFileStore.getState().setFiles(assets, {
378
- merge: true
379
- });
380
- setPaging(p => ({
381
- ...p,
382
- offset: effectiveOffset,
383
- total: response.total || effectiveOffset + assets.length,
384
- hasMore: response.hasMore,
385
- loadingMore: false
386
- }));
387
- } else {
388
- _fileStore.useFileStore.getState().setFiles(assets, {
389
- merge: false
390
- });
391
- setPaging(p => ({
392
- ...p,
393
- offset: 0,
394
- total: response.total || assets.length,
395
- hasMore: response.hasMore,
396
- loadingMore: false
397
- }));
398
- }
399
- } catch (error) {
400
- _bloom.toast.error((0, _shared.getErrorMessage)(error) || t('fileManagement.toasts.loadFailed'));
401
- } finally {
402
- setLoading(false);
403
- setRefreshing(false);
404
- setPaging(p => ({
405
- ...p,
406
- loadingMore: false
407
- }));
408
- }
409
- }, [targetUserId, oxyServices, paging]);
410
371
 
411
372
  // Self-contained document-picking + upload-preview state and handlers.
373
+ // Optimistic uploads edit the file query cache directly (see
374
+ // useFileQueries), so no loader is threaded in.
412
375
  const {
413
376
  isPickingDocument,
414
377
  pendingFiles,
415
378
  showUploadPreview,
379
+ uploading,
380
+ uploadProgress,
416
381
  handleFileUpload,
417
382
  handleConfirmUpload,
418
383
  handleCancelUpload,
@@ -429,105 +394,8 @@ const FileManagementScreen = ({
429
394
  onClose,
430
395
  selectedIds,
431
396
  setSelectedIds,
432
- loadFiles,
433
397
  t
434
398
  });
435
-
436
- // Keep a ref to avoid stale closure when calculating next offset
437
- const prevPagingRef = (0, _react.useRef)(paging);
438
- (0, _react.useEffect)(() => {
439
- prevPagingRef.current = paging;
440
- }, [paging]);
441
-
442
- // (removed effect; filteredFiles is memoized)
443
-
444
- // Load photo dimensions for justified grid - unified approach using Image.getSize
445
- const loadPhotoDimensions = (0, _react.useCallback)(async photos => {
446
- if (photos.length === 0) return;
447
- setLoadingDimensions(true);
448
-
449
- // Snapshot ids missing from the cache at kick-off; concurrent runs may
450
- // overlap but each merge is applied via a functional updater.
451
- const photosToLoad = photos.filter(photo => !photoDimensionsRef.current[photo.id]);
452
- if (photosToLoad.length === 0) {
453
- setLoadingDimensions(false);
454
- return;
455
- }
456
- try {
457
- const measured = {};
458
- await Promise.all(photosToLoad.map(async photo => {
459
- try {
460
- const downloadUrl = thumbSourceFor(photo);
461
- // URL not resolved yet — skip (do NOT record fallback
462
- // dims) so this photo is re-measured once its private-safe
463
- // URL resolves. Measuring the broken public URL is exactly
464
- // the bug we are fixing.
465
- if (!downloadUrl) {
466
- return;
467
- }
468
-
469
- // Unified approach using Image.getSize (works on all platforms)
470
- await new Promise(resolve => {
471
- _reactNative.Image.getSize(downloadUrl, (width, height) => {
472
- measured[photo.id] = {
473
- width,
474
- height
475
- };
476
- resolve();
477
- }, () => {
478
- // Fallback dimensions
479
- measured[photo.id] = {
480
- width: 1,
481
- height: 1
482
- };
483
- resolve();
484
- });
485
- });
486
- } catch (error) {
487
- // Fallback dimensions for any errors
488
- measured[photo.id] = {
489
- width: 1,
490
- height: 1
491
- };
492
- }
493
- }));
494
- if (Object.keys(measured).length > 0) {
495
- setPhotoDimensions(prev => ({
496
- ...prev,
497
- ...measured
498
- }));
499
- }
500
- } catch (error) {
501
- // Photo dimensions loading failed, continue without dimensions
502
- } finally {
503
- setLoadingDimensions(false);
504
- }
505
- }, [thumbSourceFor]);
506
-
507
- // Re-measure photo dimensions when their private-safe URLs resolve. The
508
- // justified grid's own trigger fires on the photo SET, not on URL
509
- // availability, so newly-resolved private tiles would otherwise keep their
510
- // skipped (unmeasured) state and render with fallback geometry.
511
- (0, _react.useEffect)(() => {
512
- if (viewMode !== 'photos') return;
513
- const photos = filteredFiles.filter(file => file.contentType.startsWith('image/'));
514
- if (photos.length > 0) {
515
- loadPhotoDimensions(photos);
516
- }
517
- }, [resolvedThumbUrls, viewMode, filteredFiles, loadPhotoDimensions]);
518
-
519
- // Create justified rows from photos with responsive algorithm
520
- const createJustifiedRows = (0, _react.useCallback)((photos, containerWidth) => {
521
- if (photos.length === 0) return [];
522
- const rows = [];
523
- const photosPerRow = 3; // Fixed 3 photos per row for consistency
524
-
525
- for (let i = 0; i < photos.length; i += photosPerRow) {
526
- const rowPhotos = photos.slice(i, i + photosPerRow);
527
- rows.push(rowPhotos);
528
- }
529
- return rows;
530
- }, []);
531
399
  const confirmFileDelete = (0, _react.useCallback)(async (fileId, filename) => {
532
400
  const confirmed = await _surfaces.surfaces.confirm({
533
401
  title: t('fileManagement.deleteFile') || 'Delete File',
@@ -540,30 +408,28 @@ const FileManagementScreen = ({
540
408
  });
541
409
  if (!confirmed) return;
542
410
  try {
543
- storeSetDeleting(fileId);
411
+ setDeletingId(fileId);
544
412
  await oxyServices.deleteFile(fileId);
545
413
  _bloom.toast.success(t('fileManagement.toasts.deleteSuccess'));
546
414
 
547
- // Reload files after successful deletion
548
- // Optimistic remove
549
- _fileStore.useFileStore.getState().removeFile(fileId);
550
- // Silent background reconcile
551
- setTimeout(() => loadFiles('silent'), 800);
415
+ // Remove from the query cache, then reconcile against the server.
416
+ (0, _useFileQueries.removeFileFromCache)(queryClient, targetUserId, fileId);
417
+ invalidateFiles();
552
418
  } catch (error) {
553
419
  // Provide specific error messages
554
420
  if ((0, _shared.getErrorMessage)(error)?.includes('File not found') || (0, _shared.getErrorMessage)(error)?.includes('404')) {
555
421
  _bloom.toast.error(t('fileManagement.toasts.fileNotFound'));
556
- // Still reload files to refresh the list
557
- setTimeout(() => loadFiles('silent'), 800);
422
+ // It's already gone server-side reconcile the list.
423
+ invalidateFiles();
558
424
  } else if ((0, _shared.getErrorMessage)(error)?.includes('permission') || (0, _shared.getErrorMessage)(error)?.includes('403')) {
559
425
  _bloom.toast.error(t('fileManagement.toasts.noPermission'));
560
426
  } else {
561
427
  _bloom.toast.error((0, _shared.getErrorMessage)(error) || t('fileManagement.toasts.deleteFailed'));
562
428
  }
563
429
  } finally {
564
- storeSetDeleting(null);
430
+ setDeletingId(null);
565
431
  }
566
- }, [storeSetDeleting, oxyServices, loadFiles, t]);
432
+ }, [oxyServices, queryClient, targetUserId, invalidateFiles, t]);
567
433
  const confirmBulkDelete = (0, _react.useCallback)(async () => {
568
434
  if (selectedIds.size === 0) return;
569
435
  const confirmed = await _surfaces.surfaces.confirm({
@@ -580,7 +446,7 @@ const FileManagementScreen = ({
580
446
  const deletePromises = Array.from(selectedIds).map(async fileId => {
581
447
  try {
582
448
  await oxyServices.deleteFile(fileId);
583
- _fileStore.useFileStore.getState().removeFile(fileId);
449
+ (0, _useFileQueries.removeFileFromCache)(queryClient, targetUserId, fileId);
584
450
  return {
585
451
  success: true,
586
452
  fileId
@@ -607,11 +473,11 @@ const FileManagementScreen = ({
607
473
  }));
608
474
  }
609
475
  setSelectedIds(new Set());
610
- setTimeout(() => loadFiles('silent'), 800);
476
+ invalidateFiles();
611
477
  } catch (error) {
612
478
  _bloom.toast.error((0, _shared.getErrorMessage)(error) || t('fileManagement.toasts.bulkDeleteError'));
613
479
  }
614
- }, [selectedIds, oxyServices, loadFiles, t]);
480
+ }, [selectedIds, oxyServices, queryClient, targetUserId, invalidateFiles, t]);
615
481
  const handleBulkVisibilityChange = (0, _react.useCallback)(async visibility => {
616
482
  if (selectedIds.size === 0) return;
617
483
  try {
@@ -638,26 +504,23 @@ const FileManagementScreen = ({
638
504
  count: successful,
639
505
  visibility
640
506
  }));
641
- // Update file metadata in store
642
- Array.from(selectedIds).forEach(fileId => {
643
- _fileStore.useFileStore.getState().updateFile(fileId, {
644
- metadata: {
645
- ...files.find(f => f.id === fileId)?.metadata,
646
- visibility
647
- }
507
+ // Reflect the new visibility in the cached files.
508
+ for (const fileId of selectedIds) {
509
+ (0, _useFileQueries.patchFileMetadataInCache)(queryClient, targetUserId, fileId, {
510
+ visibility
648
511
  });
649
- });
512
+ }
650
513
  }
651
514
  if (failed > 0) {
652
515
  _bloom.toast.error(t('fileManagement.toasts.visibilityFailed', {
653
516
  count: failed
654
517
  }));
655
518
  }
656
- setTimeout(() => loadFiles('silent'), 800);
519
+ invalidateFiles();
657
520
  } catch (error) {
658
521
  _bloom.toast.error((0, _shared.getErrorMessage)(error) || t('fileManagement.toasts.visibilityError'));
659
522
  }
660
- }, [selectedIds, oxyServices, files, loadFiles, t]);
523
+ }, [selectedIds, oxyServices, queryClient, targetUserId, invalidateFiles, t]);
661
524
  const handleVisibilityChange = (0, _react.useCallback)(async () => {
662
525
  if (selectedIds.size === 0) return;
663
526
  const visibility = await (0, _ActionSheetSurface.presentActionSheet)({
@@ -681,7 +544,7 @@ const FileManagementScreen = ({
681
544
  }, [selectedIds.size, handleBulkVisibilityChange, t]);
682
545
 
683
546
  // Unified download function - works on all platforms
684
- const handleFileDownload = async (fileId, filename) => {
547
+ const handleFileDownload = (0, _react.useCallback)(async (fileId, filename) => {
685
548
  try {
686
549
  // Resolve an authenticated, private-safe URL. The synchronous
687
550
  // `getFileDownloadUrl` yields the public CDN origin, which 404s for
@@ -724,8 +587,8 @@ const FileManagementScreen = ({
724
587
  } catch (error) {
725
588
  _bloom.toast.error((0, _shared.getErrorMessage)(error) || t('fileManagement.toasts.downloadFailed'));
726
589
  }
727
- };
728
- const handleFileOpen = async file => {
590
+ }, [oxyServices, t]);
591
+ const handleFileOpen = (0, _react.useCallback)(async file => {
729
592
  if (selectMode) {
730
593
  toggleSelect(file);
731
594
  return;
@@ -765,21 +628,21 @@ const FileManagementScreen = ({
765
628
  } finally {
766
629
  setLoadingFileContent(false);
767
630
  }
768
- };
769
- const handleCloseFile = () => {
631
+ }, [selectMode, toggleSelect, oxyServices, t]);
632
+ const handleCloseFile = (0, _react.useCallback)(() => {
770
633
  setOpenedFile(null);
771
634
  setFileContent(null);
772
635
  setShowFileDetailsInViewer(false);
773
636
  // Don't reset view mode when closing a file
774
- };
775
- const showFileDetailsModal = file => {
637
+ }, []);
638
+ const showFileDetailsModal = (0, _react.useCallback)(file => {
776
639
  (0, _FileDetailsModal.presentFileDetails)({
777
640
  file,
778
641
  onDownload: handleFileDownload,
779
642
  onDelete: confirmFileDelete,
780
643
  isOwner: user?.id === targetUserId
781
644
  });
782
- };
645
+ }, [handleFileDownload, confirmFileDelete, user?.id, targetUserId]);
783
646
  const renderJustifiedPhotoItem = (0, _react.useCallback)((photo, width, height, isLast) => {
784
647
  const downloadUrl = thumbSourceFor(photo);
785
648
  return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
@@ -824,18 +687,7 @@ const FileManagementScreen = ({
824
687
  })]
825
688
  })
826
689
  }, photo.id);
827
- }, [thumbSourceFor, selectMode, selectedIds, multiSelect, colors.primary, colors.text]);
828
-
829
- // Run initial load once per targetUserId change to avoid accidental loops
830
- const lastLoadedFor = (0, _react.useRef)(undefined);
831
- (0, _react.useEffect)(() => {
832
- const key = targetUserId || 'anonymous';
833
- if (lastLoadedFor.current !== key) {
834
- lastLoadedFor.current = key;
835
- loadFiles('initial');
836
- }
837
- // eslint-disable-next-line react-hooks/exhaustive-deps
838
- }, [targetUserId]);
690
+ }, [thumbSourceFor, selectMode, selectedIds, multiSelect, colors.primary, colors.text, handleFileOpen]);
839
691
 
840
692
  // SettingsListItem-based file items (for 'all' view)
841
693
  const groupedFileItems = (0, _react.useMemo)(() => {
@@ -986,8 +838,8 @@ const FileManagementScreen = ({
986
838
  backgroundColor: colors.negativeSubtle
987
839
  },
988
840
  onPress: () => confirmFileDelete(file.id, file.filename),
989
- disabled: deleting === file.id,
990
- children: deleting === file.id ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
841
+ disabled: deletingId === file.id,
842
+ children: deletingId === file.id ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
991
843
  size: "small",
992
844
  color: colors.error
993
845
  }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
@@ -999,85 +851,27 @@ const FileManagementScreen = ({
999
851
  }) : undefined
1000
852
  };
1001
853
  });
1002
- }, [filteredFiles, theme, deleting, handleFileDownload, confirmFileDelete, handleFileOpen, thumbSourceFor, selectMode, selectedIds]);
1003
-
1004
- // Scroll to selected file after selection
1005
- (0, _react.useEffect)(() => {
1006
- if (lastSelectedFileId && selectMode) {
1007
- if (viewMode === 'all' && scrollViewRef.current) {
1008
- // Find the index of the selected file (filteredFiles is already sorted)
1009
- const itemIndex = filteredFiles.findIndex(file => file.id === lastSelectedFileId);
1010
- if (itemIndex >= 0) {
1011
- // Estimate item height (GroupedItem with dense mode is approximately 60-70px)
1012
- // Account for description rows which add extra height
1013
- const baseItemHeight = 65;
1014
- const descriptionHeight = 30; // Approximate height for description
1015
- // Use filteredFiles which is already sorted according to user's selection
1016
- const sortedFiles = filteredFiles;
1017
-
1018
- // Calculate total height up to this item
1019
- let scrollPosition = 0;
1020
- for (let i = 0; i <= itemIndex && i < sortedFiles.length; i++) {
1021
- const file = sortedFiles[i];
1022
- scrollPosition += baseItemHeight;
1023
- if (file.metadata?.description) {
1024
- scrollPosition += descriptionHeight;
1025
- }
1026
- }
1027
-
1028
- // Add header, controls, search, and stats height (approximately 250px)
1029
- const headerHeight = 250;
1030
- const finalScrollPosition = headerHeight + scrollPosition - 150; // Offset to show item near top
1031
-
1032
- // Use requestAnimationFrame to ensure DOM is updated before scrolling
1033
- requestAnimationFrame(() => {
1034
- requestAnimationFrame(() => {
1035
- scrollViewRef.current?.scrollTo({
1036
- y: Math.max(0, finalScrollPosition),
1037
- animated: true
1038
- });
1039
- });
1040
- });
1041
- }
1042
- } else if (viewMode === 'photos' && photoScrollViewRef.current) {
1043
- // For photo grid, find the photo index
1044
- const photos = filteredFiles.filter(file => file.contentType.startsWith('image/'));
1045
- const photoIndex = photos.findIndex(p => p.id === lastSelectedFileId);
1046
- if (photoIndex >= 0) {
1047
- // Rough scroll estimate for the justified grid (3 photos/row; variable row heights).
1048
- const itemsPerRow = 3;
1049
- const estimatedRowHeight = 150;
1050
- const rowGap = 4;
1051
- const row = Math.floor(photoIndex / itemsPerRow);
1052
- const finalScrollPosition = row * (estimatedRowHeight + rowGap) - 100;
854
+ }, [filteredFiles, colors, deletingId, toggleSelect, handleFileDownload, confirmFileDelete, handleFileOpen, thumbSourceFor, selectMode, selectedIds]);
1053
855
 
1054
- // Use requestAnimationFrame to ensure DOM is updated before scrolling
1055
- requestAnimationFrame(() => {
1056
- requestAnimationFrame(() => {
1057
- photoScrollViewRef.current?.scrollTo({
1058
- y: Math.max(0, finalScrollPosition),
1059
- animated: true
1060
- });
1061
- });
1062
- });
1063
- }
1064
- }
1065
- }
1066
- }, [lastSelectedFileId, selectMode, viewMode, filteredFiles, safeContainerWidth]);
1067
-
1068
- // Clear selected file ID after scroll animation completes
1069
- (0, _react.useEffect)(() => {
1070
- if (lastSelectedFileId && scrollViewRef.current) {
1071
- const timeoutId = setTimeout(() => {
1072
- setLastSelectedFileId(null);
1073
- }, 600); // Allow time for scroll animation to complete
856
+ // Browse-themed terminal load-failure state DISTINCT from the empty state.
857
+ const renderLoadError = () => /*#__PURE__*/(0, _jsxRuntime.jsx)(_FileLibraryError.default, {
858
+ title: t('fileManagement.loadError.title'),
859
+ description: t('fileManagement.loadError.description'),
860
+ retryLabel: t('fileManagement.retry'),
861
+ onRetry: () => filesQuery.refetch(),
862
+ iconColor: colors.error,
863
+ titleColor: colors.text,
864
+ descriptionColor: colors.textSecondary,
865
+ buttonColor: colors.primary
866
+ });
1074
867
 
1075
- return () => clearTimeout(timeoutId);
1076
- }
1077
- }, [lastSelectedFileId]);
1078
- const renderPhotoGrid = (0, _react.useCallback)(() => {
868
+ // Browse "photos" view. The justified grid owns its own dimension
869
+ // measurement + reflow (see JustifiedPhotoGrid); this only supplies the
870
+ // photo set, the private-safe URL resolver, and the tile renderer.
871
+ const renderPhotoGrid = () => {
1079
872
  const photos = filteredFiles.filter(file => file.contentType.startsWith('image/'));
1080
873
  if (photos.length === 0) {
874
+ if (hasLoadError) return renderLoadError();
1081
875
  return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
1082
876
  className: "items-center py-[40px] px-[24px]",
1083
877
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
@@ -1103,10 +897,7 @@ const FileManagementScreen = ({
1103
897
  },
1104
898
  onPress: handleFileUpload,
1105
899
  disabled: uploading || isPickingDocument,
1106
- children: uploading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
1107
- size: "small",
1108
- color: "#FFFFFF"
1109
- }) : isPickingDocument ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
900
+ children: uploading || isPickingDocument ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
1110
901
  size: "small",
1111
902
  color: "#FFFFFF"
1112
903
  }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
@@ -1122,13 +913,13 @@ const FileManagementScreen = ({
1122
913
  })]
1123
914
  });
1124
915
  }
1125
- return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.ScrollView, {
916
+ return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ScrollView, {
1126
917
  ref: photoScrollViewRef,
1127
918
  className: "flex-1",
1128
919
  contentContainerClassName: "p-[10px]",
1129
920
  refreshControl: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.RefreshControl, {
1130
- refreshing: refreshing,
1131
- onRefresh: () => loadFiles('refresh'),
921
+ refreshing: isRefreshingFiles,
922
+ onRefresh: () => filesQuery.refetch(),
1132
923
  tintColor: colors.primary
1133
924
  }),
1134
925
  showsVerticalScrollIndicator: false,
@@ -1141,38 +932,21 @@ const FileManagementScreen = ({
1141
932
  contentSize
1142
933
  } = nativeEvent;
1143
934
  const distanceFromBottom = contentSize.height - (contentOffset.y + layoutMeasurement.height);
1144
- if (distanceFromBottom < 200 && !paging.loadingMore && paging.hasMore) {
1145
- loadFiles('more');
935
+ if (distanceFromBottom < 200 && !isFetchingMore && hasMoreFiles) {
936
+ filesQuery.fetchNextPage();
1146
937
  }
1147
938
  },
1148
939
  scrollEventThrottle: 250,
1149
- children: [loadingDimensions && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
1150
- className: "flex-row items-center justify-center py-[16px] gap-[8px]",
1151
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
1152
- size: "small",
1153
- color: colors.primary
1154
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
1155
- className: "text-[14px] italic",
1156
- style: {
1157
- color: colors.textSecondary
1158
- },
1159
- children: t('fileManagement.loadingPhotoLayout')
1160
- })]
1161
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_JustifiedPhotoGrid.default, {
940
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_JustifiedPhotoGrid.default, {
1162
941
  photos: photos,
1163
- photoDimensions: photoDimensions,
1164
- loadPhotoDimensions: loadPhotoDimensions,
1165
- createJustifiedRows: createJustifiedRows,
942
+ getThumbUrl: thumbSourceFor,
1166
943
  renderJustifiedPhotoItem: renderJustifiedPhotoItem,
1167
944
  textColor: colors.text,
1168
945
  containerWidth: typeof containerWidth === 'number' && containerWidth > 0 ? containerWidth : undefined
1169
- })]
946
+ })
1170
947
  });
1171
- }, [filteredFiles, colors, user?.id, targetUserId, uploading, handleFileUpload, refreshing, loadFiles, loadingDimensions, photoDimensions, loadPhotoDimensions, createJustifiedRows, renderJustifiedPhotoItem, containerWidth]);
1172
-
1173
- // Inline justified grid removed (moved to components/photogrid/JustifiedPhotoGrid.tsx)
1174
-
1175
- const renderEmptyState = () => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
948
+ };
949
+ const renderEmptyState = () => hasLoadError ? renderLoadError() : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
1176
950
  className: "items-center py-[40px] px-[24px]",
1177
951
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
1178
952
  name: "folder-open-outline",
@@ -1197,10 +971,7 @@ const FileManagementScreen = ({
1197
971
  },
1198
972
  onPress: handleFileUpload,
1199
973
  disabled: uploading || isPickingDocument,
1200
- children: uploading ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
1201
- size: "small",
1202
- color: "#FFFFFF"
1203
- }) : isPickingDocument ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
974
+ children: uploading || isPickingDocument ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
1204
975
  size: "small",
1205
976
  color: "#FFFFFF"
1206
977
  }) : /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
@@ -1304,7 +1075,7 @@ const FileManagementScreen = ({
1304
1075
  right: fmHeaderRight,
1305
1076
  largeTitle: false
1306
1077
  });
1307
- if (loading && !isImageOnlyPicker) {
1078
+ if (isLoadingFiles && !isImageOnlyPicker) {
1308
1079
  const GRID_PADDING = 10;
1309
1080
  const TILE_GAP = 4;
1310
1081
  const GRID_COLUMNS = 3;
@@ -1403,13 +1174,15 @@ const FileManagementScreen = ({
1403
1174
  multiSelect: multiSelect,
1404
1175
  maxSelection: maxSelection,
1405
1176
  allowUpload: allowUpload,
1406
- refreshing: refreshing,
1177
+ refreshing: isRefreshingFiles,
1407
1178
  uploading: uploading,
1408
1179
  isPickingDocument: isPickingDocument,
1409
1180
  uploadProgress: uploadProgress,
1410
- hasMore: paging.hasMore,
1411
- loadingMore: paging.loadingMore,
1412
- loading: loading,
1181
+ hasMore: hasMoreFiles,
1182
+ loadingMore: isFetchingMore,
1183
+ loading: isLoadingFiles,
1184
+ loadError: hasLoadError,
1185
+ onRetry: () => filesQuery.refetch(),
1413
1186
  reduceMotion: reduceMotion,
1414
1187
  getThumbUrl: thumbSourceFor,
1415
1188
  primaryColor: colors.primary,
@@ -1419,8 +1192,8 @@ const FileManagementScreen = ({
1419
1192
  ,
1420
1193
  onPreviewPhoto: file => showFileDetailsModal(file),
1421
1194
  onUpload: handleFileUpload,
1422
- onRefresh: () => loadFiles('refresh'),
1423
- onLoadMore: () => loadFiles('more'),
1195
+ onRefresh: () => filesQuery.refetch(),
1196
+ onLoadMore: () => filesQuery.fetchNextPage(),
1424
1197
  onCancel: () => {
1425
1198
  if (onSelect || onConfirmSelection) {
1426
1199
  // Legacy callback caller: preserve close/back behaviour.
@@ -1495,32 +1268,30 @@ const FileManagementScreen = ({
1495
1268
  textColor: colors.text,
1496
1269
  style: screenStyles.viewModeButton,
1497
1270
  accessibilityLabel: t('fileManagement.a11y.viewPhotos') || 'Show photos only'
1498
- }), !isImageOnlyPicker && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
1499
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_AnimatedButton.AnimatedButton, {
1500
- isSelected: viewMode === 'videos',
1501
- onPress: () => setViewMode('videos'),
1502
- icon: viewMode === 'videos' ? 'video' : 'video-outline',
1503
- primaryColor: colors.primary,
1504
- textColor: colors.text,
1505
- style: screenStyles.viewModeButton,
1506
- accessibilityLabel: t('fileManagement.a11y.viewVideos') || 'Show videos only'
1507
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_AnimatedButton.AnimatedButton, {
1508
- isSelected: viewMode === 'documents',
1509
- onPress: () => setViewMode('documents'),
1510
- icon: viewMode === 'documents' ? 'file-document' : 'file-document-outline',
1511
- primaryColor: colors.primary,
1512
- textColor: colors.text,
1513
- style: screenStyles.viewModeButton,
1514
- accessibilityLabel: t('fileManagement.a11y.viewDocuments') || 'Show documents only'
1515
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_AnimatedButton.AnimatedButton, {
1516
- isSelected: viewMode === 'audio',
1517
- onPress: () => setViewMode('audio'),
1518
- icon: viewMode === 'audio' ? 'music-note' : 'music-note-outline',
1519
- primaryColor: colors.primary,
1520
- textColor: colors.text,
1521
- style: screenStyles.viewModeButton,
1522
- accessibilityLabel: t('fileManagement.a11y.viewAudio') || 'Show audio only'
1523
- })]
1271
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_AnimatedButton.AnimatedButton, {
1272
+ isSelected: viewMode === 'videos',
1273
+ onPress: () => setViewMode('videos'),
1274
+ icon: viewMode === 'videos' ? 'video' : 'video-outline',
1275
+ primaryColor: colors.primary,
1276
+ textColor: colors.text,
1277
+ style: screenStyles.viewModeButton,
1278
+ accessibilityLabel: t('fileManagement.a11y.viewVideos') || 'Show videos only'
1279
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_AnimatedButton.AnimatedButton, {
1280
+ isSelected: viewMode === 'documents',
1281
+ onPress: () => setViewMode('documents'),
1282
+ icon: viewMode === 'documents' ? 'file-document' : 'file-document-outline',
1283
+ primaryColor: colors.primary,
1284
+ textColor: colors.text,
1285
+ style: screenStyles.viewModeButton,
1286
+ accessibilityLabel: t('fileManagement.a11y.viewDocuments') || 'Show documents only'
1287
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_AnimatedButton.AnimatedButton, {
1288
+ isSelected: viewMode === 'audio',
1289
+ onPress: () => setViewMode('audio'),
1290
+ icon: viewMode === 'audio' ? 'music-note' : 'music-note-outline',
1291
+ primaryColor: colors.primary,
1292
+ textColor: colors.text,
1293
+ style: screenStyles.viewModeButton,
1294
+ accessibilityLabel: t('fileManagement.a11y.viewAudio') || 'Show audio only'
1524
1295
  })]
1525
1296
  })
1526
1297
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
@@ -1553,15 +1324,15 @@ const FileManagementScreen = ({
1553
1324
  size: 14,
1554
1325
  color: colors.textSecondary
1555
1326
  })]
1556
- }), user?.id === targetUserId && (!selectMode || selectMode && allowUploadInSelectMode) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
1557
- className: `h-[44px] rounded-[22px] items-center justify-center ${isImageOnlyPicker ? 'w-auto min-w-[44px] px-[14px]' : 'w-[44px]'}`,
1327
+ }), user?.id === targetUserId && (!selectMode || allowUploadInSelectMode) && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
1328
+ className: "h-[44px] w-[44px] rounded-[22px] items-center justify-center",
1558
1329
  style: {
1559
1330
  backgroundColor: colors.primary
1560
1331
  },
1561
1332
  onPress: handleFileUpload,
1562
1333
  disabled: uploading || isPickingDocument,
1563
1334
  accessibilityRole: "button",
1564
- accessibilityLabel: isImageOnlyPicker ? t('fileManagement.a11y.uploadFromDevice') || 'Upload photo from device' : t('fileManagement.a11y.uploadFile') || 'Upload file',
1335
+ accessibilityLabel: t('fileManagement.a11y.uploadFile') || 'Upload file',
1565
1336
  accessibilityState: {
1566
1337
  busy: uploading || isPickingDocument
1567
1338
  },
@@ -1577,17 +1348,6 @@ const FileManagementScreen = ({
1577
1348
  }) : isPickingDocument ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.ActivityIndicator, {
1578
1349
  size: "small",
1579
1350
  color: "#FFFFFF"
1580
- }) : isImageOnlyPicker ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
1581
- className: "flex-row items-center gap-[6px]",
1582
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
1583
- name: "cloud-upload",
1584
- size: 18,
1585
- color: "#FFFFFF"
1586
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
1587
- className: "text-white text-[14px] font-semibold",
1588
- numberOfLines: 1,
1589
- children: t('fileManagement.upload') || 'Upload'
1590
- })]
1591
1351
  }) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.Ionicons, {
1592
1352
  name: "add",
1593
1353
  size: 22,
@@ -1683,12 +1443,15 @@ const FileManagementScreen = ({
1683
1443
  filteredFiles: filteredFiles,
1684
1444
  searchQuery: searchQuery,
1685
1445
  items: groupedFileItems,
1686
- paging: paging,
1687
- refreshing: refreshing,
1446
+ paging: {
1447
+ loadingMore: isFetchingMore,
1448
+ hasMore: hasMoreFiles
1449
+ },
1450
+ refreshing: isRefreshingFiles,
1688
1451
  colors: colors,
1689
1452
  t: t,
1690
- onRefresh: () => loadFiles('refresh'),
1691
- onLoadMore: () => loadFiles('more'),
1453
+ onRefresh: () => filesQuery.refetch(),
1454
+ onLoadMore: () => filesQuery.fetchNextPage(),
1692
1455
  onClearSearch: () => setSearchQuery(''),
1693
1456
  renderEmptyState: renderEmptyState
1694
1457
  }), !selectMode && uploading && /*#__PURE__*/(0, _jsxRuntime.jsx)(_UploadBar.default, {