@oxyhq/services 22.2.0 → 22.4.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/lib/commonjs/index.js +6 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/ui/components/FollowButton.js +24 -19
- package/lib/commonjs/ui/components/FollowButton.js.map +1 -1
- package/lib/commonjs/ui/components/OxyAuthChooser.js +74 -94
- package/lib/commonjs/ui/components/OxyAuthChooser.js.map +1 -1
- package/lib/commonjs/ui/components/oxyAuthChooserStyles.js +0 -19
- package/lib/commonjs/ui/components/oxyAuthChooserStyles.js.map +1 -1
- package/lib/commonjs/ui/context/useOxyAccountGraph.js +2 -0
- package/lib/commonjs/ui/context/useOxyAccountGraph.js.map +1 -1
- package/lib/commonjs/ui/hooks/useFollow.js +53 -10
- package/lib/commonjs/ui/hooks/useFollow.js.map +1 -1
- package/lib/commonjs/ui/hooks/useSessionManagement.js +2 -0
- package/lib/commonjs/ui/hooks/useSessionManagement.js.map +1 -1
- package/lib/commonjs/ui/index.js +6 -0
- package/lib/commonjs/ui/index.js.map +1 -1
- package/lib/commonjs/ui/stores/followStore.js +276 -92
- package/lib/commonjs/ui/stores/followStore.js.map +1 -1
- package/lib/commonjs/ui/stores/resetSessionScopedStores.js +14 -0
- package/lib/commonjs/ui/stores/resetSessionScopedStores.js.map +1 -0
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/ui/components/FollowButton.js +24 -19
- package/lib/module/ui/components/FollowButton.js.map +1 -1
- package/lib/module/ui/components/OxyAuthChooser.js +75 -95
- package/lib/module/ui/components/OxyAuthChooser.js.map +1 -1
- package/lib/module/ui/components/oxyAuthChooserStyles.js +0 -19
- package/lib/module/ui/components/oxyAuthChooserStyles.js.map +1 -1
- package/lib/module/ui/context/useOxyAccountGraph.js +2 -0
- package/lib/module/ui/context/useOxyAccountGraph.js.map +1 -1
- package/lib/module/ui/hooks/useFollow.js +51 -9
- package/lib/module/ui/hooks/useFollow.js.map +1 -1
- package/lib/module/ui/hooks/useSessionManagement.js +2 -0
- package/lib/module/ui/hooks/useSessionManagement.js.map +1 -1
- package/lib/module/ui/index.js +1 -1
- package/lib/module/ui/index.js.map +1 -1
- package/lib/module/ui/stores/followStore.js +274 -91
- package/lib/module/ui/stores/followStore.js.map +1 -1
- package/lib/module/ui/stores/resetSessionScopedStores.js +11 -0
- package/lib/module/ui/stores/resetSessionScopedStores.js.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +1 -1
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/FollowButton.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/components/oxyAuthChooserStyles.d.ts +0 -19
- package/lib/typescript/commonjs/ui/components/oxyAuthChooserStyles.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/context/useOxyAccountGraph.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts +3 -0
- package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useFollow.d.ts +13 -2
- package/lib/typescript/commonjs/ui/hooks/useFollow.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/hooks/useSessionManagement.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/index.d.ts +1 -1
- package/lib/typescript/commonjs/ui/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/stores/followStore.d.ts +4 -1
- package/lib/typescript/commonjs/ui/stores/followStore.d.ts.map +1 -1
- package/lib/typescript/commonjs/ui/stores/resetSessionScopedStores.d.ts +3 -0
- package/lib/typescript/commonjs/ui/stores/resetSessionScopedStores.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +1 -1
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/FollowButton.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts.map +1 -1
- package/lib/typescript/module/ui/components/oxyAuthChooserStyles.d.ts +0 -19
- package/lib/typescript/module/ui/components/oxyAuthChooserStyles.d.ts.map +1 -1
- package/lib/typescript/module/ui/context/useOxyAccountGraph.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts +3 -0
- package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useFollow.d.ts +13 -2
- package/lib/typescript/module/ui/hooks/useFollow.d.ts.map +1 -1
- package/lib/typescript/module/ui/hooks/useSessionManagement.d.ts.map +1 -1
- package/lib/typescript/module/ui/index.d.ts +1 -1
- package/lib/typescript/module/ui/index.d.ts.map +1 -1
- package/lib/typescript/module/ui/stores/followStore.d.ts +4 -1
- package/lib/typescript/module/ui/stores/followStore.d.ts.map +1 -1
- package/lib/typescript/module/ui/stores/resetSessionScopedStores.d.ts +3 -0
- package/lib/typescript/module/ui/stores/resetSessionScopedStores.d.ts.map +1 -0
- package/package.json +5 -5
- package/src/index.ts +1 -1
- package/src/ui/components/FollowButton.tsx +22 -20
- package/src/ui/components/OxyAuthChooser.tsx +87 -75
- package/src/ui/components/oxyAuthChooserStyles.ts +0 -19
- package/src/ui/context/useOxyAccountGraph.ts +2 -0
- package/src/ui/hooks/useFollow.ts +51 -9
- package/src/ui/hooks/useSessionManagement.ts +2 -0
- package/src/ui/index.ts +1 -1
- package/src/ui/stores/__tests__/followStore.test.ts +178 -0
- package/src/ui/stores/followStore.ts +277 -106
- package/src/ui/stores/resetSessionScopedStores.ts +8 -0
package/lib/commonjs/index.js
CHANGED
|
@@ -501,6 +501,12 @@ Object.defineProperty(exports, "useSecurityInfo", {
|
|
|
501
501
|
return _useServicesQueries.useSecurityInfo;
|
|
502
502
|
}
|
|
503
503
|
});
|
|
504
|
+
Object.defineProperty(exports, "useSeedFollowStatuses", {
|
|
505
|
+
enumerable: true,
|
|
506
|
+
get: function () {
|
|
507
|
+
return _useFollow.useSeedFollowStatuses;
|
|
508
|
+
}
|
|
509
|
+
});
|
|
504
510
|
Object.defineProperty(exports, "useSession", {
|
|
505
511
|
enumerable: true,
|
|
506
512
|
get: function () {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_core","require","_reactNative","_OxyProvider","_interopRequireDefault","_OxyContext","_useAuth","_FontLoader","_authStore","_accountStore","_assetStore","_useAssets","_useFileDownloadUrl","_useFollow","_useStorage","_useAccountQueries","_useServicesQueries","_useSecurityQueries","_useAuthMethods","_usePaymentQueries","_useAccountMutations","_useServicesMutations","_mutationFactory","_mutationKeys","_queryKeys","_useMutationStatus","_useOnlineStatus","_useOxyEvent","_errorHandlers","_useFileFiltering","_OxySignInButton","_OxyAuthPrompt","_OxyOAuthCallback","_OxyConsentScreen","_RequireOxyAuth","_FollowButton","_OxyPayButton","_LogoIcon","_LogoText","_ProfileButton","_OxyAuthChooser","_useSwitchableAccounts","_ProfileScreen","_ManageAccountScreen","_NotificationsScreen","_PreferencesScreen","_ConnectedAppsScreen","_CreateAccountScreen","_AccountMembersScreen","_AccountSettingsScreen","_bottomSheetManager","_accountDialogManager","e","__esModule","default","setPlatformOS","Platform","OS"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"names":["_core","require","_reactNative","_OxyProvider","_interopRequireDefault","_OxyContext","_useAuth","_FontLoader","_authStore","_accountStore","_assetStore","_useAssets","_useFileDownloadUrl","_useFollow","_useStorage","_useAccountQueries","_useServicesQueries","_useSecurityQueries","_useAuthMethods","_usePaymentQueries","_useAccountMutations","_useServicesMutations","_mutationFactory","_mutationKeys","_queryKeys","_useMutationStatus","_useOnlineStatus","_useOxyEvent","_errorHandlers","_useFileFiltering","_OxySignInButton","_OxyAuthPrompt","_OxyOAuthCallback","_OxyConsentScreen","_RequireOxyAuth","_FollowButton","_OxyPayButton","_LogoIcon","_LogoText","_ProfileButton","_OxyAuthChooser","_useSwitchableAccounts","_ProfileScreen","_ManageAccountScreen","_NotificationsScreen","_PreferencesScreen","_ConnectedAppsScreen","_CreateAccountScreen","_AccountMembersScreen","_AccountSettingsScreen","_bottomSheetManager","_accountDialogManager","e","__esModule","default","setPlatformOS","Platform","OS"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -32,7 +32,7 @@ const isMultiMode = props => 'userIds' in props && Array.isArray(props.userIds);
|
|
|
32
32
|
const FollowButtonInner = /*#__PURE__*/(0, _react.memo)(function FollowButtonInner({
|
|
33
33
|
userId,
|
|
34
34
|
oxyServices,
|
|
35
|
-
initiallyFollowing
|
|
35
|
+
initiallyFollowing,
|
|
36
36
|
size = 'medium',
|
|
37
37
|
onFollowChange,
|
|
38
38
|
style,
|
|
@@ -46,17 +46,18 @@ const FollowButtonInner = /*#__PURE__*/(0, _react.memo)(function FollowButtonInn
|
|
|
46
46
|
} = (0, _theme.useTheme)();
|
|
47
47
|
const {
|
|
48
48
|
isFollowing,
|
|
49
|
+
isKnown,
|
|
49
50
|
isLoading,
|
|
50
51
|
toggleFollow,
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
} = (0, _useFollow.useFollowForButton)(userId, oxyServices);
|
|
52
|
+
resolveStatus
|
|
53
|
+
} = (0, _useFollow.useFollowForButton)(userId, oxyServices, initiallyFollowing);
|
|
54
54
|
const handlePress = (0, _react.useCallback)(async event => {
|
|
55
55
|
if (preventParentActions && event?.preventDefault) {
|
|
56
56
|
event.preventDefault();
|
|
57
57
|
event.stopPropagation?.();
|
|
58
58
|
}
|
|
59
|
-
|
|
59
|
+
// Ignore presses while a mutation is in flight or the status is still unknown.
|
|
60
|
+
if (disabled || isLoading || !isKnown) return;
|
|
60
61
|
try {
|
|
61
62
|
await toggleFollow();
|
|
62
63
|
onFollowChange?.(!isFollowing);
|
|
@@ -64,32 +65,36 @@ const FollowButtonInner = /*#__PURE__*/(0, _react.memo)(function FollowButtonInn
|
|
|
64
65
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
65
66
|
_bloom.toast.error(error.message || 'Failed to update follow status');
|
|
66
67
|
}
|
|
67
|
-
}, [disabled, isLoading, toggleFollow, onFollowChange, isFollowing, preventParentActions]);
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}, [userId, initiallyFollowing]);
|
|
68
|
+
}, [disabled, isLoading, isKnown, toggleFollow, onFollowChange, isFollowing, preventParentActions]);
|
|
69
|
+
|
|
70
|
+
// Enqueue a batched status fetch ONLY when the status is genuinely unknown
|
|
71
|
+
// (not seeded from `initiallyFollowing`, not already resolved). All buttons
|
|
72
|
+
// that enqueue in the same commit coalesce into a single bulk request; known/
|
|
73
|
+
// seeded ids never fetch. Once resolved, `isKnown` flips true and this no-ops.
|
|
74
74
|
(0, _react.useEffect)(() => {
|
|
75
|
-
if (
|
|
76
|
-
}, [
|
|
77
|
-
|
|
75
|
+
if (!isKnown) resolveStatus();
|
|
76
|
+
}, [isKnown, resolveStatus]);
|
|
77
|
+
|
|
78
|
+
// While the status is genuinely unknown (being resolved), present a NEUTRAL,
|
|
79
|
+
// non-interactive state rather than a definitive "Follow".
|
|
80
|
+
const isBusy = isLoading || !isKnown;
|
|
81
|
+
const showFollowing = isKnown && isFollowing;
|
|
82
|
+
const showSpinner = showLoadingState && isBusy;
|
|
78
83
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_button.Button, {
|
|
79
|
-
variant:
|
|
84
|
+
variant: showFollowing ? 'secondary' : 'primary',
|
|
80
85
|
size: size,
|
|
81
86
|
onPress: () => {
|
|
82
87
|
void handlePress();
|
|
83
88
|
},
|
|
84
|
-
disabled: disabled ||
|
|
89
|
+
disabled: disabled || isBusy,
|
|
85
90
|
style: style,
|
|
86
91
|
textStyle: textStyle,
|
|
87
92
|
icon: showSpinner ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_loading.Loading, {
|
|
88
93
|
variant: "inline",
|
|
89
94
|
size: "small",
|
|
90
|
-
color:
|
|
95
|
+
color: showFollowing ? colors.text : colors.primaryForeground
|
|
91
96
|
}) : undefined,
|
|
92
|
-
children: showSpinner ? undefined : isFollowing ? 'Following' : 'Follow'
|
|
97
|
+
children: showSpinner ? undefined : isKnown ? isFollowing ? 'Following' : 'Follow' : undefined
|
|
93
98
|
});
|
|
94
99
|
});
|
|
95
100
|
const FollowButtonMultiInner = /*#__PURE__*/(0, _react.memo)(function FollowButtonMultiInner({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_react","require","_OxyContext","_bloom","_button","_loading","_useFollow","_followStore","_theme","_shallow","_jsxRuntime","DEFAULT_FOLLOW_ALL_LABEL","DEFAULT_FOLLOWED_ALL_LABEL","isMultiMode","props","Array","isArray","userIds","FollowButtonInner","memo","userId","oxyServices","initiallyFollowing","size","onFollowChange","style","textStyle","disabled","showLoadingState","preventParentActions","colors","useTheme","isFollowing","
|
|
1
|
+
{"version":3,"names":["_react","require","_OxyContext","_bloom","_button","_loading","_useFollow","_followStore","_theme","_shallow","_jsxRuntime","DEFAULT_FOLLOW_ALL_LABEL","DEFAULT_FOLLOWED_ALL_LABEL","isMultiMode","props","Array","isArray","userIds","FollowButtonInner","memo","userId","oxyServices","initiallyFollowing","size","onFollowChange","style","textStyle","disabled","showLoadingState","preventParentActions","colors","useTheme","isFollowing","isKnown","isLoading","toggleFollow","resolveStatus","useFollowForButton","handlePress","useCallback","event","preventDefault","stopPropagation","err","error","Error","String","toast","message","useEffect","isBusy","showFollowing","showSpinner","jsx","Button","variant","onPress","icon","Loading","color","text","primaryForeground","undefined","children","FollowButtonMultiInner","initiallyAllFollowing","followAllLabel","followedAllLabel","onBulkFollow","onBulkUnfollow","follow","useFollow","followAllUsers","unfollowAllUsers","isAnyLoading","initialFollowStatuses","useFollowStore","useShallow","state","statuses","uid","Object","prototype","hasOwnProperty","call","followingUsers","hasKnownNotFollowing","some","storeAllFollowing","allFollowing","fetchAllStatuses","isSubmitting","setIsSubmitting","useState","userIdsKey","useMemo","join","result","allAlreadyFollowing","followedCount","results","length","every","entry","alreadyFollowing","anyFollowed","success","FollowButton","canUsePrivateApi","user","currentUser","useOxy","currentUserId","id","trim","rawUserIds","multiUserIds","seen","Set","cleaned","raw","has","add","push","targetUserId","exports","_default","default"],"sourceRoot":"../../../../src","sources":["ui/components/FollowButton.tsx"],"mappings":";;;;;;AACA,IAAAA,MAAA,GAAAC,OAAA;AAMA,IAAAC,WAAA,GAAAD,OAAA;AACA,IAAAE,MAAA,GAAAF,OAAA;AACA,IAAAG,OAAA,GAAAH,OAAA;AACA,IAAAI,QAAA,GAAAJ,OAAA;AACA,IAAAK,UAAA,GAAAL,OAAA;AACA,IAAAM,YAAA,GAAAN,OAAA;AACA,IAAAO,MAAA,GAAAP,OAAA;AAEA,IAAAQ,QAAA,GAAAR,OAAA;AAAmD,IAAAS,WAAA,GAAAT,OAAA;AAEnD,MAAMU,wBAAwB,GAAG,YAAY;AAC7C,MAAMC,0BAA0B,GAAG,WAAW;;AAE9C;;AAYA;;AAOA;;AAWA;AACA;AACA;AACA;;AAGA,MAAMC,WAAW,GAAIC,KAAwB,IAC3C,SAAS,IAAIA,KAAK,IAAIC,KAAK,CAACC,OAAO,CAACF,KAAK,CAACG,OAAO,CAAC;AAEpD,MAAMC,iBAAiB,gBAAG,IAAAC,WAAI,EAAC,SAASD,iBAAiBA,CAAC;EACxDE,MAAM;EACNC,WAAW;EACXC,kBAAkB;EAClBC,IAAI,GAAG,QAAQ;EACfC,cAAc;EACdC,KAAK;EACLC,SAAS;EACTC,QAAQ,GAAG,KAAK;EAChBC,gBAAgB,GAAG,IAAI;EACvBC,oBAAoB,GAAG;AAC+B,CAAC,EAAE;EACzD,MAAM;IAAEC;EAAO,CAAC,GAAG,IAAAC,eAAQ,EAAC,CAAC;EAE7B,MAAM;IACJC,WAAW;IACXC,OAAO;IACPC,SAAS;IACTC,YAAY;IACZC;EACF,CAAC,GAAG,IAAAC,6BAAkB,EAACjB,MAAM,EAAEC,WAAW,EAAEC,kBAAkB,CAAC;EAE/D,MAAMgB,WAAW,GAAG,IAAAC,kBAAW,EAAC,MAAOC,KAAqE,IAAK;IAC/G,IAAIX,oBAAoB,IAAIW,KAAK,EAAEC,cAAc,EAAE;MACjDD,KAAK,CAACC,cAAc,CAAC,CAAC;MACtBD,KAAK,CAACE,eAAe,GAAG,CAAC;IAC3B;IACA;IACA,IAAIf,QAAQ,IAAIO,SAAS,IAAI,CAACD,OAAO,EAAE;IAEvC,IAAI;MACF,MAAME,YAAY,CAAC,CAAC;MACpBX,cAAc,GAAG,CAACQ,WAAW,CAAC;IAChC,CAAC,CAAC,OAAOW,GAAY,EAAE;MACrB,MAAMC,KAAK,GAAGD,GAAG,YAAYE,KAAK,GAAGF,GAAG,GAAG,IAAIE,KAAK,CAACC,MAAM,CAACH,GAAG,CAAC,CAAC;MACjEI,YAAK,CAACH,KAAK,CAACA,KAAK,CAACI,OAAO,IAAI,gCAAgC,CAAC;IAChE;EACF,CAAC,EAAE,CAACrB,QAAQ,EAAEO,SAAS,EAAED,OAAO,EAAEE,YAAY,EAAEX,cAAc,EAAEQ,WAAW,EAAEH,oBAAoB,CAAC,CAAC;;EAEnG;EACA;EACA;EACA;EACA,IAAAoB,gBAAS,EAAC,MAAM;IACd,IAAI,CAAChB,OAAO,EAAEG,aAAa,CAAC,CAAC;EAC/B,CAAC,EAAE,CAACH,OAAO,EAAEG,aAAa,CAAC,CAAC;;EAE5B;EACA;EACA,MAAMc,MAAM,GAAGhB,SAAS,IAAI,CAACD,OAAO;EACpC,MAAMkB,aAAa,GAAGlB,OAAO,IAAID,WAAW;EAC5C,MAAMoB,WAAW,GAAGxB,gBAAgB,IAAIsB,MAAM;EAE9C,oBACE,IAAAxC,WAAA,CAAA2C,GAAA,EAACjD,OAAA,CAAAkD,MAAM;IACLC,OAAO,EAAEJ,aAAa,GAAG,WAAW,GAAG,SAAU;IACjD5B,IAAI,EAAEA,IAAK;IACXiC,OAAO,EAAEA,CAAA,KAAM;MAAE,KAAKlB,WAAW,CAAC,CAAC;IAAE,CAAE;IACvCX,QAAQ,EAAEA,QAAQ,IAAIuB,MAAO;IAC7BzB,KAAK,EAAEA,KAAM;IACbC,SAAS,EAAEA,SAAU;IACrB+B,IAAI,EAAEL,WAAW,gBACf,IAAA1C,WAAA,CAAA2C,GAAA,EAAChD,QAAA,CAAAqD,OAAO;MACNH,OAAO,EAAC,QAAQ;MAChBhC,IAAI,EAAC,OAAO;MACZoC,KAAK,EAAER,aAAa,GAAGrB,MAAM,CAAC8B,IAAI,GAAG9B,MAAM,CAAC+B;IAAkB,CAC/D,CAAC,GACAC,SAAU;IAAAC,QAAA,EAEbX,WAAW,GAAGU,SAAS,GAAI7B,OAAO,GAAID,WAAW,GAAG,WAAW,GAAG,QAAQ,GAAI8B;EAAU,CACnF,CAAC;AAEb,CAAC,CAAC;AAEF,MAAME,sBAAsB,gBAAG,IAAA7C,WAAI,EAAC,SAAS6C,sBAAsBA,CAAC;EAClE/C,OAAO;EACPgD,qBAAqB,GAAG,KAAK;EAC7B1C,IAAI,GAAG,QAAQ;EACf2C,cAAc,GAAGvD,wBAAwB;EACzCwD,gBAAgB,GAAGvD,0BAA0B;EAC7CY,cAAc;EACd4C,YAAY;EACZC,cAAc;EACd5C,KAAK;EACLC,SAAS;EACTC,QAAQ,GAAG,KAAK;EAChBC,gBAAgB,GAAG,IAAI;EACvBC,oBAAoB,GAAG;AACD,CAAC,EAAE;EACzB,MAAM;IAAEC;EAAO,CAAC,GAAG,IAAAC,eAAQ,EAAC,CAAC;EAC7B,MAAMuC,MAAM,GAAG,IAAAC,oBAAS,EAACtD,OAAO,CAAC;EACjC,MAAMuD,cAAc,GAAG,gBAAgB,IAAIF,MAAM,GAAGA,MAAM,CAACE,cAAc,GAAGV,SAAS;EACrF,MAAMW,gBAAgB,GAAG,kBAAkB,IAAIH,MAAM,GAAGA,MAAM,CAACG,gBAAgB,GAAGX,SAAS;EAC3F,MAAMY,YAAY,GAAG,cAAc,IAAIJ,MAAM,GAAGA,MAAM,CAACI,YAAY,GAAG,KAAK;EAE3E,MAAMC,qBAAqB,GAAG,IAAAC,2BAAc,EAC1C,IAAAC,mBAAU,EAAEC,KAAK,IAAK;IACpB,MAAMC,QAAwC,GAAG,CAAC,CAAC;IACnD,KAAK,MAAMC,GAAG,IAAI/D,OAAO,EAAE;MACzB8D,QAAQ,CAACC,GAAG,CAAC,GAAGC,MAAM,CAACC,SAAS,CAACC,cAAc,CAACC,IAAI,CAACN,KAAK,CAACO,cAAc,EAAEL,GAAG,CAAC,GAC3EF,KAAK,CAACO,cAAc,CAACL,GAAG,CAAC,GACzB,IAAI;IACV;IACA,OAAOD,QAAQ;EACjB,CAAC,CACH,CAAC;EAED,MAAMO,oBAAoB,GAAGrE,OAAO,CAACsE,IAAI,CAAEP,GAAG,IAAKL,qBAAqB,CAACK,GAAG,CAAC,KAAK,KAAK,CAAC;;EAExF;EACA;EACA;EACA;EACA;EACA,MAAMQ,iBAAiB,GAAG,cAAc,IAAIlB,MAAM,GAAGA,MAAM,CAACmB,YAAY,GAAG,KAAK;EAChF,MAAMA,YAAY,GAAGD,iBAAiB,IAAKvB,qBAAqB,IAAI,CAACqB,oBAAqB;EAC1F,MAAMI,gBAAgB,GAAG,kBAAkB,IAAIpB,MAAM,GAAGA,MAAM,CAACoB,gBAAgB,GAAG5B,SAAS;EAC3F,MAAM,CAAC6B,YAAY,EAAEC,eAAe,CAAC,GAAG,IAAAC,eAAQ,EAAC,KAAK,CAAC;EAEvD,MAAM3D,SAAS,GAAGyD,YAAY,IAAIjB,YAAY;;EAE9C;EACA;EACA;EACA;EACA;EACA;EACA;EACA,MAAMoB,UAAU,GAAG,IAAAC,cAAO,EAAC,MAAM9E,OAAO,CAAC+E,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC/E,OAAO,CAAC,CAAC;EAC9D,IAAAgC,gBAAS,EAAC,MAAM;IACdyC,gBAAgB,GAAG,CAAC;EACtB,CAAC,EAAE,CAACI,UAAU,EAAEJ,gBAAgB,CAAC,CAAC;EAElC,MAAMpD,WAAW,GAAG,IAAAC,kBAAW,EAAC,MAAOC,KAAqE,IAAK;IAC/G,IAAIX,oBAAoB,IAAIW,KAAK,EAAEC,cAAc,EAAE;MACjDD,KAAK,CAACC,cAAc,CAAC,CAAC;MACtBD,KAAK,CAACE,eAAe,GAAG,CAAC;IAC3B;IACA,IAAIf,QAAQ,IAAIO,SAAS,EAAE;IAE3B,IAAIuD,YAAY,EAAE;MAChB,IAAI,CAAChB,gBAAgB,EAAE;MACvBmB,eAAe,CAAC,IAAI,CAAC;MACrB,IAAI;QACF,MAAMK,MAAM,GAAG,MAAMxB,gBAAgB,CAAC,CAAC;QACvC;QACA;QACAjD,cAAc,GAAG,KAAK,CAAC;QACvB6C,cAAc,GAAG4B,MAAM,CAAC;MAC1B,CAAC,CAAC,OAAOtD,GAAY,EAAE;QACrB,MAAMC,KAAK,GAAGD,GAAG,YAAYE,KAAK,GAAGF,GAAG,GAAG,IAAIE,KAAK,CAACC,MAAM,CAACH,GAAG,CAAC,CAAC;QACjEI,YAAK,CAACH,KAAK,CAACA,KAAK,CAACI,OAAO,IAAI,gCAAgC,CAAC;MAChE,CAAC,SAAS;QACR4C,eAAe,CAAC,KAAK,CAAC;MACxB;MACA;IACF;IAEA,IAAI,CAACpB,cAAc,EAAE;IACrBoB,eAAe,CAAC,IAAI,CAAC;IACrB,IAAI;MACF,MAAMK,MAAM,GAAG,MAAMzB,cAAc,CAAC,CAAC;MACrC,MAAM0B,mBAAmB,GAAGD,MAAM,CAACE,aAAa,KAAK,CAAC,IACjDF,MAAM,CAACG,OAAO,CAACC,MAAM,GAAG,CAAC,IACzBJ,MAAM,CAACG,OAAO,CAACE,KAAK,CAAEC,KAAK,IAAKA,KAAK,CAACC,gBAAgB,CAAC;MAC5D,MAAMC,WAAW,GAAGR,MAAM,CAACE,aAAa,GAAG,CAAC,IACvCF,MAAM,CAACG,OAAO,CAACb,IAAI,CAAEgB,KAAK,IAAKA,KAAK,CAACG,OAAO,IAAIH,KAAK,CAACC,gBAAgB,CAAC;;MAE5E;MACA;MACA,IAAIN,mBAAmB,IAAIO,WAAW,EAAE;QACtCjF,cAAc,GAAG,IAAI,CAAC;MACxB;MACA4C,YAAY,GAAG6B,MAAM,CAAC;IACxB,CAAC,CAAC,OAAOtD,GAAY,EAAE;MACrB,MAAMC,KAAK,GAAGD,GAAG,YAAYE,KAAK,GAAGF,GAAG,GAAG,IAAIE,KAAK,CAACC,MAAM,CAACH,GAAG,CAAC,CAAC;MACjEI,YAAK,CAACH,KAAK,CAACA,KAAK,CAACI,OAAO,IAAI,gCAAgC,CAAC;IAChE,CAAC,SAAS;MACR4C,eAAe,CAAC,KAAK,CAAC;IACxB;EACF,CAAC,EAAE,CAACjE,QAAQ,EAAEO,SAAS,EAAEuD,YAAY,EAAEjB,cAAc,EAAEC,gBAAgB,EAAEjD,cAAc,EAAE4C,YAAY,EAAEC,cAAc,EAAExC,oBAAoB,CAAC,CAAC;EAE7I,MAAMuB,WAAW,GAAGxB,gBAAgB,IAAIM,SAAS;EAEjD,oBACE,IAAAxB,WAAA,CAAA2C,GAAA,EAACjD,OAAA,CAAAkD,MAAM;IACLC,OAAO,EAAEkC,YAAY,GAAG,WAAW,GAAG,SAAU;IAChDlE,IAAI,EAAEA,IAAK;IACXiC,OAAO,EAAEA,CAAA,KAAM;MAAE,KAAKlB,WAAW,CAAC,CAAC;IAAE,CAAE;IACvCX,QAAQ,EAAEA,QAAQ,IAAIO,SAAU;IAChCT,KAAK,EAAEA,KAAM;IACbC,SAAS,EAAEA,SAAU;IACrB+B,IAAI,EAAEL,WAAW,gBACf,IAAA1C,WAAA,CAAA2C,GAAA,EAAChD,QAAA,CAAAqD,OAAO;MACNH,OAAO,EAAC,QAAQ;MAChBhC,IAAI,EAAC,OAAO;MACZoC,KAAK,EAAE8B,YAAY,GAAG3D,MAAM,CAAC8B,IAAI,GAAG9B,MAAM,CAAC+B;IAAkB,CAC9D,CAAC,GACAC,SAAU;IAAAC,QAAA,EAEbX,WAAW,GAAGU,SAAS,GAAI2B,YAAY,GAAGtB,gBAAgB,GAAGD;EAAe,CACvE,CAAC;AAEb,CAAC,CAAC;AAEF,MAAMyC,YAAyC,GAAI7F,KAAK,IAAK;EAC3D,MAAM;IAAEO,WAAW;IAAEuF,gBAAgB;IAAEC,IAAI,EAAEC;EAAY,CAAC,GAAG,IAAAC,kBAAM,EAAC,CAAC;EAErE,MAAMC,aAAa,GAAGF,WAAW,EAAEG,EAAE,GAAGnE,MAAM,CAACgE,WAAW,CAACG,EAAE,CAAC,CAACC,IAAI,CAAC,CAAC,GAAG,EAAE;EAE1E,MAAMC,UAAU,GAAGtG,WAAW,CAACC,KAAK,CAAC,GAAGA,KAAK,CAACG,OAAO,GAAG,IAAI;;EAE5D;EACA,MAAMmG,YAAY,GAAG,IAAArB,cAAO,EAAC,MAAM;IACjC,IAAI,CAACoB,UAAU,EAAE,OAAO,EAAE;IAC1B,MAAME,IAAI,GAAG,IAAIC,GAAG,CAAS,CAAC;IAC9B,MAAMC,OAAiB,GAAG,EAAE;IAC5B,KAAK,MAAMC,GAAG,IAAIL,UAAU,EAAE;MAC5B,MAAMF,EAAE,GAAGO,GAAG,GAAG1E,MAAM,CAAC0E,GAAG,CAAC,CAACN,IAAI,CAAC,CAAC,GAAG,EAAE;MACxC,IAAI,CAACD,EAAE,IAAIA,EAAE,KAAKD,aAAa,IAAIK,IAAI,CAACI,GAAG,CAACR,EAAE,CAAC,EAAE;MACjDI,IAAI,CAACK,GAAG,CAACT,EAAE,CAAC;MACZM,OAAO,CAACI,IAAI,CAACV,EAAE,CAAC;IAClB;IACA,OAAOM,OAAO;EAChB,CAAC,EAAE,CAACJ,UAAU,EAAEH,aAAa,CAAC,CAAC;EAE/B,IAAI,CAACJ,gBAAgB,EAAE;IACrB,OAAO,IAAI;EACb;EAEA,IAAI/F,WAAW,CAACC,KAAK,CAAC,EAAE;IACtB,IAAIsG,YAAY,CAACf,MAAM,KAAK,CAAC,EAAE;MAC7B,OAAO,IAAI;IACb;IACA,oBACE,IAAA3F,WAAA,CAAA2C,GAAA,EAACW,sBAAsB;MAAA,GACjBlD,KAAK;MACTG,OAAO,EAAEmG;IAAa,CACvB,CAAC;EAEN;EAEA,MAAMQ,YAAY,GAAG9G,KAAK,CAACM,MAAM,GAAG0B,MAAM,CAAChC,KAAK,CAACM,MAAM,CAAC,CAAC8F,IAAI,CAAC,CAAC,GAAG,EAAE;EACpE,IAAI,CAACU,YAAY,IAAKZ,aAAa,IAAIA,aAAa,KAAKY,YAAa,EAAE;IACtE,OAAO,IAAI;EACb;EAEA,oBACE,IAAAlH,WAAA,CAAA2C,GAAA,EAACnC,iBAAiB;IAAA,GACZJ,KAAK;IACTM,MAAM,EAAEwG,YAAa;IACrBvG,WAAW,EAAEA;EAAY,CAC1B,CAAC;AAEN,CAAC;AAACwG,OAAA,CAAAlB,YAAA,GAAAA,YAAA;AAAA,IAAAmB,QAAA,GAAAD,OAAA,CAAAE,OAAA,GAGapB,YAAY","ignoreList":[]}
|
|
@@ -10,6 +10,7 @@ var _vectorIcons = require("@expo/vector-icons");
|
|
|
10
10
|
var _reactNativeQrcodeSvg = _interopRequireDefault(require("react-native-qrcode-svg"));
|
|
11
11
|
var _avatar = require("@oxyhq/bloom/avatar");
|
|
12
12
|
var _button = require("@oxyhq/bloom/button");
|
|
13
|
+
var _bloom = require("@oxyhq/bloom");
|
|
13
14
|
var _typography = require("@oxyhq/bloom/typography");
|
|
14
15
|
var _theme = require("@oxyhq/bloom/theme");
|
|
15
16
|
var _core = require("@oxyhq/core");
|
|
@@ -129,39 +130,36 @@ const OxyAuthChooser = ({
|
|
|
129
130
|
}, []);
|
|
130
131
|
const passkeyAvailable = passkeyMode !== 'none';
|
|
131
132
|
const [signInPasskeyPending, setSignInPasskeyPending] = (0, _react.useState)(false);
|
|
132
|
-
const [signInPasskeyError, setSignInPasskeyError] = (0, _react.useState)(null);
|
|
133
133
|
const handleSignInWithPasskey = (0, _react.useCallback)(async () => {
|
|
134
134
|
if (signInPasskeyPending) return;
|
|
135
135
|
setSignInPasskeyPending(true);
|
|
136
|
-
setSignInPasskeyError(null);
|
|
137
136
|
try {
|
|
138
137
|
await signInWithPasskey();
|
|
139
138
|
onComplete?.();
|
|
140
139
|
} catch (error) {
|
|
141
140
|
// A cancelled/failed ceremony keeps the view open so the user can retry
|
|
142
|
-
// or fall back to the QR — surface a
|
|
143
|
-
|
|
141
|
+
// or fall back to the QR — surface the reason as a toast (owner mandate:
|
|
142
|
+
// errors never render inline inside the dialog), never swallow.
|
|
143
|
+
_bloom.toast.error(error instanceof Error && error.message ? error.message : t('accountSwitcher.toasts.passkeySignInFailed') || 'Passkey sign-in failed.');
|
|
144
144
|
} finally {
|
|
145
145
|
setSignInPasskeyPending(false);
|
|
146
146
|
}
|
|
147
|
-
}, [signInPasskeyPending, signInWithPasskey, onComplete]);
|
|
147
|
+
}, [signInPasskeyPending, signInWithPasskey, onComplete, t]);
|
|
148
148
|
const [createPasskeyPending, setCreatePasskeyPending] = (0, _react.useState)(false);
|
|
149
|
-
const [createPasskeyError, setCreatePasskeyError] = (0, _react.useState)(null);
|
|
150
149
|
const handleCreateWithPasskey = (0, _react.useCallback)(async username => {
|
|
151
150
|
if (createPasskeyPending) return;
|
|
152
151
|
setCreatePasskeyPending(true);
|
|
153
|
-
setCreatePasskeyError(null);
|
|
154
152
|
try {
|
|
155
153
|
await registerWithPasskey({
|
|
156
154
|
username
|
|
157
155
|
});
|
|
158
156
|
onComplete?.();
|
|
159
157
|
} catch (error) {
|
|
160
|
-
|
|
158
|
+
_bloom.toast.error(error instanceof Error && error.message ? error.message : t('signup.toasts.passkeyCreateFailed') || 'Account creation failed.');
|
|
161
159
|
} finally {
|
|
162
160
|
setCreatePasskeyPending(false);
|
|
163
161
|
}
|
|
164
|
-
}, [createPasskeyPending, registerWithPasskey, onComplete]);
|
|
162
|
+
}, [createPasskeyPending, registerWithPasskey, onComplete, t]);
|
|
165
163
|
|
|
166
164
|
// Bind the headless controller. `getSnapshot` returns a stable reference
|
|
167
165
|
// between changes, so it is `useSyncExternalStore`-safe. Guard the no-provider
|
|
@@ -173,6 +171,28 @@ const OxyAuthChooser = ({
|
|
|
173
171
|
view
|
|
174
172
|
} = snapshot;
|
|
175
173
|
|
|
174
|
+
// Sign-in device-flow failures land on `snapshot.signIn` asynchronously (poll /
|
|
175
|
+
// socket / popup cancel). Toast at the controller notification site — never an
|
|
176
|
+
// inline banner in the QR view (owner mandate, same contract as account-switch).
|
|
177
|
+
(0, _react.useEffect)(() => {
|
|
178
|
+
if (!controller) return;
|
|
179
|
+
let lastToastedSignInError = null;
|
|
180
|
+
const maybeToastSignInError = () => {
|
|
181
|
+
const {
|
|
182
|
+
signIn
|
|
183
|
+
} = controller.getSnapshot();
|
|
184
|
+
if (signIn.phase === 'error' && signIn.error && signIn.error !== lastToastedSignInError) {
|
|
185
|
+
lastToastedSignInError = signIn.error;
|
|
186
|
+
_bloom.toast.error(signIn.error || t('accountSwitcher.toasts.signInFailed') || 'Sign-in failed. Please try again.');
|
|
187
|
+
}
|
|
188
|
+
if (signIn.phase !== 'error') {
|
|
189
|
+
lastToastedSignInError = null;
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
maybeToastSignInError();
|
|
193
|
+
return controller.subscribe(maybeToastSignInError);
|
|
194
|
+
}, [controller, t]);
|
|
195
|
+
|
|
176
196
|
// Web: "Sign in with Oxy" auto-starts the instant the sign-in entry is
|
|
177
197
|
// reached — no button tap needed. `signInWithOxy()` tries the shared
|
|
178
198
|
// keychain first (silently, native-only) then falls to the QR handoff,
|
|
@@ -196,19 +216,24 @@ const OxyAuthChooser = ({
|
|
|
196
216
|
setSwitching(true);
|
|
197
217
|
try {
|
|
198
218
|
await controller.switchTo(accountId);
|
|
199
|
-
//
|
|
200
|
-
//
|
|
201
|
-
//
|
|
202
|
-
//
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
219
|
+
// `switchTo` never throws — it records a failure on the controller's
|
|
220
|
+
// snapshot. Read it back at the point the switch settles and surface it
|
|
221
|
+
// as a toast (event-driven, at the failure site — NOT an inline banner
|
|
222
|
+
// and NOT a snapshot-reaction). On success reload the app's account
|
|
223
|
+
// graph and drop cached account-scoped data so the new active identity
|
|
224
|
+
// re-fetches — the same side effects the context's own
|
|
225
|
+
// `switchToAccount` performs.
|
|
226
|
+
if (controller.getSnapshot().error) {
|
|
227
|
+
_bloom.toast.error(t('accountSwitcher.toasts.switchFailed') || 'There was a problem switching accounts. Please try again.');
|
|
228
|
+
return;
|
|
207
229
|
}
|
|
230
|
+
void refreshAccounts();
|
|
231
|
+
queryClient.invalidateQueries();
|
|
232
|
+
onComplete?.();
|
|
208
233
|
} finally {
|
|
209
234
|
setSwitching(false);
|
|
210
235
|
}
|
|
211
|
-
}, [controller, switching, snapshot.activeAccountId, onComplete, refreshAccounts, queryClient]);
|
|
236
|
+
}, [controller, switching, snapshot.activeAccountId, onComplete, refreshAccounts, queryClient, t]);
|
|
212
237
|
const handleManage = (0, _react.useCallback)(() => {
|
|
213
238
|
onComplete?.();
|
|
214
239
|
showBottomSheet?.('ManageAccount');
|
|
@@ -239,12 +264,12 @@ const OxyAuthChooser = ({
|
|
|
239
264
|
onRetry: () => void controller.showQr(),
|
|
240
265
|
passkeyAvailable: passkeyAvailable,
|
|
241
266
|
onSignInWithPasskey: passkeyMode === 'direct' ? () => void handleSignInWithPasskey() : () => void controller.startPasskeyHubSignIn()
|
|
242
|
-
// The hub-popup flow's pending
|
|
243
|
-
//
|
|
244
|
-
//
|
|
267
|
+
// The hub-popup flow's pending state is `snapshot.signIn` (already
|
|
268
|
+
// rendered elsewhere in this view) — only the DIRECT ceremony uses this
|
|
269
|
+
// component-local pending flag. A ceremony FAILURE is surfaced as a
|
|
270
|
+
// toast by `handleSignInWithPasskey`, never inline.
|
|
245
271
|
,
|
|
246
272
|
passkeyPending: passkeyMode === 'direct' ? signInPasskeyPending : false,
|
|
247
|
-
passkeyError: passkeyMode === 'direct' ? signInPasskeyError : null,
|
|
248
273
|
onCreateAccount: () => controller.startSignup()
|
|
249
274
|
});
|
|
250
275
|
}
|
|
@@ -257,7 +282,6 @@ const OxyAuthChooser = ({
|
|
|
257
282
|
passkeyMode: passkeyMode,
|
|
258
283
|
onCreateWithPasskey: handleCreateWithPasskey,
|
|
259
284
|
createPending: createPasskeyPending,
|
|
260
|
-
createError: createPasskeyError,
|
|
261
285
|
onOpenHub: () => void controller.startPasskeyHubSignIn(),
|
|
262
286
|
onBackToSignIn: () => controller.setView('signin')
|
|
263
287
|
});
|
|
@@ -277,33 +301,6 @@ const OxyAuthChooser = ({
|
|
|
277
301
|
// Accounts view
|
|
278
302
|
// ---------------------------------------------------------------------------
|
|
279
303
|
|
|
280
|
-
/**
|
|
281
|
-
* Inline error banner for `snapshot.error` (the account-list / switch-failure
|
|
282
|
-
* error — distinct from `snapshot.signIn.error`, which `QrView` already
|
|
283
|
-
* renders). `AccountsView` and `SignInView` previously swallowed it: a
|
|
284
|
-
* blocked/failed switch left the user with no feedback outside the QR view.
|
|
285
|
-
*/
|
|
286
|
-
const ErrorBanner = ({
|
|
287
|
-
error,
|
|
288
|
-
theme
|
|
289
|
-
}) => {
|
|
290
|
-
if (!error) return null;
|
|
291
|
-
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
292
|
-
style: [_oxyAuthChooserStyles.authChooserStyles.errorBanner, {
|
|
293
|
-
backgroundColor: theme.colors.negativeSubtle
|
|
294
|
-
}],
|
|
295
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_vectorIcons.MaterialCommunityIcons, {
|
|
296
|
-
name: "alert-circle-outline",
|
|
297
|
-
size: 18,
|
|
298
|
-
color: theme.colors.error
|
|
299
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_typography.Text, {
|
|
300
|
-
style: [_oxyAuthChooserStyles.authChooserStyles.errorBannerText, {
|
|
301
|
-
color: theme.colors.error
|
|
302
|
-
}],
|
|
303
|
-
children: error
|
|
304
|
-
})]
|
|
305
|
-
});
|
|
306
|
-
};
|
|
307
304
|
const AccountsView = ({
|
|
308
305
|
snapshot,
|
|
309
306
|
theme,
|
|
@@ -327,10 +324,7 @@ const AccountsView = ({
|
|
|
327
324
|
}
|
|
328
325
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
329
326
|
style: _oxyAuthChooserStyles.authChooserStyles.rows,
|
|
330
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
331
|
-
error: snapshot.error,
|
|
332
|
-
theme: theme
|
|
333
|
-
}), snapshot.accounts.map(account => /*#__PURE__*/(0, _jsxRuntime.jsx)(AccountRow, {
|
|
327
|
+
children: [snapshot.accounts.map(account => /*#__PURE__*/(0, _jsxRuntime.jsx)(AccountRow, {
|
|
334
328
|
account: account,
|
|
335
329
|
theme: theme,
|
|
336
330
|
switching: snapshot.switchingAccountId === account.accountId,
|
|
@@ -456,10 +450,7 @@ const SignInView = ({
|
|
|
456
450
|
onCreateAccount
|
|
457
451
|
}) => /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
458
452
|
style: _oxyAuthChooserStyles.authChooserStyles.signInBlock,
|
|
459
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.
|
|
460
|
-
error: snapshot.error,
|
|
461
|
-
theme: theme
|
|
462
|
-
}), snapshot.accounts.length > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
453
|
+
children: [snapshot.accounts.length > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
463
454
|
style: _oxyAuthChooserStyles.authChooserStyles.rows,
|
|
464
455
|
children: [snapshot.accounts.map(account => /*#__PURE__*/(0, _jsxRuntime.jsx)(AccountRow, {
|
|
465
456
|
account: account,
|
|
@@ -560,7 +551,6 @@ const QrView = ({
|
|
|
560
551
|
passkeyAvailable,
|
|
561
552
|
onSignInWithPasskey,
|
|
562
553
|
passkeyPending,
|
|
563
|
-
passkeyError,
|
|
564
554
|
onCreateAccount
|
|
565
555
|
}) => {
|
|
566
556
|
const {
|
|
@@ -568,25 +558,21 @@ const QrView = ({
|
|
|
568
558
|
commonsAvailability
|
|
569
559
|
} = snapshot;
|
|
570
560
|
const [showQrAnyway, setShowQrAnyway] = (0, _react.useState)(false);
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
})
|
|
584
|
-
}), passkeyError ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_typography.Text, {
|
|
585
|
-
style: [_oxyAuthChooserStyles.authChooserStyles.errorText, {
|
|
586
|
-
color: theme.colors.error
|
|
561
|
+
|
|
562
|
+
// A ceremony FAILURE is surfaced as a toast by `handleSignInWithPasskey` — the
|
|
563
|
+
// link itself never renders an inline error (owner mandate).
|
|
564
|
+
const passkeyLink = passkeyAvailable && signIn.phase !== 'authorized' ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
|
|
565
|
+
onPress: onSignInWithPasskey,
|
|
566
|
+
disabled: passkeyPending,
|
|
567
|
+
accessibilityRole: "button",
|
|
568
|
+
style: _oxyAuthChooserStyles.authChooserStyles.footerLink,
|
|
569
|
+
testID: "passkey-signin-link",
|
|
570
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_typography.Text, {
|
|
571
|
+
style: [_oxyAuthChooserStyles.authChooserStyles.linkText, {
|
|
572
|
+
color: theme.colors.textSecondary
|
|
587
573
|
}],
|
|
588
|
-
children:
|
|
589
|
-
})
|
|
574
|
+
children: passkeyPending ? t('accountSwitcher.passkeySigningIn') || 'Signing in…' : t('accountSwitcher.useIdentityOnDevice') || 'No Commons? Use a passkey on this device instead'
|
|
575
|
+
})
|
|
590
576
|
}) : null;
|
|
591
577
|
|
|
592
578
|
// Native, Commons confirmed NOT installed: a same-device QR is a dead
|
|
@@ -623,14 +609,11 @@ const QrView = ({
|
|
|
623
609
|
});
|
|
624
610
|
}
|
|
625
611
|
if (signIn.phase === 'error') {
|
|
612
|
+
// The failure reason is toasted by the controller subscription above — no
|
|
613
|
+
// inline error copy here (owner mandate).
|
|
626
614
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
627
615
|
style: _oxyAuthChooserStyles.authChooserStyles.centeredBlock,
|
|
628
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
629
|
-
style: [_oxyAuthChooserStyles.authChooserStyles.errorText, {
|
|
630
|
-
color: theme.colors.error
|
|
631
|
-
}],
|
|
632
|
-
children: signIn.error || 'Sign-in failed. Please try again.'
|
|
633
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_button.Button, {
|
|
616
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_button.Button, {
|
|
634
617
|
variant: "secondary",
|
|
635
618
|
onPress: onRetry,
|
|
636
619
|
style: _oxyAuthChooserStyles.authChooserStyles.secondaryButton,
|
|
@@ -687,7 +670,7 @@ const QrView = ({
|
|
|
687
670
|
// ---------------------------------------------------------------------------
|
|
688
671
|
|
|
689
672
|
/** Debounced username-availability check over the existing SDK method. */
|
|
690
|
-
function useUsernameAvailability(oxyServices) {
|
|
673
|
+
function useUsernameAvailability(oxyServices, t) {
|
|
691
674
|
const [status, setStatus] = (0, _react.useState)('idle');
|
|
692
675
|
const timerRef = (0, _react.useRef)(null);
|
|
693
676
|
const requestSeqRef = (0, _react.useRef)(0);
|
|
@@ -705,10 +688,13 @@ function useUsernameAvailability(oxyServices) {
|
|
|
705
688
|
setStatus(result.available ? 'available' : 'taken');
|
|
706
689
|
}).catch(() => {
|
|
707
690
|
if (seq !== requestSeqRef.current) return;
|
|
708
|
-
|
|
691
|
+
// Reset the (now stale) verdict rather than block on it, and surface
|
|
692
|
+
// the failure as a toast — never an inline error inside the dialog.
|
|
693
|
+
setStatus('idle');
|
|
694
|
+
_bloom.toast.error(t('accounts.create.username.checkFailed') || 'Could not check availability');
|
|
709
695
|
});
|
|
710
696
|
}, 400);
|
|
711
|
-
}, [oxyServices]);
|
|
697
|
+
}, [oxyServices, t]);
|
|
712
698
|
return {
|
|
713
699
|
status,
|
|
714
700
|
check
|
|
@@ -751,7 +737,6 @@ const SignUpView = ({
|
|
|
751
737
|
passkeyMode,
|
|
752
738
|
onCreateWithPasskey,
|
|
753
739
|
createPending,
|
|
754
|
-
createError,
|
|
755
740
|
onOpenHub,
|
|
756
741
|
onBackToSignIn
|
|
757
742
|
}) => {
|
|
@@ -759,7 +744,7 @@ const SignUpView = ({
|
|
|
759
744
|
const {
|
|
760
745
|
status: usernameStatus,
|
|
761
746
|
check: checkUsername
|
|
762
|
-
} = useUsernameAvailability(oxyServices);
|
|
747
|
+
} = useUsernameAvailability(oxyServices, t);
|
|
763
748
|
const canSubmit = username.trim().length >= 3 && usernameStatus === 'available' && !createPending;
|
|
764
749
|
|
|
765
750
|
// Native — Commons owns identity creation. Mirrors the QR view's own
|
|
@@ -833,12 +818,7 @@ const SignUpView = ({
|
|
|
833
818
|
status: usernameStatus,
|
|
834
819
|
theme: theme,
|
|
835
820
|
t: t
|
|
836
|
-
}),
|
|
837
|
-
style: [_oxyAuthChooserStyles.authChooserStyles.errorText, {
|
|
838
|
-
color: theme.colors.error
|
|
839
|
-
}],
|
|
840
|
-
children: createError
|
|
841
|
-
}) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_button.Button, {
|
|
821
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_button.Button, {
|
|
842
822
|
variant: "secondary",
|
|
843
823
|
onPress: () => void onCreateWithPasskey(username.trim()),
|
|
844
824
|
disabled: !canSubmit,
|