@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.
- package/android/build.gradle +21 -0
- package/android/src/main/AndroidManifest.xml +10 -0
- package/android/src/main/java/so/oxy/identity/OxyIdentityModule.kt +84 -0
- package/android/src/main/java/so/oxy/identity/OxyIdentityProvider.kt +77 -0
- package/android/src/main/java/so/oxy/identity/OxyIdentityStore.kt +76 -0
- package/expo-module.config.json +9 -0
- package/ios/OxyIdentity.podspec +28 -0
- package/ios/OxyIdentityModule.swift +33 -0
- package/lib/commonjs/ui/components/FollowButton.js +1 -2
- package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
- package/lib/commonjs/ui/components/SettingsIcon.js +1 -2
- package/lib/commonjs/ui/components/SettingsIcon.js.map +1 -1
- package/lib/commonjs/ui/components/logo/LogoIcon.js +0 -2
- package/lib/commonjs/ui/components/logo/LogoIcon.js.map +1 -1
- package/lib/commonjs/ui/components/logo/LogoText.js +0 -2
- package/lib/commonjs/ui/components/logo/LogoText.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +9 -8
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js +1 -3
- package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/commonjs/ui/hooks/useLanguageManagement.js +109 -28
- package/lib/commonjs/ui/hooks/useLanguageManagement.js.map +1 -1
- package/lib/commonjs/ui/hooks/useSessionManagement.js +1 -3
- package/lib/commonjs/ui/hooks/useSessionManagement.js.map +1 -1
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js +151 -88
- package/lib/commonjs/ui/screens/LanguageSelectorScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PreferencesScreen.js +5 -6
- package/lib/commonjs/ui/screens/PreferencesScreen.js.map +1 -1
- package/lib/module/ui/components/FollowButton.js +1 -1
- package/lib/module/ui/components/FollowButton.js.map +1 -1
- package/lib/module/ui/components/SettingsIcon.js +1 -1
- package/lib/module/ui/components/SettingsIcon.js.map +1 -1
- package/lib/module/ui/components/logo/LogoIcon.js +0 -1
- package/lib/module/ui/components/logo/LogoIcon.js.map +1 -1
- package/lib/module/ui/components/logo/LogoText.js +0 -1
- package/lib/module/ui/components/logo/LogoText.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +9 -8
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/context/hooks/useAuthOperations.js +1 -3
- package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
- package/lib/module/ui/hooks/useLanguageManagement.js +107 -29
- package/lib/module/ui/hooks/useLanguageManagement.js.map +1 -1
- package/lib/module/ui/hooks/useSessionManagement.js +1 -3
- package/lib/module/ui/hooks/useSessionManagement.js.map +1 -1
- package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/module/ui/screens/LanguageSelectorScreen.js +153 -91
- package/lib/module/ui/screens/LanguageSelectorScreen.js.map +1 -1
- package/lib/module/ui/screens/PreferencesScreen.js +5 -6
- package/lib/module/ui/screens/PreferencesScreen.js.map +1 -1
- package/lib/typescript/commonjs/ui/components/FollowButton.d.ts +2 -2
- package/lib/typescript/commonjs/ui/components/FollowButton.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxyPayButton.d.ts +1 -1
- package/lib/typescript/commonjs/ui/components/OxyPayButton.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/SettingsIcon.d.ts +1 -1
- package/lib/typescript/commonjs/ui/components/SettingsIcon.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/logo/LogoIcon.d.ts +1 -1
- package/lib/typescript/commonjs/ui/components/logo/LogoIcon.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/logo/LogoText.d.ts +1 -1
- package/lib/typescript/commonjs/ui/components/logo/LogoText.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts +1 -1
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts +1 -2
- package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +3 -0
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts +2 -1
- package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useFollow.d.ts +1 -1
- package/lib/typescript/commonjs/ui/hooks/useFollow.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useLanguageManagement.d.ts +52 -8
- package/lib/typescript/commonjs/ui/hooks/useLanguageManagement.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useSessionManagement.d.ts +1 -2
- package/lib/typescript/commonjs/ui/hooks/useSessionManagement.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/LanguageSelectorScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/PreferencesScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/fileManagement/FileListSection.d.ts +1 -1
- package/lib/typescript/commonjs/ui/screens/fileManagement/FileListSection.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.d.ts +1 -1
- package/lib/typescript/commonjs/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/FollowButton.d.ts +2 -2
- package/lib/typescript/module/ui/components/FollowButton.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyPayButton.d.ts +1 -1
- package/lib/typescript/module/ui/components/OxyPayButton.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/SettingsIcon.d.ts +1 -1
- package/lib/typescript/module/ui/components/SettingsIcon.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/logo/LogoIcon.d.ts +1 -1
- package/lib/typescript/module/ui/components/logo/LogoIcon.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/logo/LogoText.d.ts +1 -1
- package/lib/typescript/module/ui/components/logo/LogoText.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/OxyContext.d.ts +1 -1
- package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts +1 -2
- package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +3 -0
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts +2 -1
- package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useFollow.d.ts +1 -1
- package/lib/typescript/module/ui/hooks/useFollow.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useLanguageManagement.d.ts +52 -8
- package/lib/typescript/module/ui/hooks/useLanguageManagement.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts +1 -2
- package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/LanguageSelectorScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/PreferencesScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/fileManagement/FileListSection.d.ts +1 -1
- package/lib/typescript/module/ui/screens/fileManagement/FileListSection.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/fileManagement/hooks/useFileUploadState.d.ts +1 -1
- package/lib/typescript/module/ui/screens/fileManagement/hooks/useFileUploadState.d.ts.map +1 -1
- package/package.json +31 -18
- package/plugins/withSharedIdentityProvider.js +83 -0
- package/plugins/withSharedIdentityReader.js +46 -0
- package/src/ui/components/FollowButton.tsx +6 -5
- package/src/ui/components/OxyPayButton.tsx +1 -1
- package/src/ui/components/SettingsIcon.tsx +2 -1
- package/src/ui/components/logo/LogoIcon.tsx +2 -1
- package/src/ui/components/logo/LogoText.tsx +2 -1
- package/src/ui/context/OxyContext.tsx +13 -11
- package/src/ui/context/hooks/useAuthOperations.ts +1 -5
- package/src/ui/context/oxyContextTypes.ts +3 -0
- package/src/ui/hooks/useFollow.ts +1 -1
- package/src/ui/hooks/useLanguageManagement.ts +144 -42
- package/src/ui/hooks/useSessionManagement.ts +1 -4
- package/src/ui/screens/FeedbackScreen.tsx +1 -1
- package/src/ui/screens/LanguageSelectorScreen.tsx +195 -104
- package/src/ui/screens/PreferencesScreen.tsx +4 -6
- package/src/ui/screens/fileManagement/FileListSection.tsx +1 -1
- 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
|
-
|
|
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
|
-
|
|
16
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
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,
|
|
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,
|
|
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,
|
|
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;
|
|
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;
|
|
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;
|
|
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;
|
|
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": "
|
|
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.
|
|
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
|
-
"
|
|
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": "^
|
|
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
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
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 {
|
|
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
|
|
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
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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 {
|
|
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
|
|