@oxyhq/services 23.2.0 → 24.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/so/oxy/identity/OxyIdentityStore.kt +21 -127
- package/android/src/main/java/so/oxy/session/OxyBackgroundSession.kt +184 -0
- package/android/src/main/java/so/oxy/session/OxyBackgroundSessionApi.kt +162 -0
- package/android/src/main/java/so/oxy/session/OxyBackgroundSessionModule.kt +101 -0
- package/android/src/main/java/so/oxy/session/OxyBackgroundSessionStore.kt +179 -0
- package/android/src/main/java/so/oxy/session/OxyBackgroundToken.kt +61 -0
- package/android/src/main/java/so/oxy/storage/OxyEncryptedPrefs.kt +241 -0
- package/expo-module.config.json +4 -1
- package/lib/commonjs/ui/components/OxyProvider.js +3 -1
- package/lib/commonjs/ui/components/OxyProvider.js.map +1 -1
- package/lib/commonjs/ui/components/ProfileButton.js +1 -1
- package/lib/commonjs/ui/components/ProfileButton.js.map +1 -1
- package/lib/commonjs/ui/components/internal/PinInput.js +3 -1
- package/lib/commonjs/ui/components/internal/PinInput.js.map +1 -1
- package/lib/commonjs/ui/components/logo/LogoText.js +4 -4
- package/lib/commonjs/ui/components/logo/LogoText.js.map +1 -1
- package/lib/commonjs/ui/components/payment/PaymentSummaryStep.js +2 -2
- package/lib/commonjs/ui/components/payment/PaymentSummaryStep.js.map +1 -1
- package/lib/commonjs/ui/context/OxyContext.js +13 -0
- package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js +2 -3
- package/lib/commonjs/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ChangeAvatarScreen.js +2 -3
- package/lib/commonjs/ui/screens/ChangeAvatarScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/EditProfileScreen.js +2 -3
- package/lib/commonjs/ui/screens/EditProfileScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/FeedbackScreen.js +3 -1
- package/lib/commonjs/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ManageAccountScreen.js +1 -1
- package/lib/commonjs/ui/screens/ManageAccountScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +2 -2
- package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/PrivacySettingsScreen.js +8 -9
- package/lib/commonjs/ui/screens/PrivacySettingsScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/ProfileScreen.js +1 -1
- package/lib/commonjs/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/UserListScreen.js +2 -3
- package/lib/commonjs/ui/screens/UserListScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js +1 -1
- package/lib/commonjs/ui/screens/trust/TrustCenterScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js +2 -3
- package/lib/commonjs/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
- package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js +1 -1
- package/lib/commonjs/ui/screens/trust/TrustRewardsScreen.js.map +1 -1
- package/lib/commonjs/ui/session/backgroundSession.js +264 -0
- package/lib/commonjs/ui/session/backgroundSession.js.map +1 -0
- package/lib/commonjs/ui/session/index.js +7 -0
- package/lib/commonjs/ui/session/index.js.map +1 -1
- package/lib/commonjs/ui/session/useBackgroundSessionSync.js +81 -0
- package/lib/commonjs/ui/session/useBackgroundSessionSync.js.map +1 -0
- package/lib/commonjs/ui/utils/userUtils.js +31 -22
- package/lib/commonjs/ui/utils/userUtils.js.map +1 -1
- package/lib/module/ui/components/OxyProvider.js +3 -1
- package/lib/module/ui/components/OxyProvider.js.map +1 -1
- package/lib/module/ui/components/ProfileButton.js +2 -2
- package/lib/module/ui/components/ProfileButton.js.map +1 -1
- package/lib/module/ui/components/internal/PinInput.js +3 -1
- package/lib/module/ui/components/internal/PinInput.js.map +1 -1
- package/lib/module/ui/components/logo/LogoText.js +4 -4
- package/lib/module/ui/components/logo/LogoText.js.map +1 -1
- package/lib/module/ui/components/payment/PaymentSummaryStep.js +2 -2
- package/lib/module/ui/components/payment/PaymentSummaryStep.js.map +1 -1
- package/lib/module/ui/context/OxyContext.js +14 -1
- package/lib/module/ui/context/OxyContext.js.map +1 -1
- package/lib/module/ui/screens/AccountSettingsScreen.js +2 -3
- package/lib/module/ui/screens/AccountSettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/ChangeAvatarScreen.js +3 -4
- package/lib/module/ui/screens/ChangeAvatarScreen.js.map +1 -1
- package/lib/module/ui/screens/EditProfileScreen.js +3 -4
- package/lib/module/ui/screens/EditProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/FeedbackScreen.js +3 -1
- package/lib/module/ui/screens/FeedbackScreen.js.map +1 -1
- package/lib/module/ui/screens/ManageAccountScreen.js +2 -2
- package/lib/module/ui/screens/ManageAccountScreen.js.map +1 -1
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js +2 -2
- package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
- package/lib/module/ui/screens/PrivacySettingsScreen.js +9 -10
- package/lib/module/ui/screens/PrivacySettingsScreen.js.map +1 -1
- package/lib/module/ui/screens/ProfileScreen.js +1 -1
- package/lib/module/ui/screens/ProfileScreen.js.map +1 -1
- package/lib/module/ui/screens/UserListScreen.js +2 -3
- package/lib/module/ui/screens/UserListScreen.js.map +1 -1
- package/lib/module/ui/screens/trust/TrustCenterScreen.js +1 -1
- package/lib/module/ui/screens/trust/TrustCenterScreen.js.map +1 -1
- package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js +2 -3
- package/lib/module/ui/screens/trust/TrustLeaderboardScreen.js.map +1 -1
- package/lib/module/ui/screens/trust/TrustRewardsScreen.js +1 -1
- package/lib/module/ui/screens/trust/TrustRewardsScreen.js.map +1 -1
- package/lib/module/ui/session/backgroundSession.js +258 -0
- package/lib/module/ui/session/backgroundSession.js.map +1 -0
- package/lib/module/ui/session/index.js +1 -0
- package/lib/module/ui/session/index.js.map +1 -1
- package/lib/module/ui/session/useBackgroundSessionSync.js +76 -0
- package/lib/module/ui/session/useBackgroundSessionSync.js.map +1 -0
- package/lib/module/ui/utils/userUtils.js +31 -22
- package/lib/module/ui/utils/userUtils.js.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/ProfileButton.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/internal/PinInput.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +22 -0
- package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/ChangeAvatarScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/EditProfileScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/FeedbackScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/ProfileScreen.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/screens/trust/trustTier.d.ts +1 -1
- package/lib/typescript/commonjs/ui/screens/trust/trustTier.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/session/backgroundSession.d.ts +42 -0
- package/lib/typescript/commonjs/ui/session/backgroundSession.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/session/index.d.ts +1 -0
- package/lib/typescript/commonjs/ui/session/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/session/useBackgroundSessionSync.d.ts +23 -0
- package/lib/typescript/commonjs/ui/session/useBackgroundSessionSync.d.ts.map +1 -0
- package/lib/typescript/commonjs/ui/types/navigation.d.ts +7 -0
- package/lib/typescript/commonjs/ui/types/navigation.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/utils/userUtils.d.ts +7 -12
- package/lib/typescript/commonjs/ui/utils/userUtils.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyProvider.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/ProfileButton.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/internal/PinInput.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +22 -0
- package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/ChangeAvatarScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/EditProfileScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/FeedbackScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/PrivacySettingsScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/ProfileScreen.d.ts.map +1 -1
- package/lib/typescript/module/ui/screens/trust/trustTier.d.ts +1 -1
- package/lib/typescript/module/ui/screens/trust/trustTier.d.ts.map +1 -1
- package/lib/typescript/module/ui/session/backgroundSession.d.ts +42 -0
- package/lib/typescript/module/ui/session/backgroundSession.d.ts.map +1 -0
- package/lib/typescript/module/ui/session/index.d.ts +1 -0
- package/lib/typescript/module/ui/session/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/session/useBackgroundSessionSync.d.ts +23 -0
- package/lib/typescript/module/ui/session/useBackgroundSessionSync.d.ts.map +1 -0
- package/lib/typescript/module/ui/types/navigation.d.ts +7 -0
- package/lib/typescript/module/ui/types/navigation.d.ts.map +1 -1
- package/lib/typescript/module/ui/utils/userUtils.d.ts +7 -12
- package/lib/typescript/module/ui/utils/userUtils.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/ui/components/OxyProvider.tsx +2 -0
- package/src/ui/components/ProfileButton.tsx +5 -2
- package/src/ui/components/internal/PinInput.tsx +1 -0
- package/src/ui/components/logo/LogoText.tsx +4 -4
- package/src/ui/components/payment/PaymentSummaryStep.tsx +2 -2
- package/src/ui/context/OxyContext.tsx +14 -0
- package/src/ui/context/oxyContextTypes.ts +22 -0
- package/src/ui/screens/AccountSettingsScreen.tsx +4 -4
- package/src/ui/screens/ChangeAvatarScreen.tsx +6 -3
- package/src/ui/screens/EditProfileScreen.tsx +6 -3
- package/src/ui/screens/FeedbackScreen.tsx +1 -0
- package/src/ui/screens/ManageAccountScreen.tsx +8 -1
- package/src/ui/screens/PremiumSubscriptionScreen.tsx +2 -2
- package/src/ui/screens/PrivacySettingsScreen.tsx +13 -11
- package/src/ui/screens/ProfileScreen.tsx +3 -1
- package/src/ui/screens/UserListScreen.tsx +2 -2
- package/src/ui/screens/trust/TrustCenterScreen.tsx +2 -2
- package/src/ui/screens/trust/TrustLeaderboardScreen.tsx +3 -3
- package/src/ui/screens/trust/TrustRewardsScreen.tsx +1 -1
- package/src/ui/screens/trust/TrustRulesScreen.tsx +1 -1
- package/src/ui/screens/trust/trustTier.ts +1 -1
- package/src/ui/session/__tests__/backgroundSession.test.ts +387 -0
- package/src/ui/session/backgroundSession.ts +299 -0
- package/src/ui/session/index.ts +1 -0
- package/src/ui/session/useBackgroundSessionSync.ts +92 -0
- package/src/ui/types/navigation.ts +7 -0
- package/src/ui/utils/userUtils.ts +34 -20
|
@@ -176,6 +176,28 @@ export interface OxyContextProviderProps {
|
|
|
176
176
|
* @default 'popup'
|
|
177
177
|
*/
|
|
178
178
|
webAuthMode?: WebAuthMode;
|
|
179
|
+
/**
|
|
180
|
+
* Let NATIVE background code (a home-screen widget's WorkManager worker, a sync
|
|
181
|
+
* job) authenticate while the app process is dead and there is no JS runtime.
|
|
182
|
+
*
|
|
183
|
+
* With this on, the SDK provisions a purpose-built background credential
|
|
184
|
+
* whenever the app runs and stores it where `so.oxy.session.OxyBackgroundSession`
|
|
185
|
+
* can read it; Kotlin then exchanges it for a short access token on demand. The
|
|
186
|
+
* app writes no session code — this prop is the whole integration.
|
|
187
|
+
*
|
|
188
|
+
* OFF by default, because a credential that nobody needs is exposure that
|
|
189
|
+
* nobody needs. Turn it on only in an app that actually has background code to
|
|
190
|
+
* authenticate. Android-only today; inert on web and iOS.
|
|
191
|
+
*
|
|
192
|
+
* The credential cannot create a session (only the running app can provision
|
|
193
|
+
* one), cannot rotate or otherwise disturb the app's own device credential, and
|
|
194
|
+
* is re-authorized server-side on every use so it can never outlive a sign-out.
|
|
195
|
+
* It does NOT reduce authority: the token it mints is a full user access token,
|
|
196
|
+
* exactly like the device credential's.
|
|
197
|
+
*
|
|
198
|
+
* @default false
|
|
199
|
+
*/
|
|
200
|
+
backgroundSession?: boolean;
|
|
179
201
|
onAuthStateChange?: (user: User | null) => void;
|
|
180
202
|
onError?: (error: ApiError) => void;
|
|
181
203
|
}
|
|
@@ -12,7 +12,7 @@ import { Text } from '@oxyhq/bloom/typography';
|
|
|
12
12
|
import { Button } from '@oxyhq/bloom/button';
|
|
13
13
|
import { TextField, TextFieldInput } from '@oxyhq/bloom/text-field';
|
|
14
14
|
import { SettingsListGroup, SettingsListItem } from '@oxyhq/bloom/settings-list';
|
|
15
|
-
import type
|
|
15
|
+
import { getNormalizedUserHandle, type UpdateAccountInput } from '@oxyhq/core';
|
|
16
16
|
import type { BaseScreenProps } from '../types/navigation';
|
|
17
17
|
import { SettingsIcon } from '../components/SettingsIcon';
|
|
18
18
|
import { useOxy } from '../context/OxyContext';
|
|
@@ -67,9 +67,9 @@ const AccountSettingsScreen: React.FC<BaseScreenProps> = ({ onClose, goBack, nav
|
|
|
67
67
|
// Seed the form from the account during render (no useEffect): the first time
|
|
68
68
|
// the query resolves we capture its values into local edit state.
|
|
69
69
|
if (node && !seeded) {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
setDisplayName(
|
|
71
|
+
node.account?.name?.displayName ?? getNormalizedUserHandle(node.account) ?? '',
|
|
72
|
+
);
|
|
73
73
|
setBio(node.account?.bio ?? '');
|
|
74
74
|
setSeeded(true);
|
|
75
75
|
}
|
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
import { surfaces as bloomSurfaces } from '@oxyhq/bloom/surfaces';
|
|
41
41
|
import { useTheme } from '@oxyhq/bloom/theme';
|
|
42
42
|
import { toast } from '@oxyhq/bloom';
|
|
43
|
-
import {
|
|
43
|
+
import { getNormalizedUserHandle, logger } from '@oxyhq/core';
|
|
44
44
|
import type { FileMetadata } from '@oxyhq/core';
|
|
45
45
|
import { useOxy } from '../context/OxyContext';
|
|
46
46
|
import { useI18n } from '../hooks/useI18n';
|
|
@@ -133,7 +133,7 @@ async function loadImagePicker(): Promise<ImagePickerModule | null> {
|
|
|
133
133
|
|
|
134
134
|
const ChangeAvatarScreen: React.FC<BaseScreenProps> = ({ navigate, dismiss }) => {
|
|
135
135
|
const bloomTheme = useTheme();
|
|
136
|
-
const { t
|
|
136
|
+
const { t } = useI18n();
|
|
137
137
|
const { user, oxyServices } = useOxy();
|
|
138
138
|
|
|
139
139
|
/** Set when a permission was refused — drives the inline denied notice. */
|
|
@@ -143,7 +143,10 @@ const ChangeAvatarScreen: React.FC<BaseScreenProps> = ({ navigate, dismiss }) =>
|
|
|
143
143
|
|
|
144
144
|
useSurfaceHeader(useMemo(() => ({ title: t('changeAvatar.title') }), [t]));
|
|
145
145
|
|
|
146
|
-
const displayName = useMemo(
|
|
146
|
+
const displayName = useMemo(
|
|
147
|
+
() => user?.name?.displayName ?? getNormalizedUserHandle(user) ?? '',
|
|
148
|
+
[user],
|
|
149
|
+
);
|
|
147
150
|
const avatarUri = useMemo(
|
|
148
151
|
// `thumb` is 256x256 — exactly a 2x source for the 132dp hero.
|
|
149
152
|
() => (user?.avatar ? oxyServices.getFileDownloadUrl(user.avatar, 'thumb') : undefined),
|
|
@@ -3,7 +3,7 @@ import { useMemo } from 'react';
|
|
|
3
3
|
import { View } from 'react-native';
|
|
4
4
|
import { useTheme } from '@oxyhq/bloom/theme';
|
|
5
5
|
import { SettingsListGroup, SettingsListItem } from '@oxyhq/bloom/settings-list';
|
|
6
|
-
import {
|
|
6
|
+
import { getNormalizedUserHandle } from '@oxyhq/core';
|
|
7
7
|
import type { BaseScreenProps } from '../types/navigation';
|
|
8
8
|
import { Avatar } from '@oxyhq/bloom/avatar';
|
|
9
9
|
import ProfileSummaryCard from '../components/ProfileSummaryCard';
|
|
@@ -24,12 +24,15 @@ import type { ProfileFieldType } from './EditProfileFieldScreen';
|
|
|
24
24
|
*/
|
|
25
25
|
const EditProfileScreen: React.FC<BaseScreenProps> = ({ navigate }) => {
|
|
26
26
|
const bloomTheme = useTheme();
|
|
27
|
-
const { t
|
|
27
|
+
const { t } = useI18n();
|
|
28
28
|
const { user, oxyServices, openAvatarPicker } = useOxy();
|
|
29
29
|
|
|
30
30
|
useSurfaceHeader({ title: t('editProfile.title') || 'Edit Profile' });
|
|
31
31
|
|
|
32
|
-
const displayName = useMemo(
|
|
32
|
+
const displayName = useMemo(
|
|
33
|
+
() => user?.name?.displayName ?? getNormalizedUserHandle(user) ?? '',
|
|
34
|
+
[user],
|
|
35
|
+
);
|
|
33
36
|
const avatarUri = useMemo(
|
|
34
37
|
() => (user?.avatar ? oxyServices.getFileDownloadUrl(user.avatar, 'thumb') : undefined),
|
|
35
38
|
[user?.avatar, oxyServices],
|
|
@@ -283,6 +283,7 @@ const FeedbackScreen: React.FC<BaseScreenProps> = ({
|
|
|
283
283
|
>
|
|
284
284
|
{Array.from({ length: TOTAL_STEPS }, (_, index) => (
|
|
285
285
|
<View
|
|
286
|
+
// biome-ignore lint/suspicious/noArrayIndexKey: fixed step indicators, order never changes
|
|
286
287
|
key={index}
|
|
287
288
|
className={
|
|
288
289
|
currentStep === index
|
|
@@ -15,6 +15,7 @@ import { SettingsListGroup, SettingsListItem } from '@oxyhq/bloom/settings-list'
|
|
|
15
15
|
import {
|
|
16
16
|
getAccountDisplayName,
|
|
17
17
|
getAccountFallbackHandle,
|
|
18
|
+
getNormalizedUserHandle,
|
|
18
19
|
logger as loggerUtil,
|
|
19
20
|
packageInfo,
|
|
20
21
|
} from '@oxyhq/core';
|
|
@@ -120,7 +121,13 @@ const ManageAccountScreen: React.FC<BaseScreenProps> = ({
|
|
|
120
121
|
const [signingOutAllDevices, setSigningOutAllDevices] = useState(false);
|
|
121
122
|
const [signingOut, setSigningOut] = useState(false);
|
|
122
123
|
|
|
123
|
-
const displayName = useMemo(
|
|
124
|
+
const displayName = useMemo(
|
|
125
|
+
() =>
|
|
126
|
+
user?.name?.displayName ??
|
|
127
|
+
getNormalizedUserHandle(user) ??
|
|
128
|
+
getAccountDisplayName(null, locale),
|
|
129
|
+
[user, locale],
|
|
130
|
+
);
|
|
124
131
|
const handle = useMemo(() => getAccountFallbackHandle(user), [user]);
|
|
125
132
|
const avatarUri = useMemo(() => {
|
|
126
133
|
return user?.avatar
|
|
@@ -741,9 +741,9 @@ const PremiumSubscriptionScreen: React.FC<BaseScreenProps> = ({
|
|
|
741
741
|
</View>
|
|
742
742
|
|
|
743
743
|
<BenefitList className="mb-space-24">
|
|
744
|
-
{plan.features.map((feature
|
|
744
|
+
{plan.features.map((feature) => (
|
|
745
745
|
<BenefitRow
|
|
746
|
-
key={
|
|
746
|
+
key={feature}
|
|
747
747
|
icon={<Ionicons name="checkmark" size={18} color={colors.success} />}
|
|
748
748
|
label={feature}
|
|
749
749
|
/>
|
|
@@ -14,7 +14,7 @@ import { useI18n } from '../hooks/useI18n';
|
|
|
14
14
|
import { useSurfaceHeader } from '../hooks/useSurfaceHeader';
|
|
15
15
|
import { useSettingToggles } from '../hooks/useSettingToggle';
|
|
16
16
|
import type { BlockedUser, RestrictedUser } from '@oxyhq/core';
|
|
17
|
-
import {
|
|
17
|
+
import { getNormalizedUserHandle } from '@oxyhq/core';
|
|
18
18
|
import { useOxy } from '../context/OxyContext';
|
|
19
19
|
|
|
20
20
|
interface PrivacySettings {
|
|
@@ -68,7 +68,7 @@ const PrivacySettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
68
68
|
// Privacy settings belong to the ACTIVE account (the org/project/bot when
|
|
69
69
|
// switched, else the personal user).
|
|
70
70
|
const { oxyServices, user } = useOxy();
|
|
71
|
-
const { t
|
|
71
|
+
const { t } = useI18n();
|
|
72
72
|
|
|
73
73
|
useSurfaceHeader({ title: t('privacySettings.title') || 'Privacy Settings' });
|
|
74
74
|
const bloomTheme = useTheme();
|
|
@@ -176,35 +176,37 @@ const PrivacySettingsScreen: React.FC<BaseScreenProps> = ({
|
|
|
176
176
|
}, [oxyServices, t]);
|
|
177
177
|
|
|
178
178
|
// Helper to extract user info from blocked/restricted objects.
|
|
179
|
-
// Display names go through the canonical helper so the fallback chain is
|
|
180
|
-
// identical across every UI surface (name → username → publicKey → "Unnamed").
|
|
181
179
|
const extractUserInfo = useCallback((
|
|
182
180
|
item: BlockedUser | RestrictedUser,
|
|
183
181
|
idField: 'blockedId' | 'restrictedId'
|
|
184
182
|
) => {
|
|
185
|
-
let userIdField: string | { _id: string; username?: string; avatar?: string };
|
|
186
|
-
let userShape: { username?: string };
|
|
183
|
+
let userIdField: string | { _id: string; username?: string; avatar?: string; name?: { displayName?: string } };
|
|
184
|
+
let userShape: { username?: string; name?: { displayName?: string } };
|
|
187
185
|
let avatar: string | undefined;
|
|
188
186
|
|
|
189
187
|
if (idField === 'blockedId' && 'blockedId' in item) {
|
|
190
188
|
userIdField = item.blockedId;
|
|
191
189
|
userShape = typeof item.blockedId === 'string'
|
|
192
190
|
? { username: item.username }
|
|
193
|
-
: { username: item.blockedId.username };
|
|
191
|
+
: { username: item.blockedId.username, name: item.blockedId.name };
|
|
194
192
|
avatar = typeof item.blockedId === 'string' ? item.avatar : item.blockedId.avatar;
|
|
195
193
|
} else if (idField === 'restrictedId' && 'restrictedId' in item) {
|
|
196
194
|
userIdField = item.restrictedId;
|
|
197
195
|
userShape = typeof item.restrictedId === 'string'
|
|
198
196
|
? { username: item.username }
|
|
199
|
-
: { username: item.restrictedId.username };
|
|
197
|
+
: { username: item.restrictedId.username, name: item.restrictedId.name };
|
|
200
198
|
avatar = typeof item.restrictedId === 'string' ? item.avatar : item.restrictedId.avatar;
|
|
201
199
|
} else {
|
|
202
|
-
return { userId: '', displayName:
|
|
200
|
+
return { userId: '', displayName: getNormalizedUserHandle(null) ?? '', avatar: undefined };
|
|
203
201
|
}
|
|
204
202
|
|
|
205
203
|
const userId = typeof userIdField === 'string' ? userIdField : userIdField._id;
|
|
206
|
-
return {
|
|
207
|
-
|
|
204
|
+
return {
|
|
205
|
+
userId,
|
|
206
|
+
displayName: userShape.name?.displayName ?? getNormalizedUserHandle(userShape) ?? '',
|
|
207
|
+
avatar,
|
|
208
|
+
};
|
|
209
|
+
}, []);
|
|
208
210
|
|
|
209
211
|
if (isLoading) {
|
|
210
212
|
return (
|
|
@@ -78,7 +78,9 @@ const ProfileScreen: React.FC<ProfileScreenProps> = ({ userId, username, theme,
|
|
|
78
78
|
);
|
|
79
79
|
throw err;
|
|
80
80
|
}),
|
|
81
|
-
|
|
81
|
+
(isOwnProfile
|
|
82
|
+
? oxyServices.getMyReputationBalance()
|
|
83
|
+
: oxyServices.getReputationBalance(userId))
|
|
82
84
|
.then((balance): { total: number | undefined } => ({ total: balance.total }))
|
|
83
85
|
.catch((): { total: number | undefined } => ({ total: undefined })),
|
|
84
86
|
oxyServices.getUserStats
|
|
@@ -65,7 +65,7 @@ const UserListScreen: React.FC<UserListScreenProps> = ({
|
|
|
65
65
|
const [hasMore, setHasMore] = useState(true);
|
|
66
66
|
|
|
67
67
|
const bloomTheme = useTheme();
|
|
68
|
-
const { t
|
|
68
|
+
const { t } = useI18n();
|
|
69
69
|
|
|
70
70
|
const currentUserId = currentUser ? resolveUserId(currentUser) : '';
|
|
71
71
|
|
|
@@ -199,7 +199,7 @@ const UserListScreen: React.FC<UserListScreenProps> = ({
|
|
|
199
199
|
</TouchableOpacity>
|
|
200
200
|
);
|
|
201
201
|
},
|
|
202
|
-
[handleUserPress, currentUserId, oxyServices
|
|
202
|
+
[handleUserPress, currentUserId, oxyServices]
|
|
203
203
|
);
|
|
204
204
|
|
|
205
205
|
const renderEmpty = useCallback(() => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
import { useEffect, useMemo, useState } from 'react';
|
|
3
3
|
import { View, StyleSheet } from 'react-native';
|
|
4
|
-
import type { ReputationTransaction, TrustTier } from '@oxyhq/
|
|
4
|
+
import type { ReputationTransaction, TrustTier } from '@oxyhq/contracts';
|
|
5
5
|
import Ionicons from '@expo/vector-icons/Ionicons';
|
|
6
6
|
import { Chip } from '@oxyhq/bloom/chip';
|
|
7
7
|
import { useTheme } from '@oxyhq/bloom/theme';
|
|
@@ -36,7 +36,7 @@ const TrustCenterScreen: React.FC<BaseScreenProps> = ({
|
|
|
36
36
|
setIsLoading(true);
|
|
37
37
|
setError(null);
|
|
38
38
|
Promise.all([
|
|
39
|
-
oxyServices.
|
|
39
|
+
oxyServices.getMyReputationBalance(),
|
|
40
40
|
oxyServices.getReputationTransactions(user.id, 20, 0),
|
|
41
41
|
])
|
|
42
42
|
.then(([balance, txns]) => {
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
FlatList,
|
|
8
8
|
TouchableOpacity,
|
|
9
9
|
} from 'react-native';
|
|
10
|
-
import type { ReputationLeaderboardEntry } from '@oxyhq/
|
|
10
|
+
import type { ReputationLeaderboardEntry } from '@oxyhq/contracts';
|
|
11
11
|
import { getNormalizedUserHandle, logger } from '@oxyhq/core';
|
|
12
12
|
import { useTheme } from '@oxyhq/bloom/theme';
|
|
13
13
|
import { H6, Text } from '@oxyhq/bloom/typography';
|
|
@@ -29,7 +29,7 @@ const PODIUM_RANK = 3;
|
|
|
29
29
|
|
|
30
30
|
const TrustLeaderboardScreen: React.FC<BaseScreenProps> = ({ navigate }) => {
|
|
31
31
|
const { oxyServices, user: currentUser } = useOxy();
|
|
32
|
-
const { t
|
|
32
|
+
const { t } = useI18n();
|
|
33
33
|
const bloomTheme = useTheme();
|
|
34
34
|
|
|
35
35
|
const [leaderboard, setLeaderboard] = useState<ReputationLeaderboardEntry[]>([]);
|
|
@@ -116,7 +116,7 @@ const TrustLeaderboardScreen: React.FC<BaseScreenProps> = ({ navigate }) => {
|
|
|
116
116
|
</TouchableOpacity>
|
|
117
117
|
);
|
|
118
118
|
},
|
|
119
|
-
[oxyServices,
|
|
119
|
+
[oxyServices, currentUserId, handleEntryPress, t],
|
|
120
120
|
);
|
|
121
121
|
|
|
122
122
|
const keyExtractor = useCallback(
|
|
@@ -97,7 +97,7 @@ const TrustRewardsScreen: React.FC<BaseScreenProps> = () => {
|
|
|
97
97
|
return;
|
|
98
98
|
}
|
|
99
99
|
setIsLoading(true);
|
|
100
|
-
oxyServices.
|
|
100
|
+
oxyServices.getMyReputationBalance()
|
|
101
101
|
.then((balance) => {
|
|
102
102
|
setReputationTotal(balance.total || 0);
|
|
103
103
|
})
|
|
@@ -4,7 +4,7 @@ import { View, Text } from 'react-native';
|
|
|
4
4
|
import { SettingsListGroup, SettingsListItem } from '@oxyhq/bloom/settings-list';
|
|
5
5
|
import { Chip } from '@oxyhq/bloom/chip';
|
|
6
6
|
import { useTheme } from '@oxyhq/bloom/theme';
|
|
7
|
-
import type { ReputationRule, ReputationCategory } from '@oxyhq/
|
|
7
|
+
import type { ReputationRule, ReputationCategory } from '@oxyhq/contracts';
|
|
8
8
|
import type { BaseScreenProps } from '../../types/navigation';
|
|
9
9
|
import { useSurfaceHeader } from '../../hooks/useSurfaceHeader';
|
|
10
10
|
import { Loading } from '@oxyhq/bloom/loading';
|