@oxyhq/services 19.1.3 → 20.0.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 (128) hide show
  1. package/android/build.gradle +21 -0
  2. package/android/src/main/AndroidManifest.xml +10 -0
  3. package/android/src/main/java/so/oxy/identity/OxyIdentityModule.kt +84 -0
  4. package/android/src/main/java/so/oxy/identity/OxyIdentityProvider.kt +77 -0
  5. package/android/src/main/java/so/oxy/identity/OxyIdentityStore.kt +76 -0
  6. package/expo-module.config.json +9 -0
  7. package/ios/OxyIdentity.podspec +28 -0
  8. package/ios/OxyIdentityModule.swift +33 -0
  9. package/lib/commonjs/ui/components/FollowButton.js +1 -2
  10. package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
  11. package/lib/commonjs/ui/components/SettingsIcon.js +1 -2
  12. package/lib/commonjs/ui/components/SettingsIcon.js.map +1 -1
  13. package/lib/commonjs/ui/components/logo/LogoIcon.js +0 -2
  14. package/lib/commonjs/ui/components/logo/LogoIcon.js.map +1 -1
  15. package/lib/commonjs/ui/components/logo/LogoText.js +0 -2
  16. package/lib/commonjs/ui/components/logo/LogoText.js.map +1 -1
  17. package/lib/commonjs/ui/context/OxyContext.js +9 -8
  18. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  19. package/lib/commonjs/ui/context/hooks/useAuthOperations.js +1 -3
  20. package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
  21. package/lib/commonjs/ui/hooks/useLanguageManagement.js +109 -28
  22. package/lib/commonjs/ui/hooks/useLanguageManagement.js.map +1 -1
  23. package/lib/commonjs/ui/hooks/useSessionManagement.js +1 -3
  24. package/lib/commonjs/ui/hooks/useSessionManagement.js.map +1 -1
  25. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +151 -88
  26. package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
  27. package/lib/commonjs/ui/screens/PreferencesScreen.js +5 -6
  28. package/lib/commonjs/ui/screens/PreferencesScreen.js.map +1 -1
  29. package/lib/module/ui/components/FollowButton.js +1 -1
  30. package/lib/module/ui/components/FollowButton.js.map +1 -1
  31. package/lib/module/ui/components/SettingsIcon.js +1 -1
  32. package/lib/module/ui/components/SettingsIcon.js.map +1 -1
  33. package/lib/module/ui/components/logo/LogoIcon.js +0 -1
  34. package/lib/module/ui/components/logo/LogoIcon.js.map +1 -1
  35. package/lib/module/ui/components/logo/LogoText.js +0 -1
  36. package/lib/module/ui/components/logo/LogoText.js.map +1 -1
  37. package/lib/module/ui/context/OxyContext.js +9 -8
  38. package/lib/module/ui/context/OxyContext.js.map +1 -1
  39. package/lib/module/ui/context/hooks/useAuthOperations.js +1 -3
  40. package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
  41. package/lib/module/ui/hooks/useLanguageManagement.js +107 -29
  42. package/lib/module/ui/hooks/useLanguageManagement.js.map +1 -1
  43. package/lib/module/ui/hooks/useSessionManagement.js +1 -3
  44. package/lib/module/ui/hooks/useSessionManagement.js.map +1 -1
  45. package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
  46. package/lib/module/ui/screens/LanguageSelectorScreen.js +153 -91
  47. package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
  48. package/lib/module/ui/screens/PreferencesScreen.js +5 -6
  49. package/lib/module/ui/screens/PreferencesScreen.js.map +1 -1
  50. package/lib/typescript/commonjs/ui/components/FollowButton.d.ts +2 -2
  51. package/lib/typescript/commonjs/ui/components/FollowButton.d.ts.map +1 -1
  52. package/lib/typescript/commonjs/ui/components/OxyPayButton.d.ts +1 -1
  53. package/lib/typescript/commonjs/ui/components/OxyPayButton.d.ts.map +1 -1
  54. package/lib/typescript/commonjs/ui/components/SettingsIcon.d.ts +1 -1
  55. package/lib/typescript/commonjs/ui/components/SettingsIcon.d.ts.map +1 -1
  56. package/lib/typescript/commonjs/ui/components/logo/LogoIcon.d.ts +1 -1
  57. package/lib/typescript/commonjs/ui/components/logo/LogoIcon.d.ts.map +1 -1
  58. package/lib/typescript/commonjs/ui/components/logo/LogoText.d.ts +1 -1
  59. package/lib/typescript/commonjs/ui/components/logo/LogoText.d.ts.map +1 -1
  60. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts +1 -1
  61. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
  62. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts +1 -2
  63. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  64. package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +3 -0
  65. package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
  66. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts +2 -1
  67. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  68. package/lib/typescript/commonjs/ui/hooks/useFollow.d.ts +1 -1
  69. package/lib/typescript/commonjs/ui/hooks/useFollow.d.ts.map +1 -1
  70. package/lib/typescript/commonjs/ui/hooks/useLanguageManagement.d.ts +52 -8
  71. package/lib/typescript/commonjs/ui/hooks/useLanguageManagement.d.ts.map +1 -1
  72. package/lib/typescript/commonjs/ui/hooks/useSessionManagement.d.ts +1 -2
  73. package/lib/typescript/commonjs/ui/hooks/useSessionManagement.d.ts.map +1 -1
  74. package/lib/typescript/commonjs/ui/screens/LanguageSelectorScreen.d.ts.map +1 -1
  75. package/lib/typescript/commonjs/ui/screens/PreferencesScreen.d.ts.map +1 -1
  76. package/lib/typescript/commonjs/ui/screens/fileManagement/FileListSection.d.ts +1 -1
  77. package/lib/typescript/commonjs/ui/screens/fileManagement/FileListSection.d.ts.map +1 -1
  78. package/lib/typescript/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.d.ts +1 -1
  79. package/lib/typescript/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
  80. package/lib/typescript/module/ui/components/FollowButton.d.ts +2 -2
  81. package/lib/typescript/module/ui/components/FollowButton.d.ts.map +1 -1
  82. package/lib/typescript/module/ui/components/OxyPayButton.d.ts +1 -1
  83. package/lib/typescript/module/ui/components/OxyPayButton.d.ts.map +1 -1
  84. package/lib/typescript/module/ui/components/SettingsIcon.d.ts +1 -1
  85. package/lib/typescript/module/ui/components/SettingsIcon.d.ts.map +1 -1
  86. package/lib/typescript/module/ui/components/logo/LogoIcon.d.ts +1 -1
  87. package/lib/typescript/module/ui/components/logo/LogoIcon.d.ts.map +1 -1
  88. package/lib/typescript/module/ui/components/logo/LogoText.d.ts +1 -1
  89. package/lib/typescript/module/ui/components/logo/LogoText.d.ts.map +1 -1
  90. package/lib/typescript/module/ui/context/OxyContext.d.ts +1 -1
  91. package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
  92. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts +1 -2
  93. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  94. package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +3 -0
  95. package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
  96. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts +2 -1
  97. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  98. package/lib/typescript/module/ui/hooks/useFollow.d.ts +1 -1
  99. package/lib/typescript/module/ui/hooks/useFollow.d.ts.map +1 -1
  100. package/lib/typescript/module/ui/hooks/useLanguageManagement.d.ts +52 -8
  101. package/lib/typescript/module/ui/hooks/useLanguageManagement.d.ts.map +1 -1
  102. package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts +1 -2
  103. package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts.map +1 -1
  104. package/lib/typescript/module/ui/screens/LanguageSelectorScreen.d.ts.map +1 -1
  105. package/lib/typescript/module/ui/screens/PreferencesScreen.d.ts.map +1 -1
  106. package/lib/typescript/module/ui/screens/fileManagement/FileListSection.d.ts +1 -1
  107. package/lib/typescript/module/ui/screens/fileManagement/FileListSection.d.ts.map +1 -1
  108. package/lib/typescript/module/ui/screens/fileManagement/hooks/useFileUploadState.d.ts +1 -1
  109. package/lib/typescript/module/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
  110. package/package.json +31 -18
  111. package/plugins/withSharedIdentityProvider.js +83 -0
  112. package/plugins/withSharedIdentityReader.js +46 -0
  113. package/src/ui/components/FollowButton.tsx +6 -5
  114. package/src/ui/components/OxyPayButton.tsx +1 -1
  115. package/src/ui/components/SettingsIcon.tsx +2 -1
  116. package/src/ui/components/logo/LogoIcon.tsx +2 -1
  117. package/src/ui/components/logo/LogoText.tsx +2 -1
  118. package/src/ui/context/OxyContext.tsx +13 -11
  119. package/src/ui/context/hooks/useAuthOperations.ts +1 -5
  120. package/src/ui/context/oxyContextTypes.ts +3 -0
  121. package/src/ui/hooks/useFollow.ts +1 -1
  122. package/src/ui/hooks/useLanguageManagement.ts +144 -42
  123. package/src/ui/hooks/useSessionManagement.ts +1 -4
  124. package/src/ui/screens/FeedbackScreen.tsx +1 -1
  125. package/src/ui/screens/LanguageSelectorScreen.tsx +195 -104
  126. package/src/ui/screens/PreferencesScreen.tsx +4 -6
  127. package/src/ui/screens/fileManagement/FileListSection.tsx +1 -1
  128. package/src/ui/screens/fileManagement/hooks/useFileUploadState.ts +1 -1
@@ -1,25 +1,69 @@
1
- import type { ApiError, User } from '@oxyhq/core';
2
- import { type LanguageMetadata } from '@oxyhq/core';
1
+ import type { ApiError, User, SupportedLanguage } from '@oxyhq/core';
3
2
  import type { StorageInterface } from '../utils/storageHelpers.js';
4
3
  export interface UseLanguageManagementOptions {
5
4
  storage: StorageInterface | null;
6
5
  languageKey: string;
6
+ /**
7
+ * The active account, when signed in. When present, the account's primary
8
+ * locale (`languages[0]`) is authoritative for the app's UI locale; when
9
+ * `null` the device locale (or a locally-chosen guest override) is used.
10
+ */
11
+ user: User | null;
7
12
  onError?: (error: ApiError) => void;
8
13
  logger?: (message: string, error?: unknown) => void;
9
14
  }
10
15
  export interface UseLanguageManagementResult {
16
+ /**
17
+ * The active UI locale (a canonical `language-REGION` tag). Derived, never
18
+ * stored: the account's primary locale when signed in, otherwise the
19
+ * locally-chosen guest override, otherwise the device locale.
20
+ */
11
21
  currentLanguage: string;
12
- metadata: LanguageMetadata | null;
22
+ /**
23
+ * The ordered account locales (primary first) when signed in, or the single
24
+ * guest override when signed out. Empty only before the guest override loads
25
+ * and no device locale resolves.
26
+ */
27
+ languages: string[];
28
+ metadata: SupportedLanguage | null;
13
29
  languageName: string;
14
30
  nativeLanguageName: string;
15
- setLanguage: (languageId: string) => Promise<void>;
16
- applyLanguagePreference: (user: User | null) => Promise<void>;
31
+ /**
32
+ * Persist a single locally-owned locale (guest / device override) and mark it
33
+ * primary. For signed-in accounts, locale changes are written to the account
34
+ * (`updateProfile({ languages })`) instead — the derived `currentLanguage`
35
+ * then follows the refreshed `user`.
36
+ */
37
+ setLanguage: (locale: string) => Promise<void>;
17
38
  hydrateLanguage: () => Promise<void>;
18
39
  }
19
40
  /**
20
- * Manage UI language state, persistence, and metadata derivation.
41
+ * Append `locale` to an ordered locale list if not already present. Canonical
42
+ * order is preserved; the new locale lands last (non-primary).
43
+ */
44
+ export declare function addLocale(languages: readonly string[], locale: string): string[];
45
+ /**
46
+ * Remove `locale` from an ordered locale list. The list's new first element
47
+ * becomes the primary locale.
48
+ */
49
+ export declare function removeLocale(languages: readonly string[], locale: string): string[];
50
+ /**
51
+ * Move `locale` to the front of an ordered locale list, making it primary.
52
+ * Adds it if it was not already present.
53
+ */
54
+ export declare function setPrimaryLocale(languages: readonly string[], locale: string): string[];
55
+ /**
56
+ * Resolve and manage the app's active UI locale.
57
+ *
58
+ * The active locale is DERIVED, not stored:
59
+ * - Signed in → the account's primary locale (`getPrimaryLanguage(user)`),
60
+ * falling back to {@link FALLBACK_LOCALE}. This is what makes every Oxy app
61
+ * follow the account's language automatically.
62
+ * - Signed out → a locally-chosen guest override if one exists, otherwise the
63
+ * device locale.
21
64
  *
22
- * @param options - Configuration for storage access and error reporting
65
+ * The only external system this hook synchronizes with is local storage (the
66
+ * guest override), which is loaded once on mount.
23
67
  */
24
- export declare const useLanguageManagement: ({ storage, languageKey, onError, logger, }: UseLanguageManagementOptions) => UseLanguageManagementResult;
68
+ export declare const useLanguageManagement: ({ storage, languageKey, user, onError, logger, }: UseLanguageManagementOptions) => UseLanguageManagementResult;
25
69
  //# sourceMappingURL=useLanguageManagement.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useLanguageManagement.d.ts","sourceRoot":"","sources":["../../../../../src/ui/hooks/useLanguageManagement.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAKL,KAAK,gBAAgB,EACtB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAAyB,CAAC;AAGhE,MAAM,WAAW,4BAA4B;IAC3C,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CACrD;AAED,MAAM,WAAW,2BAA2B;IAC1C,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,uBAAuB,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9D,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAID;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,GAAI,4CAKnC,4BAA4B,KAAG,2BA4GjC,CAAC"}
1
+ {"version":3,"file":"useLanguageManagement.d.ts","sourceRoot":"","sources":["../../../../../src/ui/hooks/useLanguageManagement.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAYrE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAAyB,CAAC;AAGhE,MAAM,WAAW,4BAA4B;IAC3C,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,WAAW,EAAE,MAAM,CAAC;IACpB;;;;OAIG;IACH,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CACrD;AAED,MAAM,WAAW,2BAA2B;IAC1C;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;OAKG;IACH,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACtC;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAKhF;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAInF;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAIvF;AA6CD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,qBAAqB,GAAI,kDAMnC,4BAA4B,KAAG,2BAyGjC,CAAC"}
@@ -9,7 +9,6 @@ export interface UseSessionManagementOptions {
9
9
  storageKeyPrefix?: string;
10
10
  loginSuccess: (user: User) => void;
11
11
  logoutStore: () => void;
12
- applyLanguagePreference: (user: User) => Promise<void>;
13
12
  onAuthStateChange?: (user: User | null) => void;
14
13
  onError?: (error: ApiError) => void;
15
14
  setAuthError?: (message: string | null) => void;
@@ -38,5 +37,5 @@ export interface UseSessionManagementResult {
38
37
  *
39
38
  * @param options - Session management configuration
40
39
  */
41
- export declare const useSessionManagement: ({ oxyServices, storage, storageKeyPrefix, loginSuccess, logoutStore, applyLanguagePreference, onAuthStateChange, onError, setAuthError, logger, setTokenReady, queryClient, }: UseSessionManagementOptions) => UseSessionManagementResult;
40
+ export declare const useSessionManagement: ({ oxyServices, storage, storageKeyPrefix, loginSuccess, logoutStore, onAuthStateChange, onError, setAuthError, logger, setTokenReady, queryClient, }: UseSessionManagementOptions) => UseSessionManagementResult;
42
41
  //# sourceMappingURL=useSessionManagement.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useSessionManagement.d.ts","sourceRoot":"","sources":["../../../../../src/ui/hooks/useSessionManagement.ts"],"names":[],"mappings":"AACA,OAAO,EAAS,KAAK,QAAQ,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,EAAE,cAAc,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAAyB,CAAC;AAEhF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKzD,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACnC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,uBAAuB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACpD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACvD,cAAc,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,IAAI,CAAC;IAClH,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,eAAe,EAAE,CAAC,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,WAAW,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;IAC/C,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAKD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,+KAalC,2BAA2B,KAAG,0BA4ThC,CAAC"}
1
+ {"version":3,"file":"useSessionManagement.d.ts","sourceRoot":"","sources":["../../../../../src/ui/hooks/useSessionManagement.ts"],"names":[],"mappings":"AACA,OAAO,EAAS,KAAK,QAAQ,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,OAAO,EAAE,cAAc,EAAE,KAAK,gBAAgB,EAAE,MAAM,4BAAyB,CAAC;AAEhF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAKzD,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACjC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACnC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,iBAAiB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAChD,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACpD,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC,WAAW,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACvD,cAAc,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAC;QAAC,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,IAAI,CAAC;IAClH,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,eAAe,EAAE,CAAC,YAAY,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,iBAAiB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,mBAAmB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACjD,WAAW,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;IAC/C,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAKD;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,GAAI,sJAYlC,2BAA2B,KAAG,0BA2ThC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"LanguageSelectorScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/LanguageSelectorScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAE9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAqB,CAAC;AAa3D,UAAU,2BAA4B,SAAQ,eAAe;CAAI;;AA+LjE,wBAAkD"}
1
+ {"version":3,"file":"LanguageSelectorScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/LanguageSelectorScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAyC,MAAM,OAAO,CAAC;AAE9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAqB,CAAC;AAkB3D,UAAU,2BAA4B,SAAQ,eAAe;CAAI;;AAqRjE,wBAAkD"}
@@ -1 +1 @@
1
- {"version":3,"file":"PreferencesScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/PreferencesScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoD,MAAM,OAAO,CAAC;AAMzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAqB,CAAC;;AA4O3D,wBAA6C"}
1
+ {"version":3,"file":"PreferencesScreen.d.ts","sourceRoot":"","sources":["../../../../../src/ui/screens/PreferencesScreen.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoD,MAAM,OAAO,CAAC;AAOzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAqB,CAAC;;AAyO3D,wBAA6C"}
@@ -1,7 +1,7 @@
1
1
  import type React from 'react';
2
2
  import { ScrollView } from 'react-native';
3
3
  import type { FileMetadata } from '@oxyhq/core';
4
- import { useTheme } from '@oxyhq/bloom/theme';
4
+ import type { useTheme } from '@oxyhq/bloom/theme';
5
5
  type ThemeColors = ReturnType<typeof useTheme>['colors'];
6
6
  /** A pre-built list row descriptor (produced by the orchestrator's memo). */
7
7
  export interface FileListItem {
@@ -1 +1 @@
1
- {"version":3,"file":"FileListSection.d.ts","sourceRoot":"","sources":["../../../../../../src/ui/screens/fileManagement/FileListSection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAIH,UAAU,EAGb,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC;AAEzD,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACjC,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAClD,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,MAAM,EAAE;QAAE,WAAW,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IACnD,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,WAAW,CAAC;IACpB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAAK,MAAM,CAAC;IACnE,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,mEAAmE;IACnE,gBAAgB,EAAE,MAAM,KAAK,CAAC,SAAS,CAAC;CAC3C;AAED;;;;GAIG;AACH,QAAA,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA2EnD,CAAC;AAEF,eAAe,eAAe,CAAC"}
1
+ {"version":3,"file":"FileListSection.d.ts","sourceRoot":"","sources":["../../../../../../src/ui/screens/fileManagement/FileListSection.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAIH,UAAU,EAGb,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAGnD,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC;AAEzD,6EAA6E;AAC7E,MAAM,WAAW,YAAY;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACjC,aAAa,EAAE,KAAK,CAAC,SAAS,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAClD,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,MAAM,EAAE;QAAE,WAAW,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;IACnD,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,WAAW,CAAC;IACpB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAAK,MAAM,CAAC;IACnE,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,aAAa,EAAE,MAAM,IAAI,CAAC;IAC1B,mEAAmE;IACnE,gBAAgB,EAAE,MAAM,KAAK,CAAC,SAAS,CAAC;CAC3C;AAED;;;;GAIG;AACH,QAAA,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA2EnD,CAAC;AAEF,eAAe,eAAe,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import type React from 'react';
2
2
  import type { FileMetadata } from '@oxyhq/core';
3
- import { useUploadFile } from '../../../hooks/mutations/useAccountMutations.js';
3
+ import type { useUploadFile } from '../../../hooks/mutations/useAccountMutations.js';
4
4
  import { type PendingUploadFile } from '../shared.js';
5
5
  /** Dependencies threaded into the upload-state hook from the orchestrator. */
6
6
  export interface UseFileUploadStateParams {
@@ -1 +1 @@
1
- {"version":3,"file":"useFileUploadState.d.ts","sourceRoot":"","sources":["../../../../../../../src/ui/screens/fileManagement/hooks/useFileUploadState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAoB,YAAY,EAAE,MAAM,aAAa,CAAC;AAElE,OAAO,EAAE,aAAa,EAAE,MAAM,iDAA8C,CAAC;AAE7E,OAAO,EACH,KAAK,iBAAiB,EAQzB,MAAM,cAAW,CAAC;AAEnB,8EAA8E;AAC9E,MAAM,WAAW,wBAAwB;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;IACrD,iBAAiB,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;IACrD,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACvC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,cAAc,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAClE,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACtF,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAAK,MAAM,CAAC;CACtE;AAED,mDAAmD;AACnD,MAAM,WAAW,wBAAwB;IACrC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,mBAAmB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,sKAchC,wBAAwB,KAAG,wBA4a7B,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"useFileUploadState.d.ts","sourceRoot":"","sources":["../../../../../../../src/ui/screens/fileManagement/hooks/useFileUploadState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAoB,YAAY,EAAE,MAAM,aAAa,CAAC;AAElE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iDAA8C,CAAC;AAElF,OAAO,EACH,KAAK,iBAAiB,EAQzB,MAAM,cAAW,CAAC;AAEnB,8EAA8E;AAC9E,MAAM,WAAW,wBAAwB;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;IACrD,iBAAiB,EAAE,SAAS,GAAG,QAAQ,GAAG,UAAU,CAAC;IACrD,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,WAAW,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACvC,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAC;IACxC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,WAAW,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACzB,cAAc,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAClE,SAAS,EAAE,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACtF,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,KAAK,MAAM,CAAC;CACtE;AAED,mDAAmD;AACnD,MAAM,WAAW,wBAAwB;IACrC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,iBAAiB,EAAE,OAAO,CAAC;IAC3B,gBAAgB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,mBAAmB,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,kBAAkB,EAAE,MAAM,IAAI,CAAC;IAC/B,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9C;AAED;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAAI,sKAchC,wBAAwB,KAAG,wBA4a7B,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxyhq/services",
3
- "version": "19.1.3",
3
+ "version": "20.0.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",
@@ -60,12 +60,20 @@
60
60
  },
61
61
  "default": "./lib/module/ui/server.js"
62
62
  },
63
+ "./plugins/*": "./plugins/*.js",
64
+ "./expo-module.config.json": "./expo-module.config.json",
63
65
  "./package.json": "./package.json"
64
66
  },
65
67
  "files": [
66
68
  "src",
67
69
  "lib",
68
- "assets"
70
+ "assets",
71
+ "android/build.gradle",
72
+ "android/src",
73
+ "ios/OxyIdentityModule.swift",
74
+ "ios/OxyIdentity.podspec",
75
+ "plugins",
76
+ "expo-module.config.json"
69
77
  ],
70
78
  "keywords": [
71
79
  "react-native",
@@ -118,24 +126,16 @@
118
126
  }
119
127
  },
120
128
  "dependencies": {
121
- "@oxyhq/contracts": "0.13.2",
129
+ "@oxyhq/contracts": "0.14.0",
130
+ "@oxyhq/core": "^10.0.0",
122
131
  "color": "^4.2.3"
123
132
  },
124
133
  "devDependencies": {
125
- "@oxyhq/core": "9.2.3",
126
- "nativewind": "5.0.0-preview.3",
127
- "react-native-css": "^3.0.0",
128
- "@react-native-async-storage/async-storage": "^2.0.0",
129
- "@types/react": "*",
130
- "copyfiles": "^2.4.1",
131
- "react-native-keyboard-controller": "1.21.13",
132
- "react-native-qrcode-svg": "^6.3.0",
133
- "socket.io-client": "^4.8.1",
134
- "typescript": "^5.9.2",
135
- "zustand": "^5.0.14",
136
134
  "@biomejs/biome": "^1.9.4",
137
135
  "@commitlint/cli": "^17.6.5",
138
136
  "@commitlint/config-conventional": "^17.6.5",
137
+ "@oxyhq/core": "10.0.0",
138
+ "@react-native-async-storage/async-storage": "^2.0.0",
139
139
  "@react-native-community/netinfo": "^11.4.1",
140
140
  "@react-native/babel-preset": "^0.86.0",
141
141
  "@release-it/conventional-changelog": "^10.0.2",
@@ -147,6 +147,8 @@
147
147
  "@types/color": "^4.2.1",
148
148
  "@types/jest": "^29.5.14",
149
149
  "@types/node": "^20.19.9",
150
+ "@types/react": "*",
151
+ "copyfiles": "^2.4.1",
150
152
  "expo-file-system": "~57.0.0",
151
153
  "expo-font": "~57.0.0",
152
154
  "expo-haptics": "~57.0.0",
@@ -155,18 +157,25 @@
155
157
  "husky": "^4.3.8",
156
158
  "jest": "~29.7.0",
157
159
  "lint-staged": "^15.2.4",
160
+ "nativewind": "5.0.0-preview.3",
158
161
  "react-native-builder-bob": "^0.43.0",
162
+ "react-native-css": "^3.0.0",
159
163
  "react-native-gesture-handler": "~2.32.0",
164
+ "react-native-keyboard-controller": "1.21.13",
165
+ "react-native-qrcode-svg": "^6.3.0",
160
166
  "react-native-reanimated": "4.5.0",
161
167
  "react-native-safe-area-context": "~5.8.0",
162
168
  "react-native-svg": "15.15.5",
163
169
  "release-it": "^19.0.6",
164
- "ts-jest": "^29.4.0"
170
+ "socket.io-client": "^4.8.1",
171
+ "ts-jest": "^29.4.0",
172
+ "typescript": "^5.9.2",
173
+ "zustand": "^5.0.14"
165
174
  },
166
175
  "peerDependencies": {
167
176
  "@expo/vector-icons": "^15.0.3",
168
177
  "@oxyhq/bloom": ">=0.16.0",
169
- "@oxyhq/core": "^9.2.3",
178
+ "@oxyhq/core": "^10.0.0",
170
179
  "@react-native-async-storage/async-storage": "^2.0.0",
171
180
  "@react-native-community/netinfo": "^11.4.1",
172
181
  "@tanstack/query-async-storage-persister": "^5.101",
@@ -176,6 +185,7 @@
176
185
  "@types/react": "*",
177
186
  "@types/react-native": "*",
178
187
  "expo": ">=56.0.0",
188
+ "expo-modules-core": "*",
179
189
  "expo-document-picker": ">=56.0.0",
180
190
  "expo-file-system": ">=56.0.0",
181
191
  "expo-font": ">=13.0.0",
@@ -183,6 +193,7 @@
183
193
  "expo-image": ">=2.0.0",
184
194
  "expo-image-manipulator": ">=56.0.0",
185
195
  "expo-linear-gradient": ">=56.0.0",
196
+ "nativewind": ">=5.0.0",
186
197
  "react": ">=18.0.0",
187
198
  "react-native": ">=0.85.0",
188
199
  "react-native-gesture-handler": "~2.32.0",
@@ -192,13 +203,15 @@
192
203
  "react-native-safe-area-context": "~5.8.0",
193
204
  "react-native-svg": ">=15.15.0",
194
205
  "socket.io-client": "^4.8.0",
195
- "zustand": "^5.0.0",
196
- "nativewind": ">=5.0.0"
206
+ "zustand": "^5.0.0"
197
207
  },
198
208
  "peerDependenciesMeta": {
199
209
  "nativewind": {
200
210
  "optional": true
201
211
  },
212
+ "expo-modules-core": {
213
+ "optional": true
214
+ },
202
215
  "@expo/vector-icons": {
203
216
  "optional": true
204
217
  },
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Config plugin: withSharedIdentityProvider (Commons only).
3
+ *
4
+ * Commons is the identity vault — the ONE app that HOSTS the cross-app shared
5
+ * identity. This plugin wires the Android side of `@oxyhq/services`:
6
+ *
7
+ * - Defines a `signature`-level permission `so.oxy.shared.permission.READ_IDENTITY`.
8
+ * `signature` means only apps signed with the SAME certificate (the shared
9
+ * Oxy release keystore) can hold it — the trust boundary is the signing key,
10
+ * not the deprecated `sharedUserId`.
11
+ * - Requests that same permission (`<uses-permission>`) so Commons can also
12
+ * read cross-authority (e.g. prod ⇆ dev variant) through the provider.
13
+ * - Declares the `OxyIdentityProvider` at authority `${applicationId}.identity`
14
+ * (AGP substitutes `${applicationId}` at build → `so.oxy.commons.identity`,
15
+ * or `so.oxy.commons.dev.identity` for the dev variant), guarded by that
16
+ * permission.
17
+ * - Adds a `<queries>` entry for the provider authorities so package-visibility
18
+ * filtering (Android 11+) never hides the sibling provider from the resolver.
19
+ *
20
+ * Reader apps (accounts, Mention, …) use the companion `withSharedIdentityReader`
21
+ * plugin, which only requests the permission + queries — they never host the
22
+ * provider.
23
+ */
24
+ const { withAndroidManifest } = require('@expo/config-plugins');
25
+
26
+ const READ_IDENTITY_PERMISSION = 'so.oxy.shared.permission.READ_IDENTITY';
27
+ const PROVIDER_CLASS = 'so.oxy.identity.OxyIdentityProvider';
28
+ const PROVIDER_AUTHORITIES = ['so.oxy.commons.identity', 'so.oxy.commons.dev.identity'];
29
+
30
+ module.exports = function withSharedIdentityProvider(config) {
31
+ return withAndroidManifest(config, (modConfig) => {
32
+ const manifest = modConfig.modResults.manifest;
33
+
34
+ // 1. Define the signature-level permission.
35
+ manifest['permission'] = manifest['permission'] ?? [];
36
+ if (!manifest['permission'].some((p) => p.$['android:name'] === READ_IDENTITY_PERMISSION)) {
37
+ manifest['permission'].push({
38
+ $: {
39
+ 'android:name': READ_IDENTITY_PERMISSION,
40
+ 'android:protectionLevel': 'signature',
41
+ },
42
+ });
43
+ }
44
+
45
+ // 2. Request it (Commons reads cross-authority too).
46
+ manifest['uses-permission'] = manifest['uses-permission'] ?? [];
47
+ if (!manifest['uses-permission'].some((p) => p.$['android:name'] === READ_IDENTITY_PERMISSION)) {
48
+ manifest['uses-permission'].push({ $: { 'android:name': READ_IDENTITY_PERMISSION } });
49
+ }
50
+
51
+ // 3. Make the sibling provider authorities visible under package filtering.
52
+ manifest['queries'] = manifest['queries'] ?? [];
53
+ if (manifest['queries'].length === 0) {
54
+ manifest['queries'].push({});
55
+ }
56
+ const queries = manifest['queries'][0];
57
+ queries.provider = queries.provider ?? [];
58
+ for (const authority of PROVIDER_AUTHORITIES) {
59
+ if (!queries.provider.some((p) => p.$['android:authorities'] === authority)) {
60
+ queries.provider.push({ $: { 'android:authorities': authority } });
61
+ }
62
+ }
63
+
64
+ // 4. Host the provider.
65
+ const app = manifest.application?.[0];
66
+ if (!app) {
67
+ throw new Error('withSharedIdentityProvider: AndroidManifest has no <application>');
68
+ }
69
+ app.provider = app.provider ?? [];
70
+ if (!app.provider.some((p) => p.$['android:name'] === PROVIDER_CLASS)) {
71
+ app.provider.push({
72
+ $: {
73
+ 'android:name': PROVIDER_CLASS,
74
+ 'android:authorities': '${applicationId}.identity',
75
+ 'android:exported': 'true',
76
+ 'android:permission': READ_IDENTITY_PERMISSION,
77
+ },
78
+ });
79
+ }
80
+
81
+ return modConfig;
82
+ });
83
+ };
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Config plugin: withSharedIdentityReader (reader RPs — accounts, etc.).
3
+ *
4
+ * Reader apps do NOT host the shared identity — they only READ it from the
5
+ * Commons-hosted `OxyIdentityProvider` to enable silent "Sign in with Oxy".
6
+ * This plugin wires the minimal Android side of `@oxyhq/services`:
7
+ *
8
+ * - Requests the `signature`-level permission `so.oxy.shared.permission.READ_IDENTITY`
9
+ * (defined by Commons). Because it is `signature`, it is only granted when
10
+ * this app is signed with the SAME certificate as Commons (the shared Oxy
11
+ * release keystore) — that is the entire trust boundary.
12
+ * - Adds a `<queries>` entry for the Commons provider authorities so
13
+ * package-visibility filtering (Android 11+) never hides the provider from
14
+ * `ContentResolver.call`.
15
+ *
16
+ * The provider itself is declared only in Commons (`withSharedIdentityProvider`).
17
+ */
18
+ const { withAndroidManifest } = require('@expo/config-plugins');
19
+
20
+ const READ_IDENTITY_PERMISSION = 'so.oxy.shared.permission.READ_IDENTITY';
21
+ const PROVIDER_AUTHORITIES = ['so.oxy.commons.identity', 'so.oxy.commons.dev.identity'];
22
+
23
+ module.exports = function withSharedIdentityReader(config) {
24
+ return withAndroidManifest(config, (modConfig) => {
25
+ const manifest = modConfig.modResults.manifest;
26
+
27
+ manifest['uses-permission'] = manifest['uses-permission'] ?? [];
28
+ if (!manifest['uses-permission'].some((p) => p.$['android:name'] === READ_IDENTITY_PERMISSION)) {
29
+ manifest['uses-permission'].push({ $: { 'android:name': READ_IDENTITY_PERMISSION } });
30
+ }
31
+
32
+ manifest['queries'] = manifest['queries'] ?? [];
33
+ if (manifest['queries'].length === 0) {
34
+ manifest['queries'].push({});
35
+ }
36
+ const queries = manifest['queries'][0];
37
+ queries.provider = queries.provider ?? [];
38
+ for (const authority of PROVIDER_AUTHORITIES) {
39
+ if (!queries.provider.some((p) => p.$['android:authorities'] === authority)) {
40
+ queries.provider.push({ $: { 'android:authorities': authority } });
41
+ }
42
+ }
43
+
44
+ return modConfig;
45
+ });
46
+ };
@@ -1,8 +1,9 @@
1
- import React, { useEffect, useCallback, useMemo, useState, memo } from 'react';
2
- import {
3
- type ViewStyle,
4
- type TextStyle,
5
- type StyleProp,
1
+ import type React from 'react';
2
+ import { useEffect, useCallback, useMemo, useState, memo } from 'react';
3
+ import type {
4
+ ViewStyle,
5
+ TextStyle,
6
+ StyleProp,
6
7
  } from 'react-native';
7
8
  import { useOxy } from '../context/OxyContext';
8
9
  import { toast } from '@oxyhq/bloom';
@@ -1,5 +1,5 @@
1
1
  import type React from 'react';
2
- import { type ViewStyle, type TextStyle, type StyleProp } from 'react-native';
2
+ import type { ViewStyle, TextStyle, StyleProp } from 'react-native';
3
3
  import { useTheme } from '@oxyhq/bloom/theme';
4
4
  import { Button } from '@oxyhq/bloom/button';
5
5
  import type { PaymentItem, PaymentGatewayResult } from '../screens/PaymentGatewayScreen';
@@ -1,4 +1,5 @@
1
- import React, { memo } from 'react';
1
+ import type React from 'react';
2
+ import { memo } from 'react';
2
3
  import { View, StyleSheet } from 'react-native';
3
4
  import { MaterialCommunityIcons } from '@expo/vector-icons';
4
5
  import { darkenColor } from '../utils/colorUtils';
@@ -1,4 +1,5 @@
1
- import React, { type ReactElement } from 'react';
1
+ import type React from 'react';
2
+ import type { ReactElement } from 'react';
2
3
  import Svg, { ClipPath, Defs, G, Path } from 'react-native-svg';
3
4
  import type { ViewStyle } from 'react-native';
4
5
  import { useTheme } from '@oxyhq/bloom/theme';
@@ -1,4 +1,5 @@
1
- import React, { type ReactElement } from 'react';
1
+ import type React from 'react';
2
+ import type { ReactElement } from 'react';
2
3
  import Svg, { G, Path } from 'react-native-svg';
3
4
  import type { ViewStyle } from 'react-native';
4
5
  import { useTheme } from '@oxyhq/bloom/theme';
@@ -56,11 +56,11 @@ import {
56
56
  activeUserOf,
57
57
  accountIdsOf,
58
58
  } from '../session';
59
- import {
60
- type OxyContextState,
61
- type PasswordSignInResult,
62
- type OxyContextProviderProps,
63
- type CommitInput,
59
+ import type {
60
+ OxyContextState,
61
+ PasswordSignInResult,
62
+ OxyContextProviderProps,
63
+ CommitInput,
64
64
  } from './oxyContextTypes';
65
65
  import { DEFAULT_SESSION_VALIDITY_MS, loadUseFollowHook } from './oxyContextHelpers';
66
66
  import { commitDeviceSetAndResolve } from './commitSessionFlow';
@@ -210,14 +210,15 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
210
210
 
211
211
  const {
212
212
  currentLanguage,
213
+ languages: currentLanguages,
213
214
  metadata: currentLanguageMetadata,
214
215
  languageName: currentLanguageName,
215
216
  nativeLanguageName: currentNativeLanguageName,
216
217
  setLanguage,
217
- applyLanguagePreference,
218
218
  } = useLanguageManagement({
219
219
  storage,
220
220
  languageKey: storageKeys.language,
221
+ user,
221
222
  onError,
222
223
  logger,
223
224
  });
@@ -238,7 +239,6 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
238
239
  storageKeyPrefix,
239
240
  loginSuccess,
240
241
  logoutStore,
241
- applyLanguagePreference,
242
242
  onAuthStateChange,
243
243
  onError,
244
244
  setAuthError: (message) => setAuthState({ error: message }),
@@ -376,7 +376,6 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
376
376
  switchSession,
377
377
  sessionClient,
378
378
  syncFromClient,
379
- applyLanguagePreference,
380
379
  onAuthStateChange,
381
380
  onError,
382
381
  loginSuccess,
@@ -873,6 +872,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
873
872
  isStorageReady: storage !== null,
874
873
  error,
875
874
  currentLanguage,
875
+ currentLanguages,
876
876
  currentLanguageMetadata,
877
877
  currentLanguageName,
878
878
  currentNativeLanguageName,
@@ -924,6 +924,7 @@ export const OxyProvider: React.FC<OxyContextProviderProps> = ({
924
924
  storage,
925
925
  error,
926
926
  currentLanguage,
927
+ currentLanguages,
927
928
  currentLanguageMetadata,
928
929
  currentLanguageName,
929
930
  currentNativeLanguageName,
@@ -992,10 +993,11 @@ const LOADING_STATE: OxyContextState = {
992
993
  isAuthResolved: false,
993
994
  isStorageReady: false,
994
995
  error: null,
995
- currentLanguage: 'en',
996
+ currentLanguage: 'en-US',
997
+ currentLanguages: [],
996
998
  currentLanguageMetadata: null,
997
- currentLanguageName: 'English',
998
- currentNativeLanguageName: 'English',
999
+ currentLanguageName: 'English (United States)',
1000
+ currentNativeLanguageName: 'English (United States)',
999
1001
  hasIdentity: () => Promise.resolve(false),
1000
1002
  getPublicKey: () => Promise.resolve(null),
1001
1003
  signIn: () => rejectMissingProvider<User>(),
@@ -36,7 +36,6 @@ export interface UseAuthOperationsOptions {
36
36
  sessionClient: SessionClient;
37
37
  /** Reprojects `sessionClient.getState()` onto sessions/activeSessionId/user (Task 1's callback). Awaited after a partial `signOut` so the exposed state reflects the server truth before the call resolves. */
38
38
  syncFromClient: () => Promise<void>;
39
- applyLanguagePreference: (user: User) => Promise<void>;
40
39
  onAuthStateChange?: (user: User | null) => void;
41
40
  onError?: (error: ApiError) => void;
42
41
  loginSuccess: (user: User) => void;
@@ -91,7 +90,6 @@ export const useAuthOperations = ({
91
90
  switchSession,
92
91
  sessionClient,
93
92
  syncFromClient,
94
- applyLanguagePreference,
95
93
  onAuthStateChange,
96
94
  onError,
97
95
  loginSuccess,
@@ -219,14 +217,12 @@ export const useAuthOperations = ({
219
217
  await saveActiveSessionId(sessionResponse.sessionId);
220
218
  updateSessions(allDeviceSessions, { merge: true });
221
219
 
222
- await applyLanguagePreference(fullUser);
223
220
  loginSuccess(fullUser);
224
221
  onAuthStateChange?.(fullUser);
225
-
222
+
226
223
  return fullUser;
227
224
  },
228
225
  [
229
- applyLanguagePreference,
230
226
  logger,
231
227
  loginSuccess,
232
228
  onAuthStateChange,
@@ -28,7 +28,10 @@ export interface OxyContextState {
28
28
  isAuthResolved: boolean;
29
29
  isStorageReady: boolean;
30
30
  error: string | null;
31
+ /** Active UI locale (`language-REGION`): the account's primary locale when signed in, else the guest/device locale. */
31
32
  currentLanguage: string;
33
+ /** Ordered account locales (primary first) when signed in, or the single guest override when signed out. */
34
+ currentLanguages: string[];
32
35
  currentLanguageMetadata: ReturnType<typeof useLanguageManagement>['metadata'];
33
36
  currentLanguageName: string;
34
37
  currentNativeLanguageName: string;
@@ -2,7 +2,7 @@ import { useCallback, useMemo } from 'react';
2
2
  import { useQuery } from '@tanstack/react-query';
3
3
  import { useFollowStore } from '../stores/followStore';
4
4
  import { useOxy } from '../context/OxyContext';
5
- import { type OxyServices, type BulkFollowResult, type BulkUnfollowResult } from '@oxyhq/core';
5
+ import type { OxyServices, BulkFollowResult, BulkUnfollowResult } from '@oxyhq/core';
6
6
  import { useShallow } from 'zustand/react/shallow';
7
7
  import { queryKeys } from './queries/queryKeys';
8
8