@oxy.so/services 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/README.md +1 -1
  2. package/lib/commonjs/ui/components/BenefitList.js +93 -0
  3. package/lib/commonjs/ui/components/BenefitList.js.map +1 -0
  4. package/lib/commonjs/ui/components/FollowTargetButton.js +1 -1
  5. package/lib/commonjs/ui/components/FollowTargetButton.js.map +1 -1
  6. package/lib/commonjs/ui/components/OxyAuthChooser.js +95 -140
  7. package/lib/commonjs/ui/components/OxyAuthChooser.js.map +1 -1
  8. package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js +8 -1
  9. package/lib/commonjs/ui/components/authChooser/AccountsMenuView.js.map +1 -1
  10. package/lib/commonjs/ui/components/authChooser/SignInEntryView.js +35 -25
  11. package/lib/commonjs/ui/components/authChooser/SignInEntryView.js.map +1 -1
  12. package/lib/commonjs/ui/components/authChooser/SignInRequestView.js +2 -3
  13. package/lib/commonjs/ui/components/authChooser/SignInRequestView.js.map +1 -1
  14. package/lib/commonjs/ui/components/authChooser/SignUpView.js +12 -127
  15. package/lib/commonjs/ui/components/authChooser/SignUpView.js.map +1 -1
  16. package/lib/commonjs/ui/components/authChooser/signInFailureMessage.js +40 -0
  17. package/lib/commonjs/ui/components/authChooser/signInFailureMessage.js.map +1 -0
  18. package/lib/commonjs/ui/components/authChooser/types.js +4 -6
  19. package/lib/commonjs/ui/components/authChooser/types.js.map +1 -1
  20. package/lib/commonjs/ui/context/OxyContext.js +1 -17
  21. package/lib/commonjs/ui/context/OxyContext.js.map +1 -1
  22. package/lib/commonjs/ui/context/hooks/useAuthOperations.js +15 -2
  23. package/lib/commonjs/ui/context/hooks/useAuthOperations.js.map +1 -1
  24. package/lib/commonjs/ui/context/passkeyFlow.js +2 -28
  25. package/lib/commonjs/ui/context/passkeyFlow.js.map +1 -1
  26. package/lib/commonjs/ui/hooks/accountDialogSnapshot.js +3 -1
  27. package/lib/commonjs/ui/hooks/accountDialogSnapshot.js.map +1 -1
  28. package/lib/commonjs/ui/hooks/useProfileEditing.js +14 -0
  29. package/lib/commonjs/ui/hooks/useProfileEditing.js.map +1 -1
  30. package/lib/commonjs/ui/screens/AccountVerificationScreen.js +10 -10
  31. package/lib/commonjs/ui/screens/AccountVerificationScreen.js.map +1 -1
  32. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js +225 -9
  33. package/lib/commonjs/ui/screens/EditProfileFieldScreen.js.map +1 -1
  34. package/lib/commonjs/ui/screens/LearnMoreUsernamesScreen.js +6 -6
  35. package/lib/commonjs/ui/screens/LearnMoreUsernamesScreen.js.map +1 -1
  36. package/lib/commonjs/ui/screens/ManageAccountScreen.js +10 -0
  37. package/lib/commonjs/ui/screens/ManageAccountScreen.js.map +1 -1
  38. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js +5 -5
  39. package/lib/commonjs/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  40. package/lib/commonjs/ui/screens/trust/TrustAboutScreen.js +13 -13
  41. package/lib/commonjs/ui/screens/trust/TrustAboutScreen.js.map +1 -1
  42. package/lib/module/ui/components/BenefitList.js +89 -0
  43. package/lib/module/ui/components/BenefitList.js.map +1 -0
  44. package/lib/module/ui/components/FollowTargetButton.js +1 -1
  45. package/lib/module/ui/components/FollowTargetButton.js.map +1 -1
  46. package/lib/module/ui/components/OxyAuthChooser.js +97 -142
  47. package/lib/module/ui/components/OxyAuthChooser.js.map +1 -1
  48. package/lib/module/ui/components/authChooser/AccountsMenuView.js +8 -1
  49. package/lib/module/ui/components/authChooser/AccountsMenuView.js.map +1 -1
  50. package/lib/module/ui/components/authChooser/SignInEntryView.js +35 -25
  51. package/lib/module/ui/components/authChooser/SignInEntryView.js.map +1 -1
  52. package/lib/module/ui/components/authChooser/SignInRequestView.js +2 -3
  53. package/lib/module/ui/components/authChooser/SignInRequestView.js.map +1 -1
  54. package/lib/module/ui/components/authChooser/SignUpView.js +14 -129
  55. package/lib/module/ui/components/authChooser/SignUpView.js.map +1 -1
  56. package/lib/module/ui/components/authChooser/signInFailureMessage.js +36 -0
  57. package/lib/module/ui/components/authChooser/signInFailureMessage.js.map +1 -0
  58. package/lib/module/ui/components/authChooser/types.js +4 -6
  59. package/lib/module/ui/components/authChooser/types.js.map +1 -1
  60. package/lib/module/ui/context/OxyContext.js +2 -18
  61. package/lib/module/ui/context/OxyContext.js.map +1 -1
  62. package/lib/module/ui/context/hooks/useAuthOperations.js +15 -2
  63. package/lib/module/ui/context/hooks/useAuthOperations.js.map +1 -1
  64. package/lib/module/ui/context/passkeyFlow.js +2 -27
  65. package/lib/module/ui/context/passkeyFlow.js.map +1 -1
  66. package/lib/module/ui/hooks/accountDialogSnapshot.js +3 -1
  67. package/lib/module/ui/hooks/accountDialogSnapshot.js.map +1 -1
  68. package/lib/module/ui/hooks/useProfileEditing.js +14 -0
  69. package/lib/module/ui/hooks/useProfileEditing.js.map +1 -1
  70. package/lib/module/ui/screens/AccountVerificationScreen.js +6 -6
  71. package/lib/module/ui/screens/AccountVerificationScreen.js.map +1 -1
  72. package/lib/module/ui/screens/EditProfileFieldScreen.js +225 -9
  73. package/lib/module/ui/screens/EditProfileFieldScreen.js.map +1 -1
  74. package/lib/module/ui/screens/LearnMoreUsernamesScreen.js +6 -6
  75. package/lib/module/ui/screens/LearnMoreUsernamesScreen.js.map +1 -1
  76. package/lib/module/ui/screens/ManageAccountScreen.js +12 -2
  77. package/lib/module/ui/screens/ManageAccountScreen.js.map +1 -1
  78. package/lib/module/ui/screens/PremiumSubscriptionScreen.js +1 -1
  79. package/lib/module/ui/screens/PremiumSubscriptionScreen.js.map +1 -1
  80. package/lib/module/ui/screens/trust/TrustAboutScreen.js +7 -7
  81. package/lib/module/ui/screens/trust/TrustAboutScreen.js.map +1 -1
  82. package/lib/typescript/commonjs/index.d.ts +1 -1
  83. package/lib/typescript/commonjs/index.d.ts.map +1 -1
  84. package/lib/typescript/commonjs/ui/components/BenefitList.d.ts +25 -0
  85. package/lib/typescript/commonjs/ui/components/BenefitList.d.ts.map +1 -0
  86. package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts +3 -4
  87. package/lib/typescript/commonjs/ui/components/OxyAuthChooser.d.ts.map +1 -1
  88. package/lib/typescript/commonjs/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
  89. package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts +11 -12
  90. package/lib/typescript/commonjs/ui/components/authChooser/SignInEntryView.d.ts.map +1 -1
  91. package/lib/typescript/commonjs/ui/components/authChooser/SignInRequestView.d.ts.map +1 -1
  92. package/lib/typescript/commonjs/ui/components/authChooser/SignUpView.d.ts +10 -13
  93. package/lib/typescript/commonjs/ui/components/authChooser/SignUpView.d.ts.map +1 -1
  94. package/lib/typescript/commonjs/ui/components/authChooser/signInFailureMessage.d.ts +16 -0
  95. package/lib/typescript/commonjs/ui/components/authChooser/signInFailureMessage.d.ts.map +1 -0
  96. package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts +11 -13
  97. package/lib/typescript/commonjs/ui/components/authChooser/types.d.ts.map +1 -1
  98. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts +1 -1
  99. package/lib/typescript/commonjs/ui/context/OxyContext.d.ts.map +1 -1
  100. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts +3 -2
  101. package/lib/typescript/commonjs/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  102. package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts +20 -10
  103. package/lib/typescript/commonjs/ui/context/oxyContextTypes.d.ts.map +1 -1
  104. package/lib/typescript/commonjs/ui/context/passkeyFlow.d.ts +2 -21
  105. package/lib/typescript/commonjs/ui/context/passkeyFlow.d.ts.map +1 -1
  106. package/lib/typescript/commonjs/ui/hooks/accountDialogSnapshot.d.ts.map +1 -1
  107. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts +3 -0
  108. package/lib/typescript/commonjs/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  109. package/lib/typescript/commonjs/ui/hooks/useProfileEditing.d.ts +1 -0
  110. package/lib/typescript/commonjs/ui/hooks/useProfileEditing.d.ts.map +1 -1
  111. package/lib/typescript/commonjs/ui/screens/EditProfileFieldScreen.d.ts.map +1 -1
  112. package/lib/typescript/commonjs/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  113. package/lib/typescript/module/index.d.ts +1 -1
  114. package/lib/typescript/module/index.d.ts.map +1 -1
  115. package/lib/typescript/module/ui/components/BenefitList.d.ts +25 -0
  116. package/lib/typescript/module/ui/components/BenefitList.d.ts.map +1 -0
  117. package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts +3 -4
  118. package/lib/typescript/module/ui/components/OxyAuthChooser.d.ts.map +1 -1
  119. package/lib/typescript/module/ui/components/authChooser/AccountsMenuView.d.ts.map +1 -1
  120. package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts +11 -12
  121. package/lib/typescript/module/ui/components/authChooser/SignInEntryView.d.ts.map +1 -1
  122. package/lib/typescript/module/ui/components/authChooser/SignInRequestView.d.ts.map +1 -1
  123. package/lib/typescript/module/ui/components/authChooser/SignUpView.d.ts +10 -13
  124. package/lib/typescript/module/ui/components/authChooser/SignUpView.d.ts.map +1 -1
  125. package/lib/typescript/module/ui/components/authChooser/signInFailureMessage.d.ts +16 -0
  126. package/lib/typescript/module/ui/components/authChooser/signInFailureMessage.d.ts.map +1 -0
  127. package/lib/typescript/module/ui/components/authChooser/types.d.ts +11 -13
  128. package/lib/typescript/module/ui/components/authChooser/types.d.ts.map +1 -1
  129. package/lib/typescript/module/ui/context/OxyContext.d.ts +1 -1
  130. package/lib/typescript/module/ui/context/OxyContext.d.ts.map +1 -1
  131. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts +3 -2
  132. package/lib/typescript/module/ui/context/hooks/useAuthOperations.d.ts.map +1 -1
  133. package/lib/typescript/module/ui/context/oxyContextTypes.d.ts +20 -10
  134. package/lib/typescript/module/ui/context/oxyContextTypes.d.ts.map +1 -1
  135. package/lib/typescript/module/ui/context/passkeyFlow.d.ts +2 -21
  136. package/lib/typescript/module/ui/context/passkeyFlow.d.ts.map +1 -1
  137. package/lib/typescript/module/ui/hooks/accountDialogSnapshot.d.ts.map +1 -1
  138. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts +3 -0
  139. package/lib/typescript/module/ui/hooks/mutations/useAccountMutations.d.ts.map +1 -1
  140. package/lib/typescript/module/ui/hooks/useProfileEditing.d.ts +1 -0
  141. package/lib/typescript/module/ui/hooks/useProfileEditing.d.ts.map +1 -1
  142. package/lib/typescript/module/ui/screens/EditProfileFieldScreen.d.ts.map +1 -1
  143. package/lib/typescript/module/ui/screens/ManageAccountScreen.d.ts.map +1 -1
  144. package/package.json +6 -6
  145. package/src/index.ts +1 -1
  146. package/src/ui/components/BenefitList.tsx +111 -0
  147. package/src/ui/components/FollowTargetButton.tsx +1 -1
  148. package/src/ui/components/OxyAuthChooser.tsx +106 -156
  149. package/src/ui/components/authChooser/AccountsMenuView.tsx +7 -0
  150. package/src/ui/components/authChooser/SignInEntryView.tsx +41 -44
  151. package/src/ui/components/authChooser/SignInRequestView.tsx +1 -4
  152. package/src/ui/components/authChooser/SignUpView.tsx +16 -114
  153. package/src/ui/components/authChooser/signInFailureMessage.ts +39 -0
  154. package/src/ui/components/authChooser/types.ts +11 -13
  155. package/src/ui/context/OxyContext.tsx +2 -20
  156. package/src/ui/context/__tests__/passkeyFlow.test.ts +2 -65
  157. package/src/ui/context/hooks/useAuthOperations.ts +10 -5
  158. package/src/ui/context/oxyContextTypes.ts +16 -8
  159. package/src/ui/context/passkeyFlow.ts +2 -39
  160. package/src/ui/hooks/accountDialogSnapshot.ts +2 -0
  161. package/src/ui/hooks/useProfileEditing.ts +15 -0
  162. package/src/ui/screens/AccountVerificationScreen.tsx +6 -6
  163. package/src/ui/screens/EditProfileFieldScreen.tsx +202 -7
  164. package/src/ui/screens/LearnMoreUsernamesScreen.tsx +6 -6
  165. package/src/ui/screens/ManageAccountScreen.tsx +12 -0
  166. package/src/ui/screens/PremiumSubscriptionScreen.tsx +1 -1
  167. package/src/ui/screens/trust/TrustAboutScreen.tsx +7 -7
  168. package/lib/commonjs/ui/components/authChooser/useUsernameAvailability.js +0 -50
  169. package/lib/commonjs/ui/components/authChooser/useUsernameAvailability.js.map +0 -1
  170. package/lib/module/ui/components/authChooser/useUsernameAvailability.js +0 -46
  171. package/lib/module/ui/components/authChooser/useUsernameAvailability.js.map +0 -1
  172. package/lib/typescript/commonjs/ui/components/authChooser/useUsernameAvailability.d.ts +0 -16
  173. package/lib/typescript/commonjs/ui/components/authChooser/useUsernameAvailability.d.ts.map +0 -1
  174. package/lib/typescript/module/ui/components/authChooser/useUsernameAvailability.d.ts +0 -16
  175. package/lib/typescript/module/ui/components/authChooser/useUsernameAvailability.d.ts.map +0 -1
  176. package/src/ui/components/authChooser/useUsernameAvailability.ts +0 -60
@@ -11,7 +11,7 @@ import { H4, Text } from '@oxy.so/bloom/typography';
11
11
  import { Button } from '@oxy.so/bloom/button';
12
12
  import { TextField, TextFieldInput } from '@oxy.so/bloom/text-field';
13
13
  import { IconCircle } from '@oxy.so/bloom/icon-circle';
14
- import { BenefitList, BenefitRow } from '@oxy.so/bloom/benefit-list';
14
+ import { BenefitList, BenefitRow } from '../components/BenefitList';
15
15
  import * as Icons from '@oxy.so/bloom/icons';
16
16
  import { useI18n } from '../hooks/useI18n';
17
17
  import { useSurfaceHeader } from '../hooks/useSurfaceHeader';
@@ -82,7 +82,7 @@ const AccountVerificationScreen: React.FC<BaseScreenProps> = ({
82
82
  <View className="px-screen-margin pb-space-32">
83
83
  {/* Hero */}
84
84
  <View className="items-center py-space-24 gap-space-12">
85
- <IconCircle icon={Icons.Verified_Stroke2_Corner2_Rounded} />
85
+ <IconCircle icon={Icons.RiVerifiedBadgeLine} />
86
86
  <H4 className="text-headerBold font-headerBold text-text text-center">
87
87
  {t('accountVerification.heroTitle') || 'Get a verified badge'}
88
88
  </H4>
@@ -97,15 +97,15 @@ const AccountVerificationScreen: React.FC<BaseScreenProps> = ({
97
97
  accessibilityLabel={t('accountVerification.sections.benefits') || 'What verification gives you'}
98
98
  >
99
99
  <BenefitRow
100
- icon={<Icons.ShieldCheck_Stroke2_Corner0_Rounded size="sm" style={{ color: bloomTheme.colors.primary }} />}
100
+ icon={<Icons.RiShieldCheckLine size="sm" style={{ color: bloomTheme.colors.primary }} />}
101
101
  label={t('accountVerification.benefits.authenticity') || 'Confirms your identity is authentic and trusted'}
102
102
  />
103
103
  <BenefitRow
104
- icon={<Icons.Verified_Stroke2_Corner2_Rounded size="sm" style={{ color: bloomTheme.colors.primary }} />}
104
+ icon={<Icons.RiVerifiedBadgeLine size="sm" style={{ color: bloomTheme.colors.primary }} />}
105
105
  label={t('accountVerification.benefits.badge') || 'Displays a verified badge across the platform'}
106
106
  />
107
107
  <BenefitRow
108
- icon={<Icons.Sparkle_Stroke2_Corner0_Rounded size="sm" style={{ color: bloomTheme.colors.primary }} />}
108
+ icon={<Icons.RiSparklingLine size="sm" style={{ color: bloomTheme.colors.primary }} />}
109
109
  label={t('accountVerification.benefits.credibility') || 'Builds credibility with people who follow you'}
110
110
  />
111
111
  </BenefitList>
@@ -161,7 +161,7 @@ const AccountVerificationScreen: React.FC<BaseScreenProps> = ({
161
161
  </Button>
162
162
 
163
163
  <View className="flex-row items-start gap-space-8 mt-space-24">
164
- <Icons.CircleInfo_Stroke2_Corner0_Rounded
164
+ <Icons.RiInformationLine
165
165
  size="sm"
166
166
  style={{ color: bloomTheme.colors.textTertiary }}
167
167
  />
@@ -12,6 +12,16 @@ import { useTheme } from '@oxy.so/bloom/theme';
12
12
  import { Text } from '@oxy.so/bloom/typography';
13
13
  import { Button } from '@oxy.so/bloom/button';
14
14
  import { TextField, TextFieldInput } from '@oxy.so/bloom/text-field';
15
+ import {
16
+ Select,
17
+ SelectContent,
18
+ SelectIcon,
19
+ SelectItem,
20
+ SelectItemIndicator,
21
+ SelectItemText,
22
+ SelectTrigger,
23
+ SelectValue,
24
+ } from '@oxy.so/bloom/select';
15
25
  import { normalizeTheme } from '@oxy.so/core';
16
26
  import type { User } from '@oxy.so/core';
17
27
  import { useI18n } from '../hooks/useI18n';
@@ -53,6 +63,67 @@ interface FieldConfig {
53
63
  inputProps?: Partial<TextInputProps>;
54
64
  }>;
55
65
  isList?: boolean;
66
+ /** Renders `renderBirthdayPicker` instead of the plain-text `fields`. */
67
+ isDatePicker?: boolean;
68
+ }
69
+
70
+ /**
71
+ * The earliest calendar year the birthday picker offers — matches the
72
+ * platform's own lower bound (`dateOfBirthSchema`, `@oxy.so/contracts`) so a
73
+ * value this picker can produce is never one the API would reject.
74
+ */
75
+ const MIN_BIRTH_YEAR = 1900;
76
+
77
+ /** `MIN_BIRTH_YEAR` through the current year, most recent first. */
78
+ function birthYearOptions(): Array<{ value: string; label: string }> {
79
+ const currentYear = new Date().getUTCFullYear();
80
+ const years: Array<{ value: string; label: string }> = [];
81
+ for (let year = currentYear; year >= MIN_BIRTH_YEAR; year--) {
82
+ years.push({ value: String(year), label: String(year) });
83
+ }
84
+ return years;
85
+ }
86
+
87
+ /**
88
+ * Month names are not run through `t()` here: this SDK has no existing
89
+ * calendar-month translation catalogue to hook into, and inventing one is out
90
+ * of scope for wiring up the date picker itself. English month names are a
91
+ * known, deliberate limitation of this pass.
92
+ */
93
+ const MONTH_OPTIONS: Array<{ value: string; label: string }> = [
94
+ { value: '01', label: 'January' },
95
+ { value: '02', label: 'February' },
96
+ { value: '03', label: 'March' },
97
+ { value: '04', label: 'April' },
98
+ { value: '05', label: 'May' },
99
+ { value: '06', label: 'June' },
100
+ { value: '07', label: 'July' },
101
+ { value: '08', label: 'August' },
102
+ { value: '09', label: 'September' },
103
+ { value: '10', label: 'October' },
104
+ { value: '11', label: 'November' },
105
+ { value: '12', label: 'December' },
106
+ ];
107
+
108
+ /**
109
+ * Real Gregorian days in `month` (1-12) of `year`, leap years included — the
110
+ * same rule `dateOfBirthSchema` (`@oxy.so/contracts`) applies server-side,
111
+ * written a second time here because a picker's OWN day list must bound
112
+ * itself before the value ever reaches it.
113
+ */
114
+ function daysInMonth(year: number, month: number): number {
115
+ const isLeapYear = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
116
+ const DAYS_PER_MONTH = [31, isLeapYear ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
117
+ return DAYS_PER_MONTH[month - 1];
118
+ }
119
+
120
+ /** Day options for the current year/month selection — 31 while either is unset. */
121
+ function dayOptions(year: string, month: string): Array<{ value: string; label: string }> {
122
+ const count = year && month ? daysInMonth(Number(year), Number(month)) : 31;
123
+ return Array.from({ length: count }, (_, index) => {
124
+ const day = String(index + 1).padStart(2, '0');
125
+ return { value: day, label: day };
126
+ });
56
127
  }
57
128
 
58
129
  interface EditProfileFieldScreenProps extends BaseScreenProps {
@@ -131,7 +202,13 @@ function buildInitialProfileState(
131
202
  fieldValues.lastName = String(userData.lastName || userData.name?.last || '');
132
203
  break;
133
204
  case 'birthday':
134
- fieldValues.birthday = String(userData.birthday || userData.dateOfBirth || '');
205
+ // Seeded from `dateOfBirth` ONLY, never the legacy free-text
206
+ // `birthday` — a structured picker needs a real `YYYY-MM-DD`
207
+ // value to select against, and `birthday` has no guaranteed
208
+ // shape (see its own comment in `db/schema/users.ts`). An
209
+ // account whose `dateOfBirth` is not yet set opens the picker
210
+ // empty rather than seeded with a guess.
211
+ fieldValues.dateOfBirth = String(userData.dateOfBirth || '');
135
212
  break;
136
213
  case 'address':
137
214
  fieldValues.address = String(userData.address || '');
@@ -322,17 +399,18 @@ const EditProfileFieldScreen: React.FC<EditProfileFieldScreenProps> = ({
322
399
  return {
323
400
  title: t('editProfile.items.birthday.title') || 'Birthday',
324
401
  subtitle: t('editProfile.items.birthday.subtitle') || 'Your date of birth',
402
+ // One entry, naming the field `handleSave`'s generic branch writes
403
+ // (`fieldConfig.fields[0]?.key`) — `renderBirthdayPicker` renders the
404
+ // actual day/month/year controls; this array is never mapped through
405
+ // `renderField` for this field type (see `isDatePicker` below).
325
406
  fields: [
326
407
  {
327
- key: 'birthday',
408
+ key: 'dateOfBirth',
328
409
  label: t('editProfile.items.birthday.label') || 'Birthday',
329
410
  placeholder: t('editProfile.items.birthday.placeholder') || 'YYYY-MM-DD',
330
- inputProps: {
331
- autoCapitalize: 'none',
332
- autoCorrect: false,
333
- },
334
411
  },
335
412
  ],
413
+ isDatePicker: true,
336
414
  };
337
415
  case 'locations':
338
416
  return {
@@ -364,6 +442,54 @@ const EditProfileFieldScreen: React.FC<EditProfileFieldScreenProps> = ({
364
442
  }
365
443
  }, [fieldErrors]);
366
444
 
445
+ // The birthday picker's three pieces, seeded once from the same
446
+ // one-time-mount value `fieldValues.dateOfBirth` already carries (empty
447
+ // string parts when unset). Kept separate from `fieldValues` because a
448
+ // `Select` needs its OWN current value per control; each change handler
449
+ // below composes the three back into the single `dateOfBirth` field
450
+ // `handleSave` actually writes, in the event handler itself rather than
451
+ // an effect.
452
+ const [dobYear, setDobYear] = useState(() => (fieldValues.dateOfBirth || '').split('-')[0] || '');
453
+ const [dobMonth, setDobMonth] = useState(() => (fieldValues.dateOfBirth || '').split('-')[1] || '');
454
+ const [dobDay, setDobDay] = useState(() => (fieldValues.dateOfBirth || '').split('-')[2] || '');
455
+
456
+ // A partial selection (e.g. year and month but no day yet) writes ''`,
457
+ // which `updateField`/the API's `dateOfBirth` write path already treats
458
+ // as "clear" — the same behaviour a fully-erased text field would have
459
+ // had. There is deliberately no separate "incomplete date" error: the
460
+ // three controls are either all filled (a real date) or the field is
461
+ // unset, and both are valid states to save.
462
+ const commitDateOfBirth = useCallback((year: string, month: string, day: string) => {
463
+ handleFieldChange('dateOfBirth', year && month && day ? `${year}-${month}-${day}` : '');
464
+ }, [handleFieldChange]);
465
+
466
+ // Changing the year or month can strand a selected day past the new
467
+ // month's length (31 March -> April has none) — clamped down to the new
468
+ // last day rather than left pointing at a day `dayOptions` no longer
469
+ // lists, the same way a native date picker behaves.
470
+ const handleDobYearChange = useCallback((year: string) => {
471
+ const clampedDay = dobDay && dobMonth && Number(dobDay) > daysInMonth(Number(year), Number(dobMonth))
472
+ ? String(daysInMonth(Number(year), Number(dobMonth))).padStart(2, '0')
473
+ : dobDay;
474
+ setDobYear(year);
475
+ setDobDay(clampedDay);
476
+ commitDateOfBirth(year, dobMonth, clampedDay);
477
+ }, [dobMonth, dobDay, commitDateOfBirth]);
478
+
479
+ const handleDobMonthChange = useCallback((month: string) => {
480
+ const clampedDay = dobDay && dobYear && Number(dobDay) > daysInMonth(Number(dobYear), Number(month))
481
+ ? String(daysInMonth(Number(dobYear), Number(month))).padStart(2, '0')
482
+ : dobDay;
483
+ setDobMonth(month);
484
+ setDobDay(clampedDay);
485
+ commitDateOfBirth(dobYear, month, clampedDay);
486
+ }, [dobYear, dobDay, commitDateOfBirth]);
487
+
488
+ const handleDobDayChange = useCallback((day: string) => {
489
+ setDobDay(day);
490
+ commitDateOfBirth(dobYear, dobMonth, day);
491
+ }, [dobYear, dobMonth, commitDateOfBirth]);
492
+
367
493
  // Validate all fields
368
494
  const validateFields = useCallback((): boolean => {
369
495
  const errors: Record<string, string | undefined> = {};
@@ -511,6 +637,71 @@ const EditProfileFieldScreen: React.FC<EditProfileFieldScreenProps> = ({
511
637
  );
512
638
  };
513
639
 
640
+ // Render the birthday picker: three `Select`s (day, month, year) rather
641
+ // than a native date-picker dependency. Neither this app nor
642
+ // `@oxy.so/bloom` has one installed, and `Select` is already this
643
+ // design system's cross-platform choice control (a bottom sheet on
644
+ // native, an anchored dropdown on web — see its own docs) with no new
645
+ // dependency to add and no native linking to carry across platforms.
646
+ const renderBirthdayPicker = () => (
647
+ <View className="flex-row gap-space-8">
648
+ <View className="flex-1">
649
+ <Select value={dobMonth} onValueChange={handleDobMonthChange}>
650
+ <SelectTrigger label={t('editProfile.items.birthday.month') || 'Month'}>
651
+ <SelectValue placeholder={t('editProfile.items.birthday.month') || 'Month'} />
652
+ <SelectIcon />
653
+ </SelectTrigger>
654
+ <SelectContent
655
+ label={t('editProfile.items.birthday.month') || 'Month'}
656
+ items={MONTH_OPTIONS}
657
+ renderItem={(item) => (
658
+ <SelectItem value={item.value} label={item.label}>
659
+ <SelectItemIndicator />
660
+ <SelectItemText>{item.label}</SelectItemText>
661
+ </SelectItem>
662
+ )}
663
+ />
664
+ </Select>
665
+ </View>
666
+ <View className="flex-1">
667
+ <Select value={dobDay} onValueChange={handleDobDayChange}>
668
+ <SelectTrigger label={t('editProfile.items.birthday.day') || 'Day'}>
669
+ <SelectValue placeholder={t('editProfile.items.birthday.day') || 'Day'} />
670
+ <SelectIcon />
671
+ </SelectTrigger>
672
+ <SelectContent
673
+ label={t('editProfile.items.birthday.day') || 'Day'}
674
+ items={dayOptions(dobYear, dobMonth)}
675
+ renderItem={(item) => (
676
+ <SelectItem value={item.value} label={item.label}>
677
+ <SelectItemIndicator />
678
+ <SelectItemText>{item.label}</SelectItemText>
679
+ </SelectItem>
680
+ )}
681
+ />
682
+ </Select>
683
+ </View>
684
+ <View className="flex-1">
685
+ <Select value={dobYear} onValueChange={handleDobYearChange}>
686
+ <SelectTrigger label={t('editProfile.items.birthday.year') || 'Year'}>
687
+ <SelectValue placeholder={t('editProfile.items.birthday.year') || 'Year'} />
688
+ <SelectIcon />
689
+ </SelectTrigger>
690
+ <SelectContent
691
+ label={t('editProfile.items.birthday.year') || 'Year'}
692
+ items={birthYearOptions()}
693
+ renderItem={(item) => (
694
+ <SelectItem value={item.value} label={item.label}>
695
+ <SelectItemIndicator />
696
+ <SelectItemText>{item.label}</SelectItemText>
697
+ </SelectItem>
698
+ )}
699
+ />
700
+ </Select>
701
+ </View>
702
+ </View>
703
+ );
704
+
514
705
  // Render list content (locations or links)
515
706
  const renderListContent = () => {
516
707
  const addLabel = fieldType === 'locations'
@@ -590,7 +781,11 @@ const EditProfileFieldScreen: React.FC<EditProfileFieldScreenProps> = ({
590
781
  <View className="px-screen-margin pt-space-16 pb-space-32 gap-space-24">
591
782
  {/* Form Content */}
592
783
  <View className="gap-space-16 p-space-16 rounded-radius-20 bg-fill">
593
- {fieldConfig.isList ? renderListContent() : fieldConfig.fields.map(renderField)}
784
+ {fieldConfig.isList
785
+ ? renderListContent()
786
+ : fieldConfig.isDatePicker
787
+ ? renderBirthdayPicker()
788
+ : fieldConfig.fields.map(renderField)}
594
789
  </View>
595
790
  </View>
596
791
  );
@@ -28,31 +28,31 @@ const INFO_SECTIONS: InfoSection[] = [
28
28
  id: 'what',
29
29
  titleKey: 'learnMoreUsernames.sections.what.title',
30
30
  contentKey: 'learnMoreUsernames.sections.what.content',
31
- Icon: Icons.At_Stroke2_Corner0_Rounded,
31
+ Icon: Icons.RiAtLine,
32
32
  },
33
33
  {
34
34
  id: 'rules',
35
35
  titleKey: 'learnMoreUsernames.sections.rules.title',
36
36
  contentKey: 'learnMoreUsernames.sections.rules.content',
37
- Icon: Icons.BulletList_Stroke2_Corner0_Rounded,
37
+ Icon: Icons.RiListUnordered,
38
38
  },
39
39
  {
40
40
  id: 'unique',
41
41
  titleKey: 'learnMoreUsernames.sections.unique.title',
42
42
  contentKey: 'learnMoreUsernames.sections.unique.content',
43
- Icon: Icons.Key_Stroke2_Corner2_Rounded,
43
+ Icon: Icons.RiKey2Line,
44
44
  },
45
45
  {
46
46
  id: 'change',
47
47
  titleKey: 'learnMoreUsernames.sections.change.title',
48
48
  contentKey: 'learnMoreUsernames.sections.change.content',
49
- Icon: Icons.ArrowRotateClockwise_Stroke2_Corner0_Rounded,
49
+ Icon: Icons.RiResetRightLine,
50
50
  },
51
51
  {
52
52
  id: 'tips',
53
53
  titleKey: 'learnMoreUsernames.sections.tips.title',
54
54
  contentKey: 'learnMoreUsernames.sections.tips.content',
55
- Icon: Icons.Sparkle_Stroke2_Corner0_Rounded,
55
+ Icon: Icons.RiSparklingLine,
56
56
  },
57
57
  ];
58
58
 
@@ -84,7 +84,7 @@ const LearnMoreUsernamesScreen: React.FC<BaseScreenProps> = ({
84
84
  <>
85
85
  <View className="px-screen-margin pb-space-32">
86
86
  <View className="items-center py-space-24 gap-space-12">
87
- <IconCircle icon={Icons.At_Stroke2_Corner0_Rounded} />
87
+ <IconCircle icon={Icons.RiAtLine} />
88
88
  <Text className="font-sans text-body text-text-secondary text-center">
89
89
  {t('learnMoreUsernames.introText')}
90
90
  </Text>
@@ -4,6 +4,7 @@ import {
4
4
  View,
5
5
  StyleSheet,
6
6
  ActivityIndicator,
7
+ Linking,
7
8
  Platform,
8
9
  } from 'react-native';
9
10
  import Ionicons from '../icons/Ionicons';
@@ -13,6 +14,7 @@ import { useTheme } from '@oxy.so/bloom/theme';
13
14
  import { Text } from '@oxy.so/bloom/typography';
14
15
  import { SettingsListGroup, SettingsListItem } from '@oxy.so/bloom/settings-list';
15
16
  import {
17
+ IDENTITY_WEB_ORIGIN,
16
18
  getAccountDisplayName,
17
19
  getAccountFallbackHandle,
18
20
  getNormalizedUserHandle,
@@ -27,6 +29,7 @@ import { presentActionSheet } from '../components/surfaces/ActionSheetSurface';
27
29
  import { useOxy } from '../context/OxyContext';
28
30
  import { useI18n } from '../hooks/useI18n';
29
31
  import { useSurfaceHeader } from '../hooks/useSurfaceHeader';
32
+ import { isWebBrowser } from '../utils/isWebBrowser';
30
33
  import { useCurrentUser } from '../hooks/queries/useAccountQueries';
31
34
  import { useUserSubscription } from '../hooks/queries/usePaymentQueries';
32
35
  import { useDeviceSessions } from '../hooks/queries/useServicesQueries';
@@ -326,6 +329,15 @@ const ManageAccountScreen: React.FC<BaseScreenProps> = ({
326
329
  );
327
330
  return;
328
331
  }
332
+ // Web: deleting an account is signed with its identity key, which only
333
+ // the identity origin can unseal — the deletion happens there, never on
334
+ // this page.
335
+ if (isWebBrowser()) {
336
+ await Linking.openURL(`${IDENTITY_WEB_ORIGIN}/`).catch(() => {
337
+ toast.error(t('accountSwitcher.linkOpenFailed'));
338
+ });
339
+ return;
340
+ }
329
341
  const deleted = await presentDeleteAccount({
330
342
  username: user.username || '',
331
343
  onDelete: handleConfirmDelete,
@@ -10,7 +10,7 @@ import { Chip } from '@oxy.so/bloom/chip';
10
10
  import { Badge } from '@oxy.so/bloom/badge';
11
11
  import { Card, CardBody } from '@oxy.so/bloom/card';
12
12
  import { H2, H4, H5, Text } from '@oxy.so/bloom/typography';
13
- import { BenefitList, BenefitRow } from '@oxy.so/bloom/benefit-list';
13
+ import { BenefitList, BenefitRow } from '../components/BenefitList';
14
14
  import {
15
15
  SegmentedControl,
16
16
  SegmentedControlItem,
@@ -3,7 +3,7 @@ import { View } from 'react-native';
3
3
  import { useTheme } from '@oxy.so/bloom/theme';
4
4
  import { H4, Text } from '@oxy.so/bloom/typography';
5
5
  import { IconCircle } from '@oxy.so/bloom/icon-circle';
6
- import { BenefitList, BenefitRow } from '@oxy.so/bloom/benefit-list';
6
+ import { BenefitList, BenefitRow } from '../../components/BenefitList';
7
7
  import * as Icons from '@oxy.so/bloom/icons';
8
8
  import type { BaseScreenProps } from '../../types/navigation';
9
9
  import { useI18n } from '../../hooks/useI18n';
@@ -22,7 +22,7 @@ const TrustAboutScreen: React.FC<BaseScreenProps> = () => {
22
22
  return (
23
23
  <View className="px-screen-margin pt-space-16 pb-space-32">
24
24
  <View className="items-center py-space-24 gap-space-12">
25
- <IconCircle icon={Icons.ShieldCheck_Stroke2_Corner0_Rounded} />
25
+ <IconCircle icon={Icons.RiShieldCheckLine} />
26
26
  <Text className="font-sans text-body text-text-secondary text-center">
27
27
  {t('trust.about.intro') || 'Oxy Trust is a recognition of your positive actions in the Oxy Ecosystem. Reputation cannot be sent or received directly, only earned by contributing to the community.'}
28
28
  </Text>
@@ -36,23 +36,23 @@ const TrustAboutScreen: React.FC<BaseScreenProps> = () => {
36
36
  accessibilityLabel={t('trust.about.how.title') || 'How to Earn Reputation'}
37
37
  >
38
38
  <BenefitRow
39
- icon={<Icons.UserCircle_Stroke2_Corner0_Rounded size="sm" style={{ color: iconColor }} />}
39
+ icon={<Icons.RiAccountCircleLine size="sm" style={{ color: iconColor }} />}
40
40
  label={t('trust.about.how.help') || 'Helping other users'}
41
41
  />
42
42
  <BenefitRow
43
- icon={<Icons.Flag_Stroke2_Corner0_Rounded size="sm" style={{ color: iconColor }} />}
43
+ icon={<Icons.RiFlagLine size="sm" style={{ color: iconColor }} />}
44
44
  label={t('trust.about.how.report') || 'Reporting bugs'}
45
45
  />
46
46
  <BenefitRow
47
- icon={<Icons.PencilLine_Stroke2_Corner0_Rounded size="sm" style={{ color: iconColor }} />}
47
+ icon={<Icons.RiEditLine size="sm" style={{ color: iconColor }} />}
48
48
  label={t('trust.about.how.contribute') || 'Contributing content'}
49
49
  />
50
50
  <BenefitRow
51
- icon={<Icons.Calendar_Stroke2_Corner0_Rounded size="sm" style={{ color: iconColor }} />}
51
+ icon={<Icons.RiCalendarLine size="sm" style={{ color: iconColor }} />}
52
52
  label={t('trust.about.how.participate') || 'Participating in events'}
53
53
  />
54
54
  <BenefitRow
55
- icon={<Icons.Sparkle_Stroke2_Corner0_Rounded size="sm" style={{ color: iconColor }} />}
55
+ icon={<Icons.RiSparklingLine size="sm" style={{ color: iconColor }} />}
56
56
  label={t('trust.about.how.other') || 'Other positive actions'}
57
57
  />
58
58
  </BenefitList>
@@ -1,50 +0,0 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- exports.useUsernameAvailability = useUsernameAvailability;
7
- var _react = require("react");
8
- var _toast = require("@oxy.so/bloom/toast");
9
- /**
10
- * Debounced username-availability check over the existing SDK method.
11
- *
12
- * One responsibility: turn keystrokes into an `idle | checking | available |
13
- * taken` verdict without racing. A sequence guard drops superseded responses,
14
- * and a NETWORK failure resets the (now stale) verdict and toasts — it never
15
- * paints an inline error inside the dialog (owner mandate).
16
- */
17
-
18
- /** Keystrokes settle for this long before a check is issued. */
19
- const DEBOUNCE_MS = 400;
20
- /** Shorter than this and there is nothing worth asking the server about. */
21
- const MIN_USERNAME_LENGTH = 3;
22
- function useUsernameAvailability(oxyServices, t) {
23
- const [status, setStatus] = (0, _react.useState)('idle');
24
- const timerRef = (0, _react.useRef)(null);
25
- const requestSeqRef = (0, _react.useRef)(0);
26
- const check = (0, _react.useCallback)(value => {
27
- if (timerRef.current) clearTimeout(timerRef.current);
28
- const seq = ++requestSeqRef.current;
29
- if (!value || value.length < MIN_USERNAME_LENGTH) {
30
- setStatus('idle');
31
- return;
32
- }
33
- setStatus('checking');
34
- timerRef.current = setTimeout(() => {
35
- void oxyServices.checkUsernameAvailability(value).then(result => {
36
- if (seq !== requestSeqRef.current) return; // superseded by a newer check
37
- setStatus(result.available ? 'available' : 'taken');
38
- }).catch(() => {
39
- if (seq !== requestSeqRef.current) return;
40
- setStatus('idle');
41
- _toast.toast.error(t('accounts.create.username.checkFailed'));
42
- });
43
- }, DEBOUNCE_MS);
44
- }, [oxyServices, t]);
45
- return {
46
- status,
47
- check
48
- };
49
- }
50
- //# sourceMappingURL=useUsernameAvailability.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["_react","require","_toast","DEBOUNCE_MS","MIN_USERNAME_LENGTH","useUsernameAvailability","oxyServices","t","status","setStatus","useState","timerRef","useRef","requestSeqRef","check","useCallback","value","current","clearTimeout","seq","length","setTimeout","checkUsernameAvailability","then","result","available","catch","toast","error"],"sourceRoot":"../../../../../src","sources":["ui/components/authChooser/useUsernameAvailability.ts"],"mappings":";;;;;;AASA,IAAAA,MAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AAVA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AASA;AACA,MAAME,WAAW,GAAG,GAAG;AACvB;AACA,MAAMC,mBAAmB,GAAG,CAAC;AAEtB,SAASC,uBAAuBA,CACrCC,WAAwB,EACxBC,CAAY,EAIZ;EACA,MAAM,CAACC,MAAM,EAAEC,SAAS,CAAC,GAAG,IAAAC,eAAQ,EAAiB,MAAM,CAAC;EAC5D,MAAMC,QAAQ,GAAG,IAAAC,aAAM,EAAuC,IAAI,CAAC;EACnE,MAAMC,aAAa,GAAG,IAAAD,aAAM,EAAC,CAAC,CAAC;EAE/B,MAAME,KAAK,GAAG,IAAAC,kBAAW,EACtBC,KAAa,IAAK;IACjB,IAAIL,QAAQ,CAACM,OAAO,EAAEC,YAAY,CAACP,QAAQ,CAACM,OAAO,CAAC;IACpD,MAAME,GAAG,GAAG,EAAEN,aAAa,CAACI,OAAO;IACnC,IAAI,CAACD,KAAK,IAAIA,KAAK,CAACI,MAAM,GAAGhB,mBAAmB,EAAE;MAChDK,SAAS,CAAC,MAAM,CAAC;MACjB;IACF;IACAA,SAAS,CAAC,UAAU,CAAC;IACrBE,QAAQ,CAACM,OAAO,GAAGI,UAAU,CAAC,MAAM;MAClC,KAAKf,WAAW,CACbgB,yBAAyB,CAACN,KAAK,CAAC,CAChCO,IAAI,CAAEC,MAAM,IAAK;QAChB,IAAIL,GAAG,KAAKN,aAAa,CAACI,OAAO,EAAE,OAAO,CAAC;QAC3CR,SAAS,CAACe,MAAM,CAACC,SAAS,GAAG,WAAW,GAAG,OAAO,CAAC;MACrD,CAAC,CAAC,CACDC,KAAK,CAAC,MAAM;QACX,IAAIP,GAAG,KAAKN,aAAa,CAACI,OAAO,EAAE;QACnCR,SAAS,CAAC,MAAM,CAAC;QACjBkB,YAAK,CAACC,KAAK,CAACrB,CAAC,CAAC,sCAAsC,CAAC,CAAC;MACxD,CAAC,CAAC;IACN,CAAC,EAAEJ,WAAW,CAAC;EACjB,CAAC,EACD,CAACG,WAAW,EAAEC,CAAC,CACjB,CAAC;EAED,OAAO;IAAEC,MAAM;IAAEM;EAAM,CAAC;AAC1B","ignoreList":[]}
@@ -1,46 +0,0 @@
1
- "use strict";
2
-
3
- /**
4
- * Debounced username-availability check over the existing SDK method.
5
- *
6
- * One responsibility: turn keystrokes into an `idle | checking | available |
7
- * taken` verdict without racing. A sequence guard drops superseded responses,
8
- * and a NETWORK failure resets the (now stale) verdict and toasts — it never
9
- * paints an inline error inside the dialog (owner mandate).
10
- */
11
-
12
- import { useCallback, useRef, useState } from 'react';
13
- import { toast } from '@oxy.so/bloom/toast';
14
- /** Keystrokes settle for this long before a check is issued. */
15
- const DEBOUNCE_MS = 400;
16
- /** Shorter than this and there is nothing worth asking the server about. */
17
- const MIN_USERNAME_LENGTH = 3;
18
- export function useUsernameAvailability(oxyServices, t) {
19
- const [status, setStatus] = useState('idle');
20
- const timerRef = useRef(null);
21
- const requestSeqRef = useRef(0);
22
- const check = useCallback(value => {
23
- if (timerRef.current) clearTimeout(timerRef.current);
24
- const seq = ++requestSeqRef.current;
25
- if (!value || value.length < MIN_USERNAME_LENGTH) {
26
- setStatus('idle');
27
- return;
28
- }
29
- setStatus('checking');
30
- timerRef.current = setTimeout(() => {
31
- void oxyServices.checkUsernameAvailability(value).then(result => {
32
- if (seq !== requestSeqRef.current) return; // superseded by a newer check
33
- setStatus(result.available ? 'available' : 'taken');
34
- }).catch(() => {
35
- if (seq !== requestSeqRef.current) return;
36
- setStatus('idle');
37
- toast.error(t('accounts.create.username.checkFailed'));
38
- });
39
- }, DEBOUNCE_MS);
40
- }, [oxyServices, t]);
41
- return {
42
- status,
43
- check
44
- };
45
- }
46
- //# sourceMappingURL=useUsernameAvailability.js.map
@@ -1 +0,0 @@
1
- {"version":3,"names":["useCallback","useRef","useState","toast","DEBOUNCE_MS","MIN_USERNAME_LENGTH","useUsernameAvailability","oxyServices","t","status","setStatus","timerRef","requestSeqRef","check","value","current","clearTimeout","seq","length","setTimeout","checkUsernameAvailability","then","result","available","catch","error"],"sourceRoot":"../../../../../src","sources":["ui/components/authChooser/useUsernameAvailability.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA,SAASA,WAAW,EAAEC,MAAM,EAAEC,QAAQ,QAAQ,OAAO;AACrD,SAASC,KAAK,QAAQ,qBAAqB;AAM3C;AACA,MAAMC,WAAW,GAAG,GAAG;AACvB;AACA,MAAMC,mBAAmB,GAAG,CAAC;AAE7B,OAAO,SAASC,uBAAuBA,CACrCC,WAAwB,EACxBC,CAAY,EAIZ;EACA,MAAM,CAACC,MAAM,EAAEC,SAAS,CAAC,GAAGR,QAAQ,CAAiB,MAAM,CAAC;EAC5D,MAAMS,QAAQ,GAAGV,MAAM,CAAuC,IAAI,CAAC;EACnE,MAAMW,aAAa,GAAGX,MAAM,CAAC,CAAC,CAAC;EAE/B,MAAMY,KAAK,GAAGb,WAAW,CACtBc,KAAa,IAAK;IACjB,IAAIH,QAAQ,CAACI,OAAO,EAAEC,YAAY,CAACL,QAAQ,CAACI,OAAO,CAAC;IACpD,MAAME,GAAG,GAAG,EAAEL,aAAa,CAACG,OAAO;IACnC,IAAI,CAACD,KAAK,IAAIA,KAAK,CAACI,MAAM,GAAGb,mBAAmB,EAAE;MAChDK,SAAS,CAAC,MAAM,CAAC;MACjB;IACF;IACAA,SAAS,CAAC,UAAU,CAAC;IACrBC,QAAQ,CAACI,OAAO,GAAGI,UAAU,CAAC,MAAM;MAClC,KAAKZ,WAAW,CACba,yBAAyB,CAACN,KAAK,CAAC,CAChCO,IAAI,CAAEC,MAAM,IAAK;QAChB,IAAIL,GAAG,KAAKL,aAAa,CAACG,OAAO,EAAE,OAAO,CAAC;QAC3CL,SAAS,CAACY,MAAM,CAACC,SAAS,GAAG,WAAW,GAAG,OAAO,CAAC;MACrD,CAAC,CAAC,CACDC,KAAK,CAAC,MAAM;QACX,IAAIP,GAAG,KAAKL,aAAa,CAACG,OAAO,EAAE;QACnCL,SAAS,CAAC,MAAM,CAAC;QACjBP,KAAK,CAACsB,KAAK,CAACjB,CAAC,CAAC,sCAAsC,CAAC,CAAC;MACxD,CAAC,CAAC;IACN,CAAC,EAAEJ,WAAW,CAAC;EACjB,CAAC,EACD,CAACG,WAAW,EAAEC,CAAC,CACjB,CAAC;EAED,OAAO;IAAEC,MAAM;IAAEI;EAAM,CAAC;AAC1B","ignoreList":[]}
@@ -1,16 +0,0 @@
1
- /**
2
- * Debounced username-availability check over the existing SDK method.
3
- *
4
- * One responsibility: turn keystrokes into an `idle | checking | available |
5
- * taken` verdict without racing. A sequence guard drops superseded responses,
6
- * and a NETWORK failure resets the (now stale) verdict and toasts — it never
7
- * paints an inline error inside the dialog (owner mandate).
8
- */
9
- import type { OxyServices } from '@oxy.so/core';
10
- import type { Translate } from './types';
11
- export type UsernameStatus = 'idle' | 'checking' | 'available' | 'taken';
12
- export declare function useUsernameAvailability(oxyServices: OxyServices, t: Translate): {
13
- status: UsernameStatus;
14
- check: (value: string) => void;
15
- };
16
- //# sourceMappingURL=useUsernameAvailability.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useUsernameAvailability.d.ts","sourceRoot":"","sources":["../../../../../../src/ui/components/authChooser/useUsernameAvailability.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAEzC,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC;AAOzE,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,WAAW,EACxB,CAAC,EAAE,SAAS,GACX;IACD,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC,CAgCA"}
@@ -1,16 +0,0 @@
1
- /**
2
- * Debounced username-availability check over the existing SDK method.
3
- *
4
- * One responsibility: turn keystrokes into an `idle | checking | available |
5
- * taken` verdict without racing. A sequence guard drops superseded responses,
6
- * and a NETWORK failure resets the (now stale) verdict and toasts — it never
7
- * paints an inline error inside the dialog (owner mandate).
8
- */
9
- import type { OxyServices } from '@oxy.so/core';
10
- import type { Translate } from './types.js';
11
- export type UsernameStatus = 'idle' | 'checking' | 'available' | 'taken';
12
- export declare function useUsernameAvailability(oxyServices: OxyServices, t: Translate): {
13
- status: UsernameStatus;
14
- check: (value: string) => void;
15
- };
16
- //# sourceMappingURL=useUsernameAvailability.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"useUsernameAvailability.d.ts","sourceRoot":"","sources":["../../../../../../src/ui/components/authChooser/useUsernameAvailability.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAS,CAAC;AAEzC,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC;AAOzE,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,WAAW,EACxB,CAAC,EAAE,SAAS,GACX;IACD,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC,CAgCA"}