@oxy.so/services 11.6.0 → 11.9.0

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 (186) hide show
  1. package/android/src/main/java/so/oxy/security/OxyCallerPolicy.kt +18 -0
  2. package/lib/commonjs/assets/assets/fonts/icons/OxyServicesIonicons.ttf +0 -0
  3. package/lib/commonjs/assets/assets/fonts/icons/OxyServicesMaterialCommunityIcons.ttf +0 -0
  4. package/lib/commonjs/assets/assets/fonts/icons/manifest.json +8 -5
  5. package/lib/commonjs/assets/fonts/icons/OxyServicesIonicons.ttf +0 -0
  6. package/lib/commonjs/assets/fonts/icons/OxyServicesMaterialCommunityIcons.ttf +0 -0
  7. package/lib/commonjs/assets/fonts/icons/manifest.json +8 -5
  8. package/lib/commonjs/ui/components/fileManagement/FileViewer.js +2 -1
  9. package/lib/commonjs/ui/components/fileManagement/FileViewer.js.map +1 -1
  10. package/lib/commonjs/ui/components/supervision/PersonPicker.js +69 -0
  11. package/lib/commonjs/ui/components/supervision/PersonPicker.js.map +1 -0
  12. package/lib/commonjs/ui/components/supervision/presentation.js +23 -0
  13. package/lib/commonjs/ui/components/supervision/presentation.js.map +1 -0
  14. package/lib/commonjs/ui/hooks/queries/queryKeys.js +3 -1
  15. package/lib/commonjs/ui/hooks/queries/queryKeys.js.map +1 -1
  16. package/lib/commonjs/ui/hooks/queries/useFileQueries.js +39 -17
  17. package/lib/commonjs/ui/hooks/queries/useFileQueries.js.map +1 -1
  18. package/lib/commonjs/ui/hooks/queries/useSupervision.js +37 -0
  19. package/lib/commonjs/ui/hooks/queries/useSupervision.js.map +1 -0
  20. package/lib/commonjs/ui/icons/subsetGlyphMaps.js +3 -0
  21. package/lib/commonjs/ui/icons/subsetGlyphMaps.js.map +1 -1
  22. package/lib/commonjs/ui/index.js +13 -0
  23. package/lib/commonjs/ui/index.js.map +1 -1
  24. package/lib/commonjs/ui/navigation/routes.js +2 -0
  25. package/lib/commonjs/ui/navigation/routes.js.map +1 -1
  26. package/lib/commonjs/ui/navigation/surfaceRegistry.js +2 -2
  27. package/lib/commonjs/ui/navigation/surfaceRegistry.js.map +1 -1
  28. package/lib/commonjs/ui/screens/CreateAccountScreen.js +10 -2
  29. package/lib/commonjs/ui/screens/CreateAccountScreen.js.map +1 -1
  30. package/lib/commonjs/ui/screens/FileManagementScreen.js +102 -44
  31. package/lib/commonjs/ui/screens/FileManagementScreen.js.map +1 -1
  32. package/lib/commonjs/ui/screens/FileTrashScreen.js +235 -0
  33. package/lib/commonjs/ui/screens/FileTrashScreen.js.map +1 -0
  34. package/lib/commonjs/ui/screens/ManageAccountScreen.js +7 -0
  35. package/lib/commonjs/ui/screens/ManageAccountScreen.js.map +1 -1
  36. package/lib/commonjs/ui/screens/SupervisionScreen.js +529 -0
  37. package/lib/commonjs/ui/screens/SupervisionScreen.js.map +1 -0
  38. package/lib/commonjs/ui/screens/fileManagement/trashActions.js +147 -0
  39. package/lib/commonjs/ui/screens/fileManagement/trashActions.js.map +1 -0
  40. package/lib/commonjs/ui/screens/index.js +7 -0
  41. package/lib/commonjs/ui/screens/index.js.map +1 -1
  42. package/lib/commonjs/ui/stores/assetStore.js +22 -7
  43. package/lib/commonjs/ui/stores/assetStore.js.map +1 -1
  44. package/lib/module/assets/assets/fonts/icons/OxyServicesIonicons.ttf +0 -0
  45. package/lib/module/assets/assets/fonts/icons/OxyServicesMaterialCommunityIcons.ttf +0 -0
  46. package/lib/module/assets/assets/fonts/icons/manifest.json +8 -5
  47. package/lib/module/assets/fonts/icons/OxyServicesIonicons.ttf +0 -0
  48. package/lib/module/assets/fonts/icons/OxyServicesMaterialCommunityIcons.ttf +0 -0
  49. package/lib/module/assets/fonts/icons/manifest.json +8 -5
  50. package/lib/module/ui/components/fileManagement/FileViewer.js +2 -1
  51. package/lib/module/ui/components/fileManagement/FileViewer.js.map +1 -1
  52. package/lib/module/ui/components/supervision/PersonPicker.js +65 -0
  53. package/lib/module/ui/components/supervision/PersonPicker.js.map +1 -0
  54. package/lib/module/ui/components/supervision/presentation.js +19 -0
  55. package/lib/module/ui/components/supervision/presentation.js.map +1 -0
  56. package/lib/module/ui/hooks/queries/queryKeys.js +3 -1
  57. package/lib/module/ui/hooks/queries/queryKeys.js.map +1 -1
  58. package/lib/module/ui/hooks/queries/useFileQueries.js +38 -17
  59. package/lib/module/ui/hooks/queries/useFileQueries.js.map +1 -1
  60. package/lib/module/ui/hooks/queries/useSupervision.js +32 -0
  61. package/lib/module/ui/hooks/queries/useSupervision.js.map +1 -0
  62. package/lib/module/ui/icons/subsetGlyphMaps.js +3 -0
  63. package/lib/module/ui/icons/subsetGlyphMaps.js.map +1 -1
  64. package/lib/module/ui/index.js +1 -0
  65. package/lib/module/ui/index.js.map +1 -1
  66. package/lib/module/ui/navigation/routes.js +2 -0
  67. package/lib/module/ui/navigation/routes.js.map +1 -1
  68. package/lib/module/ui/navigation/surfaceRegistry.js +2 -2
  69. package/lib/module/ui/navigation/surfaceRegistry.js.map +1 -1
  70. package/lib/module/ui/screens/CreateAccountScreen.js +10 -2
  71. package/lib/module/ui/screens/CreateAccountScreen.js.map +1 -1
  72. package/lib/module/ui/screens/FileManagementScreen.js +102 -44
  73. package/lib/module/ui/screens/FileManagementScreen.js.map +1 -1
  74. package/lib/module/ui/screens/FileTrashScreen.js +232 -0
  75. package/lib/module/ui/screens/FileTrashScreen.js.map +1 -0
  76. package/lib/module/ui/screens/ManageAccountScreen.js +7 -0
  77. package/lib/module/ui/screens/ManageAccountScreen.js.map +1 -1
  78. package/lib/module/ui/screens/SupervisionScreen.js +525 -0
  79. package/lib/module/ui/screens/SupervisionScreen.js.map +1 -0
  80. package/lib/module/ui/screens/fileManagement/trashActions.js +138 -0
  81. package/lib/module/ui/screens/fileManagement/trashActions.js.map +1 -0
  82. package/lib/module/ui/screens/index.js +1 -0
  83. package/lib/module/ui/screens/index.js.map +1 -1
  84. package/lib/module/ui/stores/assetStore.js +22 -7
  85. package/lib/module/ui/stores/assetStore.js.map +1 -1
  86. package/lib/typescript/commonjs/ui/components/fileManagement/FileViewer.d.ts +3 -0
  87. package/lib/typescript/commonjs/ui/components/fileManagement/FileViewer.d.ts.map +1 -1
  88. package/lib/typescript/commonjs/ui/components/supervision/PersonPicker.d.ts +6 -0
  89. package/lib/typescript/commonjs/ui/components/supervision/PersonPicker.d.ts.map +1 -0
  90. package/lib/typescript/commonjs/ui/components/supervision/presentation.d.ts +3 -0
  91. package/lib/typescript/commonjs/ui/components/supervision/presentation.d.ts.map +1 -0
  92. package/lib/typescript/commonjs/ui/hooks/queries/queryKeys.d.ts +2 -0
  93. package/lib/typescript/commonjs/ui/hooks/queries/queryKeys.d.ts.map +1 -1
  94. package/lib/typescript/commonjs/ui/hooks/queries/useFileQueries.d.ts +22 -6
  95. package/lib/typescript/commonjs/ui/hooks/queries/useFileQueries.d.ts.map +1 -1
  96. package/lib/typescript/commonjs/ui/hooks/queries/useSupervision.d.ts +475 -0
  97. package/lib/typescript/commonjs/ui/hooks/queries/useSupervision.d.ts.map +1 -0
  98. package/lib/typescript/commonjs/ui/icons/Ionicons.d.ts +1 -1
  99. package/lib/typescript/commonjs/ui/icons/Ionicons.d.ts.map +1 -1
  100. package/lib/typescript/commonjs/ui/icons/MaterialCommunityIcons.d.ts +1 -1
  101. package/lib/typescript/commonjs/ui/icons/MaterialCommunityIcons.d.ts.map +1 -1
  102. package/lib/typescript/commonjs/ui/icons/subsetGlyphMaps.d.ts +3 -0
  103. package/lib/typescript/commonjs/ui/icons/subsetGlyphMaps.d.ts.map +1 -1
  104. package/lib/typescript/commonjs/ui/index.d.ts +1 -0
  105. package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
  106. package/lib/typescript/commonjs/ui/navigation/routes.d.ts +1 -1
  107. package/lib/typescript/commonjs/ui/navigation/routes.d.ts.map +1 -1
  108. package/lib/typescript/commonjs/ui/navigation/surfaceRegistry.d.ts +6 -0
  109. package/lib/typescript/commonjs/ui/navigation/surfaceRegistry.d.ts.map +1 -1
  110. package/lib/typescript/commonjs/ui/screens/CreateAccountScreen.d.ts.map +1 -1
  111. package/lib/typescript/commonjs/ui/screens/FileManagementScreen.d.ts.map +1 -1
  112. package/lib/typescript/commonjs/ui/screens/FileTrashScreen.d.ts +14 -0
  113. package/lib/typescript/commonjs/ui/screens/FileTrashScreen.d.ts.map +1 -0
  114. package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  115. package/lib/typescript/commonjs/ui/screens/SupervisionScreen.d.ts +3 -0
  116. package/lib/typescript/commonjs/ui/screens/SupervisionScreen.d.ts.map +1 -0
  117. package/lib/typescript/commonjs/ui/screens/fileManagement/trashActions.d.ts +66 -0
  118. package/lib/typescript/commonjs/ui/screens/fileManagement/trashActions.d.ts.map +1 -0
  119. package/lib/typescript/commonjs/ui/screens/index.d.ts +1 -0
  120. package/lib/typescript/commonjs/ui/screens/index.d.ts.map +1 -1
  121. package/lib/typescript/commonjs/ui/stores/assetStore.d.ts.map +1 -1
  122. package/lib/typescript/commonjs/ui/utils/identityCrypto.d.ts +1 -0
  123. package/lib/typescript/commonjs/ui/utils/identityCrypto.d.ts.map +1 -1
  124. package/lib/typescript/module/ui/components/fileManagement/FileViewer.d.ts +3 -0
  125. package/lib/typescript/module/ui/components/fileManagement/FileViewer.d.ts.map +1 -1
  126. package/lib/typescript/module/ui/components/supervision/PersonPicker.d.ts +6 -0
  127. package/lib/typescript/module/ui/components/supervision/PersonPicker.d.ts.map +1 -0
  128. package/lib/typescript/module/ui/components/supervision/presentation.d.ts +3 -0
  129. package/lib/typescript/module/ui/components/supervision/presentation.d.ts.map +1 -0
  130. package/lib/typescript/module/ui/hooks/queries/queryKeys.d.ts +2 -0
  131. package/lib/typescript/module/ui/hooks/queries/queryKeys.d.ts.map +1 -1
  132. package/lib/typescript/module/ui/hooks/queries/useFileQueries.d.ts +22 -6
  133. package/lib/typescript/module/ui/hooks/queries/useFileQueries.d.ts.map +1 -1
  134. package/lib/typescript/module/ui/hooks/queries/useSupervision.d.ts +475 -0
  135. package/lib/typescript/module/ui/hooks/queries/useSupervision.d.ts.map +1 -0
  136. package/lib/typescript/module/ui/icons/Ionicons.d.ts +1 -1
  137. package/lib/typescript/module/ui/icons/Ionicons.d.ts.map +1 -1
  138. package/lib/typescript/module/ui/icons/MaterialCommunityIcons.d.ts +1 -1
  139. package/lib/typescript/module/ui/icons/MaterialCommunityIcons.d.ts.map +1 -1
  140. package/lib/typescript/module/ui/icons/subsetGlyphMaps.d.ts +3 -0
  141. package/lib/typescript/module/ui/icons/subsetGlyphMaps.d.ts.map +1 -1
  142. package/lib/typescript/module/ui/index.d.ts +1 -0
  143. package/lib/typescript/module/ui/index.d.ts.map +1 -1
  144. package/lib/typescript/module/ui/navigation/routes.d.ts +1 -1
  145. package/lib/typescript/module/ui/navigation/routes.d.ts.map +1 -1
  146. package/lib/typescript/module/ui/navigation/surfaceRegistry.d.ts +6 -0
  147. package/lib/typescript/module/ui/navigation/surfaceRegistry.d.ts.map +1 -1
  148. package/lib/typescript/module/ui/screens/CreateAccountScreen.d.ts.map +1 -1
  149. package/lib/typescript/module/ui/screens/FileManagementScreen.d.ts.map +1 -1
  150. package/lib/typescript/module/ui/screens/FileTrashScreen.d.ts +14 -0
  151. package/lib/typescript/module/ui/screens/FileTrashScreen.d.ts.map +1 -0
  152. package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  153. package/lib/typescript/module/ui/screens/SupervisionScreen.d.ts +3 -0
  154. package/lib/typescript/module/ui/screens/SupervisionScreen.d.ts.map +1 -0
  155. package/lib/typescript/module/ui/screens/fileManagement/trashActions.d.ts +66 -0
  156. package/lib/typescript/module/ui/screens/fileManagement/trashActions.d.ts.map +1 -0
  157. package/lib/typescript/module/ui/screens/index.d.ts +1 -0
  158. package/lib/typescript/module/ui/screens/index.d.ts.map +1 -1
  159. package/lib/typescript/module/ui/stores/assetStore.d.ts.map +1 -1
  160. package/lib/typescript/module/ui/utils/identityCrypto.d.ts +1 -0
  161. package/lib/typescript/module/ui/utils/identityCrypto.d.ts.map +1 -1
  162. package/package.json +6 -21
  163. package/src/assets/fonts/icons/OxyServicesIonicons.ttf +0 -0
  164. package/src/assets/fonts/icons/OxyServicesMaterialCommunityIcons.ttf +0 -0
  165. package/src/assets/fonts/icons/manifest.json +8 -5
  166. package/src/ui/components/fileManagement/FileViewer.tsx +5 -1
  167. package/src/ui/components/supervision/PersonPicker.tsx +67 -0
  168. package/src/ui/components/supervision/presentation.ts +17 -0
  169. package/src/ui/hooks/queries/__tests__/fileQueries.test.ts +70 -0
  170. package/src/ui/hooks/queries/queryKeys.ts +2 -0
  171. package/src/ui/hooks/queries/useFileQueries.ts +45 -16
  172. package/src/ui/hooks/queries/useSupervision.ts +25 -0
  173. package/src/ui/icons/subsetGlyphMaps.ts +3 -0
  174. package/src/ui/index.ts +2 -0
  175. package/src/ui/navigation/__tests__/getSurfaceConfig.test.ts +9 -0
  176. package/src/ui/navigation/routes.ts +4 -0
  177. package/src/ui/navigation/surfaceRegistry.ts +5 -1
  178. package/src/ui/screens/CreateAccountScreen.tsx +15 -1
  179. package/src/ui/screens/FileManagementScreen.tsx +142 -49
  180. package/src/ui/screens/FileTrashScreen.tsx +228 -0
  181. package/src/ui/screens/ManageAccountScreen.tsx +10 -0
  182. package/src/ui/screens/SupervisionScreen.tsx +593 -0
  183. package/src/ui/screens/fileManagement/__tests__/trashActions.test.ts +177 -0
  184. package/src/ui/screens/fileManagement/trashActions.ts +161 -0
  185. package/src/ui/screens/index.ts +2 -0
  186. package/src/ui/stores/assetStore.ts +24 -13
@@ -0,0 +1,14 @@
1
+ import type React from 'react';
2
+ import type { BaseScreenProps } from '../types/navigation.js';
3
+ /**
4
+ * The person's Trash (ADR 0043 D5): the files they moved to trash, most
5
+ * recently trashed first. Each can be restored — served again, back in the
6
+ * library — or deleted permanently, after a confirmation (and a second one when
7
+ * an app still uses it). An account's trash never expires, so nothing here
8
+ * disappears on its own; it still counts toward the account's storage.
9
+ */
10
+ declare const FileTrashScreen: React.FC<BaseScreenProps & {
11
+ userId?: string;
12
+ }>;
13
+ export default FileTrashScreen;
14
+ //# sourceMappingURL=FileTrashScreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileTrashScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/FileTrashScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAS/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAqB,CAAC;AAa3D;;;;;;GAMG;AACH,QAAA,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAoMpE,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"ManageAccountScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/ManageAccountScreen.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAiB/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAqB,CAAC;AA+C3D;;;;;;;GAOG;AACH,QAAA,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CA8nBlD,CAAC;AAYF,eAAe,mBAAmB,CAAC"}
1
+ {"version":3,"file":"ManageAccountScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/ManageAccountScreen.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAiB/B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAqB,CAAC;AA+C3D;;;;;;;GAOG;AACH,QAAA,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAwoBlD,CAAC;AAYF,eAAe,mBAAmB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { BaseScreenProps } from '../types/navigation.js';
2
+ export default function SupervisionScreen(props: BaseScreenProps): import("react").JSX.Element;
3
+ //# sourceMappingURL=SupervisionScreen.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SupervisionScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/SupervisionScreen.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAqB,CAAC;AAkjB3D,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,KAAK,EAAE,eAAe,+BAO/D"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * What the file manager does when the person removes, restores or deletes a
3
+ * file (ADR 0043 D5). Pure of React and of the UI: every call takes the asset
4
+ * API and the confirmation it may need, so the decisions are testable on their
5
+ * own and the screens only render.
6
+ *
7
+ * - "Delete" in the library MOVES TO TRASH: the file stops being served, is
8
+ * kept, and can be restored from Trash. A `blocked` file (taken down after a
9
+ * content claim, D10) cannot be trashed — it is already served to nobody —
10
+ * so removing it is the permanent delete, which is its owner's to make.
11
+ * - Permanent deletion happens only from Trash (or for a blocked file). The
12
+ * API refuses to delete a file an application still uses (409, with the
13
+ * number of uses); the person is told and decides, and only then is the
14
+ * delete forced.
15
+ */
16
+ import type { FileMetadata } from '@oxy.so/core';
17
+ /** The part of `oxyServices.assets` these actions use. */
18
+ export interface TrashAssetsApi {
19
+ trash(fileId: string): Promise<unknown>;
20
+ restore(fileId: string): Promise<unknown>;
21
+ delete(fileId: string, options?: {
22
+ force?: boolean;
23
+ }): Promise<unknown>;
24
+ }
25
+ /** What removing a file from the library does to it. */
26
+ export type LibraryRemoval = 'trash' | 'delete';
27
+ /** A `blocked` file is deleted (it cannot go to trash); every other is trashed. */
28
+ export declare function libraryRemovalFor(file: Pick<FileMetadata, 'status'>): LibraryRemoval;
29
+ /** The HTTP status of a failed asset call, when it carries one. */
30
+ export declare function errorStatus(error: unknown): number | undefined;
31
+ /**
32
+ * How many uses an application still has of a file the API refused to delete
33
+ * (409, `details.summary.remainingLinks`), or `null` when the refusal is not
34
+ * that one.
35
+ */
36
+ export declare function remainingUses(error: unknown): number | null;
37
+ /** Outcome of {@link deletePermanently}. */
38
+ export type PermanentDeleteOutcome = 'deleted' | 'cancelled' | 'gone';
39
+ /**
40
+ * Delete a file for good. When applications still use it the API refuses;
41
+ * `confirmStillUsed(count)` asks the person, and only a yes forces the delete.
42
+ * A file already gone (404) is `gone` — the caller just refreshes. Any other
43
+ * failure is thrown.
44
+ */
45
+ export declare function deletePermanently(assets: TrashAssetsApi, fileId: string, confirmStillUsed: (uses: number) => Promise<boolean>): Promise<PermanentDeleteOutcome>;
46
+ /** Outcome of {@link restoreFromTrash}. */
47
+ export type RestoreOutcome = 'restored' | 'not_in_trash' | 'gone';
48
+ /**
49
+ * Bring a file back from trash. One that is no longer in trash — restored
50
+ * elsewhere, or blocked after a claim (409 `FILE_NOT_IN_TRASH`) — or no longer
51
+ * exists (404) is reported, not thrown: the trash list is just stale.
52
+ */
53
+ export declare function restoreFromTrash(assets: TrashAssetsApi, fileId: string): Promise<RestoreOutcome>;
54
+ /** Per-file outcome of removing several files from the library. */
55
+ export interface LibraryRemovalResult {
56
+ trashed: string[];
57
+ deleted: string[];
58
+ failed: string[];
59
+ }
60
+ /**
61
+ * Remove several files from the library at once: each goes to trash, except a
62
+ * blocked one, which is deleted (asking about remaining uses as
63
+ * {@link deletePermanently} does). One failure never stops the others.
64
+ */
65
+ export declare function removeFromLibrary(assets: TrashAssetsApi, files: ReadonlyArray<Pick<FileMetadata, 'id' | 'status' | 'filename'>>, confirmStillUsed: (uses: number, filename: string) => Promise<boolean>): Promise<LibraryRemovalResult>;
66
+ //# sourceMappingURL=trashActions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trashActions.d.ts","sourceRoot":"","sources":["../../../../../../src/ui/screens/fileManagement/trashActions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,0DAA0D;AAC1D,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACxC,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACzE;AAED,wDAAwD;AACxD,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEhD,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,GAAG,cAAc,CAEpF;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAQ9D;AAWD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAU3D;AAED,4CAA4C;AAC5C,MAAM,MAAM,sBAAsB,GAAG,SAAS,GAAG,WAAW,GAAG,MAAM,CAAC;AAEtE;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GACnD,OAAO,CAAC,sBAAsB,CAAC,CAYjC;AAED,2CAA2C;AAC3C,MAAM,MAAM,cAAc,GAAG,UAAU,GAAG,cAAc,GAAG,MAAM,CAAC;AAElE;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,cAAc,EACtB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,cAAc,CAAC,CAWzB;AAED,mEAAmE;AACnE,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,aAAa,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,GAAG,QAAQ,GAAG,UAAU,CAAC,CAAC,EACtE,gBAAgB,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GACrE,OAAO,CAAC,oBAAoB,CAAC,CAwB/B"}
@@ -15,4 +15,5 @@ export { default as ConnectedAppsScreen } from './ConnectedAppsScreen.js';
15
15
  export { default as CreateAccountScreen } from './CreateAccountScreen.js';
16
16
  export { default as AccountMembersScreen } from './AccountMembersScreen.js';
17
17
  export { default as AccountSettingsScreen } from './AccountSettingsScreen.js';
18
+ export { default as SupervisionScreen } from './SupervisionScreen.js';
18
19
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,oBAAiB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,0BAAuB,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,0BAAuB,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,wBAAqB,CAAC;AACnE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,0BAAuB,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,0BAAuB,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,2BAAwB,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,4BAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,oBAAiB,CAAC;AAC3D,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,0BAAuB,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,0BAAuB,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,wBAAqB,CAAC;AACnE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,0BAAuB,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,0BAAuB,CAAC;AACvE,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,2BAAwB,CAAC;AACzE,OAAO,EAAE,OAAO,IAAI,qBAAqB,EAAE,MAAM,4BAAyB,CAAC;AAE3E,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,wBAAqB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"assetStore.d.ts","sourceRoot":"","sources":["../../../../../src/ui/stores/assetStore.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"assetStore.d.ts","sourceRoot":"","sources":["../../../../../src/ui/stores/assetStore.ts"],"names":[],"mappings":"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"}
@@ -35,6 +35,7 @@ export declare const loadIdentityCrypto: () => Promise<{
35
35
  signIdentityProof: typeof import("@oxy.so/core/crypto").signIdentityProof;
36
36
  deriveIdentityLinkCode: typeof import("@oxy.so/core/crypto").deriveIdentityLinkCode;
37
37
  solveRegistrationPow: typeof import("@oxy.so/core/crypto").solveRegistrationPow;
38
+ createContentHasher: typeof import("@oxy.so/core/crypto").createContentHasher;
38
39
  canonicalize: typeof import("@oxy.so/protocol").canonicalize;
39
40
  loadCommonsIdentityBridge: typeof import("@oxy.so/protocol").loadCommonsIdentityBridge;
40
41
  signMessage: typeof import("@oxy.so/protocol").signMessage;
@@ -1 +1 @@
1
- {"version":3,"file":"identityCrypto.d.ts","sourceRoot":"","sources":["../../../../../src/ui/utils/identityCrypto.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAsC,CAAC"}
1
+ {"version":3,"file":"identityCrypto.d.ts","sourceRoot":"","sources":["../../../../../src/ui/utils/identityCrypto.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAsC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxy.so/services",
3
- "version": "11.6.0",
3
+ "version": "11.9.0",
4
4
  "description": "OxyHQ Expo/React Native SDK — UI components, screens, and native features",
5
5
  "main": "lib/commonjs/index.js",
6
6
  "module": "lib/module/index.js",
@@ -111,7 +111,7 @@
111
111
  ],
112
112
  "repository": {
113
113
  "type": "git",
114
- "url": "https://github.com/oxyhq/sdk",
114
+ "url": "git+https://github.com/OxyHQ/oxy.git",
115
115
  "directory": "packages/services"
116
116
  },
117
117
  "author": "OxyHQ",
@@ -136,33 +136,18 @@
136
136
  "copy-dts": "copyfiles -u 1 \"src/**/*.d.ts\" lib/typescript",
137
137
  "delete-debug-view": "rm -rf ./lib/commonjs/components/bottomSheetDebugView ./lib/module/components/bottomSheetDebugView ./lib/typescript/components/bottomSheetDebugView || true",
138
138
  "delete-dts.js": "find ./lib/commonjs -name '*.d.js*' -delete && find ./lib/module -name '*.d.js*' -delete",
139
- "release": "rm -rf lib && bun run build && release-it",
140
139
  "prepublishOnly": "node ../../scripts/assert-bun-publish.mjs && bun run typescript && bun run test && bun run build"
141
140
  },
142
- "release-it": {
143
- "git": {
144
- "tagName": "@oxy.so/services@${version}",
145
- "tagAnnotation": "Release @oxy.so/services@${version}",
146
- "commitMessage": "chore(services): release @oxy.so/services@${version}"
147
- },
148
- "github": {
149
- "release": true,
150
- "releaseName": "@oxy.so/services@${version}"
151
- },
152
- "npm": {
153
- "publish": true
154
- }
155
- },
156
141
  "dependencies": {
157
142
  "@expo/config-plugins": "57.0.9",
158
- "@oxy.so/contracts": "4.17.0",
143
+ "@oxy.so/contracts": "^4.22.0",
159
144
  "color": "^5.0.3"
160
145
  },
161
146
  "devDependencies": {
162
147
  "@commitlint/cli": "^21.2.1",
163
148
  "@commitlint/config-conventional": "^21.2.0",
164
149
  "@expo/vector-icons": "^15.0.3",
165
- "@oxy.so/core": "4.13.0",
150
+ "@oxy.so/core": "4.18.0",
166
151
  "@react-native-async-storage/async-storage": "^2.0.0",
167
152
  "@react-native-community/netinfo": "^12.0.1",
168
153
  "@react-native/babel-preset": "^0.86.2",
@@ -205,17 +190,17 @@
205
190
  "react-native-reanimated": "4.5.0",
206
191
  "react-native-safe-area-context": "~5.8.0",
207
192
  "react-native-svg": "15.15.5",
208
- "release-it": "^19.0.6",
209
193
  "socket.io-client": "^4.8.1",
210
194
  "ts-jest": "^29.4.12",
211
195
  "typescript": "^5.9.2",
212
196
  "zustand": "^5.0.14"
213
197
  },
214
198
  "//@oxy.so/bloom": "RE-RAISE THIS FLOOR ON EVERY BREAKING BLOOM RELEASE, in the same commit as the root package.json catalog entry and the code that requires it. The breaking position is the MAJOR, so `^3.0.1` means `>=3.0.1 <4.0.0`: 3.x minors are admitted on semver's additive promise, and Bloom 4.0.0 is refused until someone raises this deliberately. The CAP is the part that is load-bearing. An earlier revision of this key recorded the opposite trade -- an uncapped `>=` floor, accepted so that intentionally-breaking Bloom 0.x minors would not be blocked -- and that trade is closed by evidence rather than by preference: an unbounded range is exactly what let `bun install` pair this package with Bloom 1.0.0 and emit no warning at all, and 1.0.0 broke it four ways (a deleted provider, a renamed confirm option, a renamed Chip fill, and two REMOVED SUBPATHS that fail at bundle time, before any typecheck runs). A floor is a claim about what was measured; a cap is the claim that nothing beyond it was. RAISED TO 3.0.1 from `^2.1.0`. Bloom 3.0.0 breaks exactly two things -- `PageHeader` defaults to `presentation=\"floating\"` and stops hiding the title under `transparent`, and `Field disabled` now reaches the control that reads the field context -- and THIS PACKAGE IMPORTS NEITHER: it renders no `PageHeader` and no `Field`, and 3.0 removes no subpath (unlike 2.0.0, which is why that floor cost code changes and this one does not). Its six `transparent` occurrences are CSS colour values, not the PageHeader prop. The cap had to move rather than widen to a union, because leaving `^2.1.0` in place is what made `bun install` resolve a SECOND, nested Bloom 2.12.4 under this package for any app on Bloom 3 -- two copies of a library whose 3.0 contracts (`control-surface`, `TopEdgeProvider`, `ScrollOffsetProvider`) are React contexts, so a provider from one copy cannot be read by a consumer from the other. Mention's `oxyRuntimeCompatibility` test is what caught it; nothing in a typecheck can. RAISED AGAIN TO 3.2.0 from `^3.0.1`, for the same class of reason the 2.x note records, only in the other direction: 3.2.0 ADDS the per-glyph icon subpaths (`@oxy.so/bloom/icons/RiAtLine`) that this package's screens now import instead of the `@oxy.so/bloom/icons` barrel, and a missing subpath fails at bundle time, in the consumer's Metro, long after this package has typechecked and shipped. `^3.0.1` would have admitted Bloom 3.0.1 and 3.1.0, neither of which has those subpaths, so the floor is the only thing standing between a consumer and a red build. Nothing else about 3.1.0 or 3.2.0 is required here; the cap stays at the major. RAISED TO ^4.2.0: FollowButton now delegates its visuals to Bloom media-header FollowButton with loading, textStyle and large size; the new shared UI contracts require one Bloom4 context across Services and its consumer. RAISED TO ^4.31.0: the sign-in and account screens type one-time codes into `InputOtp` with `type=\"alphanumeric\"` (the long sign-in code and backup codes), which 4.31.0 adds; older 4.x drops the letters. RAISED TO ^4.35.0: every password field passes `revealable` to `TextFieldInput` (the eye button, 4.35.0); older 4.x drops the prop silently and the password cannot be shown. The provider also mounts `@oxy.so/bloom/locale` (4.32.0+). RAISED TO ^5.1.0 (services 9.0.0, a major because consumers must move to Bloom 5 with it): Bloom 5.0.0 types `Card`'s `style` without radius, border width or `overflow` (geometry goes through `radius`/`border`/`clipContent`) and stops clipping a Card's children by default, so `BenefitList`'s `overflow: 'visible'` became both a type error and unnecessary; it is removed. The cap MOVES rather than widening to a `^4 || ^5` union, for the reason the 3.0.1 note records: a union lets an app resolve a second, nested Bloom copy and split the React contexts. The floor is 5.1.0 because that is the version measured here (every package builds and tests against it); 5.0.0 was not measured. RAISED TO ^6.0.0 (services 10.0.0, a major because consumers must move to Bloom 6 with it, and because this package's own `FollowButton`/`FollowTargetButton` `size` moves with Bloom's vocabulary): Bloom 6.0.0 removes the duplicate spellings its 5.x types still admitted, and this package used four of them. The control `size` narrows to `xs|sm|md|lg`, so every `small`/`medium`/`large` handed to a Bloom control became `sm`/`md`/`lg`, and the Follow buttons' public `size` became `sm|md|lg` because it is passed straight through to Bloom's media-header `FollowButton`. `Switch` is controlled by `checked`/`onCheckedChange`, not `value`/`onValueChange`. `Button` has no `variant`: each call site names `appearance` and `tone` (the pair the 5.x recipe resolved the variant to, so nothing repaints), `LinkButton`'s colour is `linkTone`, and `PeableButton` renders `InverseButton`. `Card` takes `appearance=\"outline\"` for `variant=\"outlined\"`. The deprecated spellings Bloom 6 still accepts (`isInvalid`, Chip `color`/`variant`) are not breaks and are left alone. The cap MOVES rather than widening to a `^5 || ^6` union, for the reason the 3.0.1 note records: a union lets an app resolve a second, nested Bloom copy and split the React contexts. The floor is 6.0.0 because that is the version measured when this raise was made; the workspace catalog has since moved to ^6.2.0, which adds only the `cover-header` subpath this package does not import, so the floor stays. MAINTENANCE 6.2.1: floor >=6.2.1 and cap <6.3.0 deliberately admit only the reviewed patch line with native Back/X completion and SVG paint/resize fixes. Known 6.4.0 lacks these fixes; the exact root catalog pin prevents a caret from selecting it. A broader minor range requires forward-port and consumer acceptance. VERIFIED 7.1.2: the additional >=7.1.2 <7.2.0 line contains the reviewed native fixes. Services build/types and the website real browser provider/theme tests pass with one byte-verified Bloom copy at both the root and Services importer. The root catalog remains pinned to 6.2.1; consumers explicitly choose one supported line. Versions 6.3.x, 6.4.x and 7.1.0/7.1.1 remain excluded. VERIFIED 7.7.0: admit the progressive media-preview release as another explicit line, so consumers selecting it share one Bloom provider/theme/font context with Services. Existing supported lines and the workspace catalog stay unchanged; unreviewed 7.2-7.6 and 7.8+ remain excluded. VERIFIED 7.13.1: admit the accessible bottom-sheet dialog release so consumers selecting this line share Bloom surface, theme and overlay contexts with Services. Stable Services 11.1.1 validates the unchanged 11.1.0 source against 7.13.1 with 1040 tests, types and packed exports; the existing catalog and other supported peer lines stay unchanged. VERIFIED 7.14.0: the additive outlined Stepper release is covered by Services build, types and 1040 tests against the published package on the 11.1 maintenance branch. VERIFIED 7.15.0: additive Button focus, hover and keyboard events; the stable maintenance line passes types and all 1040 tests against the official package, preserving the existing peer lines. VERIFIED 7.16.1: the stable 11.1 maintenance line passes types and all 1040 tests against the official Accordion, rating and Dialog release; packed exports are verified. Preserve every existing peer line. VERIFIED 7.17.0: Services 11.1.5 maintenance types, 1040 tests, fresh build and packed exports pass against the official additive Carousel/Search and dialog-focus release. Preserve the existing catalog and peer lines on main. VERIFIED 7.18/7.19: the 11.1 maintenance line passed types and 1040 tests separately against both official releases; this main line passed types and all 1042 tests against 7.19.0 after building its workspace dependencies. The root catalog remains 6.2.1; apps choose one admitted line. VERIFIED 7.20.0: additive viewport observation, opt-in Meter/RatingBar reveal and Dialog minimum side gutter; Services types and all 1042 tests pass against the release candidate tarball. Existing peer lines and the workspace catalog remain unchanged. VERIFIED 7.21.0: configurable Dialog/BottomSheet backdrop and transition preserve defaults; this main line passes types and all 1042 tests against the byte-verified release candidate. Existing supported peer lines and the workspace catalog remain unchanged. VERIFIED 7.22.0: controlled Collapsible and rich RadioGroup composition preserve Services compatibility; maintenance Services types and all 1040 tests pass against the release candidate, with unchanged 11.1.0 runtime source. Mercaria validates the composed purchase panels in eight browser scenarios and all four client typechecks. VERIFIED 7.27.0: exact ColorScope roles, local mode and portal propagation preserve Services defaults. This main line passes types and all 114 suites / 1042 tests against the official 7.27.0 package with a single Bloom resolution. Stable 11.1.13 maintenance also passes types and all 113 suites / 1040 tests. Preserve the existing main catalog and earlier admitted peer lines. VERIFIED 7.28.0: types and all 114 suites / 1042 tests pass with the official CSS 3.1.0-rc.0 / NativeWind 5.0.0-rc.0 compiler pair. Maintenance also verifies Expo 56.0.23 and RN 0.85.3; no runtime source or framework peer changes are required. VERIFIED 7.29.0: TypeScript and all 114 suites / 1042 tests pass with the paired NativeWind 5.0.0-rc.0 and react-native-css 3.1.0-rc.0. Optional gallery lifecycle callback preserves existing surface behavior; runtime source unchanged. VERIFIED 7.30.0: TypeScript and all 114 suites / 1042 tests pass against the video-overlay release candidate with one Bloom runtime; existing framework catalog and runtime source stay unchanged. VERIFIED 7.31.0: TypeScript and all 114 suites / 1042 tests pass against the official 7.31.0 package with one Bloom runtime. It adds the `video-view` subpath (expo-video's VideoView with `playsInline` on, so web video plays inline on iPhone Safari) and routes MediaSurface through it; this package imports neither, and runtime source and framework catalog stay unchanged. VERIFIED 7.32.0 AND 7.33.0 (11.2.0-oxy-one.4): each official package installed as the one Bloom resolution; types and all 115 suites / 1050 tests pass against both (and against the 6.2.1 catalog). 7.32.0 adds the shared agent-avatar renderer and Clippo; 7.33.0 adds the lean `settings-modal/modal` and `settings-modal/fields` entries. Both are additive (no subpath removed, no peer or dependency changed) and this package imports neither family. The cap moves to <7.34.0 so a 7.33 patch (7.33.1 restores web TextField side padding) needs no services release. The root catalog stays 6.2.1. Same verification and fix as maintenance 11.1.18. VERIFIED 8.0.0 (11.2.0-oxy-one.4): types and all 115 suites / 1050 tests pass with 8.0.0 as the one Bloom resolution. Its only break is that `LinkPreviewCard` leaves the root barrel for `@oxy.so/bloom/link-preview` (its cover now loads through `expo-image`, which the root barrel must not link); this package imports neither. The 8.0 line is admitted beside 7.x, so an app moves to Bloom 8 without a services major. VERIFIED 8.1.1 AND 9.0.0 (11.2.0-oxy-one.5): each installed as the one Bloom resolution (8.1.1 from the registry, 9.0.0 from the packed release candidate); types and all 115 suites / 1050 tests pass against both, and against the 6.2.1 catalog. 8.1.x adds the unified agent-avatar renderer and changes nothing this package imports. 9.0.0 removes the `small` / `medium` / `large` spellings from control sizes (Chip, Badge, Sidebar, Rating and others), renames `AlertDialog` / `Command` `visible` + `onClose` to `open` + `onOpenChange`, replaces the composer's `listening` with `voiceState`, and swaps the glass material for blur and tint; this package used one of those, Chip `size=\"small\"` (three screens), now `sm`, which every admitted line accepts. The 8.1 minor joins the 8.0 line (one 8.x range) and the 9.0 line is admitted beside the earlier ones. The root catalog stays 6.2.1. VERIFIED 10.0.0 (11.2.0-oxy-one.7): installed from the registry as the one Bloom resolution; types and all 115 suites / 1050 tests pass. 10.0.0 makes an avatar one flat `AvatarCharacter` and removes `AvatarConfig` with its constants from `@oxy.so/bloom/agent-avatar`; this package imports nothing from that family, so nothing here changes. The 10.0 line is admitted beside the earlier ones. The root catalog stays 6.2.1.",
199
+ "//@oxy.so/core": "The core peer is the root catalog's `^4.18.0` (>=4.18.0 <5.0.0), and contracts is a `workspace:^` dependency (packed as ^<its version>). Both were EXACT pins: core since the Oxy One prerelease (4.5.0-oxy-one.0, which a caret range could not admit) and contracts by `workspace:*`; the reason left with the prerelease, and an exact pin made every core or contracts minor a peer conflict or a second nested copy in each app until services was republished. The FLOOR is the core this package is built and tested against and needs (4.18.0: `assets.list({ status: 'trash' })`, `FileMetadata.trashedAt`, `AssetLiveStatus`); raise it, in the same commit, to the first core a change here requires. The CAP is the major: core 4.x minors are admitted on semver's additive promise, and core 5.0.0 is refused until it is measured here, because a second core copy splits the one OxyServices instance and session an app shares with this package.",
215
200
  "peerDependencies": {
216
201
  "@expo/vector-icons": "^15.0.3",
217
202
  "@oxy.so/bloom": ">=6.2.1 <6.3.0 || >=7.1.2 <7.2.0 || >=7.7.0 <7.8.0 || >=7.13.1 <7.34.0 || >=8.0.0 <8.2.0 || >=9.0.0 <9.1.0 || >=10.0.0",
218
- "@oxy.so/core": "4.13.0",
203
+ "@oxy.so/core": "^4.18.0",
219
204
  "@react-native-async-storage/async-storage": "^2.0.0",
220
205
  "@react-native-community/netinfo": ">=11.4.1 <13.0.0",
221
206
  "@tanstack/query-async-storage-persister": "^5.101",
@@ -5,8 +5,8 @@
5
5
  "ionicons": {
6
6
  "fontFamily": "OxyServicesIonicons",
7
7
  "file": "src/assets/fonts/icons/OxyServicesIonicons.ttf",
8
- "bytes": 43004,
9
- "sha256": "367d1eb46c64097ace34b793d7fbff9257c0da191d8cab73329cfe8999e95611",
8
+ "bytes": 43160,
9
+ "sha256": "c062679623ae08f1fb0231729c1f9efae97044e35ffe51f7c0544f866cb2f959",
10
10
  "names": [
11
11
  "add",
12
12
  "add-circle-outline",
@@ -18,6 +18,7 @@
18
18
  "arrow-back",
19
19
  "arrow-down",
20
20
  "arrow-forward",
21
+ "arrow-undo",
21
22
  "arrow-up",
22
23
  "at",
23
24
  "briefcase-outline",
@@ -151,8 +152,8 @@
151
152
  "materialCommunityIcons": {
152
153
  "fontFamily": "OxyServicesMaterialCommunityIcons",
153
154
  "file": "src/assets/fonts/icons/OxyServicesMaterialCommunityIcons.ttf",
154
- "bytes": 28852,
155
- "sha256": "844252d83e5510b012333218db9e16cc997164360d1ab4f24148c3ca384ab740",
155
+ "bytes": 29224,
156
+ "sha256": "c7fdc975626c395ee2b1d0c462ae8dab6f800935bb64739d2d07ea4a30da51d0",
156
157
  "names": [
157
158
  "account",
158
159
  "account-circle",
@@ -213,6 +214,7 @@
213
214
  "code-tags",
214
215
  "cog",
215
216
  "cog-outline",
217
+ "contacts",
216
218
  "contain",
217
219
  "content-copy",
218
220
  "controller",
@@ -220,6 +222,7 @@
220
222
  "credit-card",
221
223
  "cube-outline",
222
224
  "database-outline",
225
+ "decimal",
223
226
  "delete",
224
227
  "delete-outline",
225
228
  "devices",
@@ -349,5 +352,5 @@
349
352
  }
350
353
  },
351
354
  "glyphMapsFile": "src/ui/icons/subsetGlyphMaps.ts",
352
- "glyphMapsSha256": "25d2d86d08ea7238dfe49210cf98754ffcc60fefbe5b8ad812e13c2d3239948f"
355
+ "glyphMapsSha256": "1f2e6005461383abb6c5443981341e8ae716110eb6de6590f8a3caa4cfe614b0"
353
356
  }
@@ -18,7 +18,10 @@ interface FileViewerProps {
18
18
  onToggleDetails: () => void;
19
19
  onClose: () => void;
20
20
  onDownload: (fileId: string, filename: string) => void;
21
+ /** Removes the file from the library: to trash, or for good if it is blocked. */
21
22
  onDelete: (fileId: string, filename: string) => void;
23
+ /** The remove button's label — "Move to trash", or "Delete" for a blocked file. */
24
+ deleteLabel: string;
22
25
  isOwner: boolean;
23
26
  }
24
27
 
@@ -55,6 +58,7 @@ export const FileViewer: React.FC<FileViewerProps> = ({
55
58
  onClose,
56
59
  onDownload,
57
60
  onDelete,
61
+ deleteLabel,
58
62
  isOwner,
59
63
  }) => {
60
64
  const { colors } = useTheme();
@@ -395,7 +399,7 @@ export const FileViewer: React.FC<FileViewerProps> = ({
395
399
  onDelete(file.id, file.filename);
396
400
  }}
397
401
  >
398
- Delete
402
+ {deleteLabel}
399
403
  </Button>
400
404
  </View>
401
405
  )}
@@ -0,0 +1,67 @@
1
+ import { useState } from 'react';
2
+ import { View } from 'react-native';
3
+ import { useQuery } from '@tanstack/react-query';
4
+ import { Button } from '@oxy.so/bloom/button';
5
+ import { Text } from '@oxy.so/bloom/typography';
6
+ import type { SafetyPerson } from '@oxy.so/contracts';
7
+ import { useOxy } from '../../context/OxyContext';
8
+ import { useI18n } from '../../hooks/useI18n';
9
+ import { AccountFlowField, AccountFlowNote } from '../signIn/accountFlowParts';
10
+ export function PersonPicker({
11
+ onSelect,
12
+ exclude = [],
13
+ }: {
14
+ onSelect: (person: SafetyPerson) => void;
15
+ exclude?: string[];
16
+ }) {
17
+ const { oxyServices, user } = useOxy(),
18
+ { t } = useI18n();
19
+ const [text, setText] = useState(''),
20
+ [query, setQuery] = useState('');
21
+ const results = useQuery({
22
+ queryKey: ['oxy', 'safety', 'people', user?.id, query],
23
+ queryFn: () => oxyServices.safety.people({ query }),
24
+ enabled: query.length >= 2,
25
+ staleTime: 0,
26
+ gcTime: 0,
27
+ retry: false,
28
+ });
29
+ return (
30
+ <View style={{ gap: 12 }}>
31
+ <AccountFlowNote>{t('supervision.exactHandleHint')}</AccountFlowNote>
32
+ <AccountFlowField
33
+ label={t('supervision.searchLabel')}
34
+ value={text}
35
+ onChange={setText}
36
+ onSubmit={() => setQuery(text.trim().replace(/^@/, ''))}
37
+ error={null}
38
+ testID="supervision-person-query"
39
+ />
40
+ <Button
41
+ onPress={() => setQuery(text.trim().replace(/^@/, ''))}
42
+ disabled={text.trim().length < 2}
43
+ loading={results.isFetching}
44
+ >
45
+ {t('supervision.search')}
46
+ </Button>
47
+ {results.isError ? (
48
+ <AccountFlowNote>{t('supervision.loadError')}</AccountFlowNote>
49
+ ) : (
50
+ results.data?.items
51
+ .filter((person) => !exclude.includes(person.accountId))
52
+ .map((person) => (
53
+ <Button
54
+ key={person.accountId}
55
+ appearance="plain"
56
+ onPress={() => onSelect(person)}
57
+ testID={`supervision-person-${person.accountId}`}
58
+ >
59
+ {person.displayName ?? person.username ?? t('supervision.account')}{' '}
60
+ {person.username ? `@${person.username}` : ''}
61
+ </Button>
62
+ ))
63
+ )}
64
+ {results.data?.items.length === 0 ? <Text>{t('supervision.noPeople')}</Text> : null}
65
+ </View>
66
+ );
67
+ }
@@ -0,0 +1,17 @@
1
+ /** Format integer authorization evidence without rounding it through a floating-point division. */
2
+ export function formatApprovalAmount(minor: number, currency: string, locale: string): string {
3
+ const digits =
4
+ new Intl.NumberFormat(locale, { style: 'currency', currency }).resolvedOptions()
5
+ .maximumFractionDigits ?? 2;
6
+ const value = BigInt(minor),
7
+ absolute = value < 0n ? -value : value,
8
+ scale = 10n ** BigInt(digits);
9
+ const whole = new Intl.NumberFormat(locale, { maximumFractionDigits: 0 }).format(
10
+ absolute / scale,
11
+ );
12
+ const decimal =
13
+ new Intl.NumberFormat(locale).formatToParts(1.1).find((part) => part.type === 'decimal')
14
+ ?.value ?? '.';
15
+ const fraction = digits ? `${decimal}${(absolute % scale).toString().padStart(digits, '0')}` : '';
16
+ return `${value < 0n ? '-' : ''}${whole}${fraction} ${currency}`;
17
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * The file library's page mapping and cache helpers for the Trash view (ADR
3
+ * 0043 D5): a trashed file keeps its `trashedAt`, and the library and the
4
+ * trash are separate cache entries under one `files` root.
5
+ */
6
+ import { QueryClient } from '@tanstack/react-query';
7
+ import { queryKeys } from '../queryKeys';
8
+ import {
9
+ mapRawFileToMetadata,
10
+ removeFileFromCache,
11
+ toUserFilesPage,
12
+ type UserFilesInfinite,
13
+ } from '../useFileQueries';
14
+
15
+ jest.mock('../../../context/OxyContext', () => ({ useOxy: () => ({}) }));
16
+
17
+ const page = (ids: string[]): UserFilesInfinite => ({
18
+ pages: [
19
+ {
20
+ files: ids.map((id) => mapRawFileToMetadata({ id, originalName: `${id}.png` })),
21
+ total: ids.length,
22
+ hasMore: false,
23
+ nextOffset: 40,
24
+ },
25
+ ],
26
+ pageParams: [0],
27
+ });
28
+
29
+ describe('mapRawFileToMetadata', () => {
30
+ it('keeps the status and when the file went to trash', () => {
31
+ const file = mapRawFileToMetadata({
32
+ id: 'f',
33
+ originalName: 'f.png',
34
+ status: 'trash',
35
+ trashedAt: '2026-10-16T10:00:00.000Z',
36
+ });
37
+ expect(file).toMatchObject({ status: 'trash', trashedAt: '2026-10-16T10:00:00.000Z' });
38
+ expect(mapRawFileToMetadata({ id: 'g', trashedAt: null })).not.toHaveProperty('trashedAt');
39
+ });
40
+ });
41
+
42
+ describe('toUserFilesPage', () => {
43
+ it('maps a page and where the next one starts', () => {
44
+ const mapped = toUserFilesPage({ files: [{ id: 'a' }], total: 41, hasMore: true }, 0);
45
+ expect(mapped).toMatchObject({ total: 41, hasMore: true, nextOffset: 40 });
46
+ expect(mapped.files.map((file) => file.id)).toEqual(['a']);
47
+ });
48
+ });
49
+
50
+ describe('the trash cache', () => {
51
+ it('is its own entry under files.all, and removal targets the list it names', () => {
52
+ expect(queryKeys.files.trash('u').slice(0, 1)).toEqual([...queryKeys.files.all]);
53
+ expect(queryKeys.files.trash('u')).not.toEqual(queryKeys.files.list('u'));
54
+
55
+ const client = new QueryClient();
56
+ client.setQueryData(queryKeys.files.list('u'), page(['a', 'b']));
57
+ client.setQueryData(queryKeys.files.trash('u'), page(['b', 't']));
58
+
59
+ removeFileFromCache(client, 'u', 'b', 'trash');
60
+ const ids = (key: readonly unknown[]) =>
61
+ client
62
+ .getQueryData<UserFilesInfinite>(key)
63
+ ?.pages.flatMap((p) => p.files.map((file) => file.id));
64
+ expect(ids(queryKeys.files.trash('u'))).toEqual(['t']);
65
+ expect(ids(queryKeys.files.list('u'))).toEqual(['a', 'b']);
66
+
67
+ removeFileFromCache(client, 'u', 'a');
68
+ expect(ids(queryKeys.files.list('u'))).toEqual(['b']);
69
+ });
70
+ });
@@ -113,6 +113,8 @@ export const queryKeys = {
113
113
  files: {
114
114
  all: ['files'] as const,
115
115
  list: (ownerId?: string) => [...queryKeys.files.all, 'list', ownerId || 'anonymous'] as const,
116
+ /** The owner's trash (ADR 0043 D5) — under `files.all`, so one invalidation covers both. */
117
+ trash: (ownerId?: string) => [...queryKeys.files.all, 'trash', ownerId || 'anonymous'] as const,
116
118
  },
117
119
 
118
120
  // Connected apps (OAuth grants the user has authorized)
@@ -27,6 +27,12 @@ export interface RawUserFile {
27
27
  createdAt?: string;
28
28
  metadata?: Record<string, unknown>;
29
29
  variants?: unknown[];
30
+ /** Whether any application uses the file (ADR 0043 D5). */
31
+ inUse?: boolean;
32
+ /** `blocked`: taken down after a content claim (ADR 0043 D10). */
33
+ status?: string;
34
+ /** When the owner moved it to trash (ADR 0043 D5). */
35
+ trashedAt?: string | null;
30
36
  }
31
37
 
32
38
  /** One page of the infinite file list. */
@@ -48,31 +54,52 @@ export function mapRawFileToMetadata(raw: RawUserFile): FileMetadata {
48
54
  length: raw.size ?? 0,
49
55
  chunkSize: 0,
50
56
  uploadDate: raw.createdAt ?? '',
57
+ ...(typeof raw.inUse === 'boolean' ? { inUse: raw.inUse } : {}),
58
+ ...(raw.status === 'active' || raw.status === 'trash' || raw.status === 'blocked'
59
+ ? { status: raw.status }
60
+ : {}),
61
+ ...(typeof raw.trashedAt === 'string' ? { trashedAt: raw.trashedAt } : {}),
51
62
  metadata: raw.metadata ?? {},
52
63
  variants: (raw.variants ?? []) as FileMetadata['variants'],
53
64
  };
54
65
  }
55
66
 
67
+ /** Which of the owner's files a page lists: the library, or the trash (ADR 0043 D5). */
68
+ export type UserFilesListing = 'library' | 'trash';
69
+
70
+ /** Map one `oxyServices.assets.list` response onto a page. */
71
+ export function toUserFilesPage(
72
+ response: { files?: unknown[]; total?: number; hasMore?: boolean },
73
+ offset: number,
74
+ ): UserFilesPage {
75
+ const files = ((response.files ?? []) as RawUserFile[]).map(mapRawFileToMetadata);
76
+ return {
77
+ files,
78
+ total: response.total ?? offset + files.length,
79
+ hasMore: Boolean(response.hasMore),
80
+ nextOffset: offset + FILES_PAGE_SIZE,
81
+ };
82
+ }
83
+
56
84
  /**
57
- * Infinite-paginated list of the owner's files. Fires on mount and whenever
58
- * `ownerId` changes (a new key); `staleTime: 0` reloads on every open. The
59
- * rendered list is `data.pages.flatMap(p => p.files)`.
85
+ * Infinite-paginated list of the owner's files: the LIBRARY (active files, and
86
+ * blocked ones shown as removed after a claim) or, with `listing: 'trash'`,
87
+ * what the owner moved to trash, most recently trashed first. Fires on mount
88
+ * and whenever `ownerId` changes (a new key); `staleTime: 0` reloads on every
89
+ * open. The rendered list is `data.pages.flatMap(p => p.files)`.
60
90
  */
61
- export const useUserFilesInfinite = (ownerId?: string) => {
91
+ export const useUserFilesInfinite = (ownerId?: string, listing: UserFilesListing = 'library') => {
62
92
  const { oxyServices } = useOxy();
63
93
  return useInfiniteQuery<UserFilesPage, Error>({
64
- queryKey: queryKeys.files.list(ownerId),
94
+ queryKey: listing === 'trash' ? queryKeys.files.trash(ownerId) : queryKeys.files.list(ownerId),
65
95
  queryFn: async ({ pageParam }) => {
66
96
  const offset = typeof pageParam === 'number' ? pageParam : 0;
67
- const response = await oxyServices.assets.list({ limit: FILES_PAGE_SIZE, offset });
68
- const raw = (response.files ?? []) as RawUserFile[];
69
- const files = raw.map(mapRawFileToMetadata);
70
- return {
71
- files,
72
- total: response.total ?? offset + files.length,
73
- hasMore: Boolean(response.hasMore),
74
- nextOffset: offset + FILES_PAGE_SIZE,
75
- };
97
+ const response = await oxyServices.assets.list({
98
+ limit: FILES_PAGE_SIZE,
99
+ offset,
100
+ ...(listing === 'trash' ? { status: 'trash' as const } : {}),
101
+ });
102
+ return toUserFilesPage(response, offset);
76
103
  },
77
104
  initialPageParam: 0,
78
105
  getNextPageParam: (lastPage) => (lastPage.hasMore ? lastPage.nextOffset : undefined),
@@ -114,13 +141,15 @@ export function prependFileToCache(
114
141
  });
115
142
  }
116
143
 
117
- /** Remove a file (by id) from every page. */
144
+ /** Remove a file (by id) from every page of the library, or of the trash. */
118
145
  export function removeFileFromCache(
119
146
  queryClient: QueryClient,
120
147
  ownerId: string | undefined,
121
148
  fileId: string,
149
+ listing: UserFilesListing = 'library',
122
150
  ): void {
123
- queryClient.setQueryData<UserFilesInfinite>(fileListKey(ownerId), (data) =>
151
+ const key = listing === 'trash' ? queryKeys.files.trash(ownerId) : fileListKey(ownerId);
152
+ queryClient.setQueryData<UserFilesInfinite>(key, (data) =>
124
153
  data ? mapPages(data, (files) => files.filter((f) => f.id !== fileId)) : data,
125
154
  );
126
155
  }
@@ -0,0 +1,25 @@
1
+ import { useQuery } from '@tanstack/react-query';
2
+ import { useOxy } from '../../context/OxyContext';
3
+ export const supervisionQueryKeys = {
4
+ all: ['oxy', 'safety', 'supervision'] as const,
5
+ account: (id: string, sessionId: string) =>
6
+ ['oxy', 'safety', 'supervision', id, sessionId] as const,
7
+ };
8
+ /** Advisory UI state only. Every read/write still requires the live server policy. */
9
+ export function useSupervision() {
10
+ const { oxyServices, user, isAuthenticated, activeSessionId } = useOxy();
11
+ const result = useQuery({
12
+ queryKey: supervisionQueryKeys.account(user?.id ?? '', activeSessionId ?? ''),
13
+ queryFn: () => oxyServices.safety.supervisionState(),
14
+ enabled: isAuthenticated && !!activeSessionId && user?.kind === 'personal',
15
+ staleTime: 0,
16
+ gcTime: 0,
17
+ refetchOnWindowFocus: 'always',
18
+ refetchOnMount: 'always',
19
+ retry: false,
20
+ });
21
+ return {
22
+ ...result,
23
+ data: result.isFetchedAfterMount && !result.isError ? result.data : undefined,
24
+ };
25
+ }