@atproto/oauth-provider-ui 0.0.2 → 0.1.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 (182) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/{src/authorization-page.html → authorization-page.html} +36 -33
  3. package/{src/error-page.html → error-page.html} +17 -24
  4. package/package.json +28 -37
  5. package/src/authorization-page.tsx +21 -27
  6. package/src/components/forms/button.tsx +8 -8
  7. package/src/components/forms/fieldset.tsx +1 -1
  8. package/src/components/forms/form-card-async.tsx +1 -1
  9. package/src/components/forms/form-card.tsx +1 -1
  10. package/src/components/forms/input-checkbox.tsx +3 -3
  11. package/src/components/forms/input-container.tsx +12 -12
  12. package/src/components/forms/input-text.tsx +2 -2
  13. package/src/components/forms/wizard-card.tsx +2 -2
  14. package/src/components/layouts/layout-title-page.tsx +9 -8
  15. package/src/components/layouts/layout-welcome.tsx +21 -16
  16. package/src/components/utils/account-image.tsx +2 -2
  17. package/src/components/utils/admonition.tsx +5 -5
  18. package/src/components/utils/client-name.tsx +30 -4
  19. package/src/components/utils/error-card.tsx +1 -1
  20. package/src/components/utils/help-card.tsx +3 -3
  21. package/src/components/utils/multi-lang-string.tsx +14 -8
  22. package/src/components/utils/password-strength-meter.tsx +3 -3
  23. package/src/components/utils/url-viewer.tsx +1 -1
  24. package/src/error-page.tsx +8 -14
  25. package/src/hooks/use-api.ts +65 -45
  26. package/src/hydration-data.d.ts +42 -0
  27. package/src/lib/api.ts +12 -21
  28. package/src/{cookies.ts → lib/cookies.ts} +8 -2
  29. package/src/lib/json-client.ts +62 -18
  30. package/src/lib/util.ts +2 -1
  31. package/src/locales/an/messages.po +35 -28
  32. package/src/locales/ast/messages.po +35 -28
  33. package/src/locales/ca/messages.po +35 -28
  34. package/src/locales/da/messages.po +35 -28
  35. package/src/locales/de/messages.po +35 -28
  36. package/src/locales/el/messages.po +35 -28
  37. package/src/locales/en/messages.po +35 -28
  38. package/src/locales/en-GB/messages.po +35 -28
  39. package/src/locales/es/messages.po +35 -28
  40. package/src/locales/eu/messages.po +35 -28
  41. package/src/locales/fi/messages.po +35 -28
  42. package/src/locales/fr/messages.po +35 -28
  43. package/src/locales/ga/messages.po +35 -28
  44. package/src/locales/gl/messages.po +35 -28
  45. package/src/locales/hi/messages.po +35 -28
  46. package/src/locales/hu/messages.po +35 -28
  47. package/src/locales/ia/messages.po +35 -28
  48. package/src/locales/id/messages.po +35 -28
  49. package/src/locales/it/messages.po +35 -28
  50. package/src/locales/ja/messages.po +35 -28
  51. package/src/locales/km/messages.po +35 -28
  52. package/src/locales/ko/messages.po +35 -28
  53. package/src/locales/locale-provider.tsx +55 -59
  54. package/src/locales/locale-selector.tsx +13 -14
  55. package/src/locales/locales.ts +161 -146
  56. package/src/locales/ne/messages.po +35 -28
  57. package/src/locales/nl/messages.po +35 -28
  58. package/src/locales/pl/messages.po +35 -28
  59. package/src/locales/pt-BR/messages.po +35 -28
  60. package/src/locales/ro/messages.po +35 -28
  61. package/src/locales/ru/messages.po +35 -28
  62. package/src/locales/sv/messages.po +35 -28
  63. package/src/locales/th/messages.po +35 -28
  64. package/src/locales/tr/messages.po +35 -28
  65. package/src/locales/uk/messages.po +35 -28
  66. package/src/locales/vi/messages.po +35 -28
  67. package/src/locales/zh-CN/messages.po +35 -28
  68. package/src/locales/zh-HK/messages.po +35 -28
  69. package/src/locales/zh-TW/messages.po +35 -28
  70. package/src/style.css +219 -0
  71. package/src/views/authorize/accept/accept-form.tsx +11 -6
  72. package/src/views/authorize/authorize-view.tsx +13 -10
  73. package/src/views/authorize/reset-password/reset-password-view.tsx +2 -2
  74. package/src/views/authorize/sign-in/sign-in-form.tsx +39 -41
  75. package/src/views/authorize/sign-in/sign-in-picker.tsx +3 -3
  76. package/src/views/authorize/sign-up/sign-up-disclaimer.tsx +3 -3
  77. package/src/views/authorize/sign-up/sign-up-handle-form.tsx +6 -6
  78. package/src/views/authorize/sign-up/sign-up-view.tsx +3 -3
  79. package/src/views/authorize/welcome/welcome-view.tsx +5 -5
  80. package/tsconfig.json +1 -2
  81. package/{tsconfig.frontend.json → tsconfig.src.json} +4 -1
  82. package/tsconfig.src.tsbuildinfo +1 -0
  83. package/tsconfig.tools.json +1 -1
  84. package/tsconfig.tools.tsbuildinfo +1 -1
  85. package/vite.config.mjs +38 -7
  86. package/dist/assets/COdVzed-.css +0 -3
  87. package/dist/assets/COdVzed-.js +0 -100
  88. package/dist/assets/COdVzed-.js.map +0 -1
  89. package/dist/assets/Cqnfnbvc.js +0 -6
  90. package/dist/assets/Cqnfnbvc.js.map +0 -1
  91. package/dist/assets/bundle-manifest.json +0 -630
  92. package/dist/assets/error-view-Bu4y7Nd8.js +0 -208
  93. package/dist/assets/error-view-Bu4y7Nd8.js.map +0 -1
  94. package/dist/assets/index-DXlCRM6V.js +0 -36
  95. package/dist/assets/index-DXlCRM6V.js.map +0 -1
  96. package/dist/assets/messages-2GoTm2qL.js +0 -4
  97. package/dist/assets/messages-2GoTm2qL.js.map +0 -1
  98. package/dist/assets/messages-6Cn2Jbhw.js +0 -4
  99. package/dist/assets/messages-6Cn2Jbhw.js.map +0 -1
  100. package/dist/assets/messages-75hFgOK2.js +0 -4
  101. package/dist/assets/messages-75hFgOK2.js.map +0 -1
  102. package/dist/assets/messages-B3OK4k0O.js +0 -4
  103. package/dist/assets/messages-B3OK4k0O.js.map +0 -1
  104. package/dist/assets/messages-BNXlPzKV.js +0 -4
  105. package/dist/assets/messages-BNXlPzKV.js.map +0 -1
  106. package/dist/assets/messages-BUygB8mD.js +0 -4
  107. package/dist/assets/messages-BUygB8mD.js.map +0 -1
  108. package/dist/assets/messages-BVPPcwNr.js +0 -4
  109. package/dist/assets/messages-BVPPcwNr.js.map +0 -1
  110. package/dist/assets/messages-BbbWUQS8.js +0 -4
  111. package/dist/assets/messages-BbbWUQS8.js.map +0 -1
  112. package/dist/assets/messages-BibKCYyW.js +0 -4
  113. package/dist/assets/messages-BibKCYyW.js.map +0 -1
  114. package/dist/assets/messages-BlPrr9_7.js +0 -4
  115. package/dist/assets/messages-BlPrr9_7.js.map +0 -1
  116. package/dist/assets/messages-ByVCw40U.js +0 -4
  117. package/dist/assets/messages-ByVCw40U.js.map +0 -1
  118. package/dist/assets/messages-C5DU1neP.js +0 -4
  119. package/dist/assets/messages-C5DU1neP.js.map +0 -1
  120. package/dist/assets/messages-C6IgUtbX.js +0 -4
  121. package/dist/assets/messages-C6IgUtbX.js.map +0 -1
  122. package/dist/assets/messages-C92Zzt2o.js +0 -4
  123. package/dist/assets/messages-C92Zzt2o.js.map +0 -1
  124. package/dist/assets/messages-CGZqYT14.js +0 -4
  125. package/dist/assets/messages-CGZqYT14.js.map +0 -1
  126. package/dist/assets/messages-CGlsy4wt.js +0 -4
  127. package/dist/assets/messages-CGlsy4wt.js.map +0 -1
  128. package/dist/assets/messages-CPT1nd0u.js +0 -4
  129. package/dist/assets/messages-CPT1nd0u.js.map +0 -1
  130. package/dist/assets/messages-CTTdXyw_.js +0 -4
  131. package/dist/assets/messages-CTTdXyw_.js.map +0 -1
  132. package/dist/assets/messages-ChK_C_Pj.js +0 -4
  133. package/dist/assets/messages-ChK_C_Pj.js.map +0 -1
  134. package/dist/assets/messages-CjJbk7Uf.js +0 -4
  135. package/dist/assets/messages-CjJbk7Uf.js.map +0 -1
  136. package/dist/assets/messages-CoiLjLYO.js +0 -4
  137. package/dist/assets/messages-CoiLjLYO.js.map +0 -1
  138. package/dist/assets/messages-Cwx6B4Ti.js +0 -4
  139. package/dist/assets/messages-Cwx6B4Ti.js.map +0 -1
  140. package/dist/assets/messages-D0uXAp_H.js +0 -4
  141. package/dist/assets/messages-D0uXAp_H.js.map +0 -1
  142. package/dist/assets/messages-DG0_arU0.js +0 -4
  143. package/dist/assets/messages-DG0_arU0.js.map +0 -1
  144. package/dist/assets/messages-DOXFJh9K.js +0 -4
  145. package/dist/assets/messages-DOXFJh9K.js.map +0 -1
  146. package/dist/assets/messages-DPK7nOoC.js +0 -4
  147. package/dist/assets/messages-DPK7nOoC.js.map +0 -1
  148. package/dist/assets/messages-Duccgtu0.js +0 -4
  149. package/dist/assets/messages-Duccgtu0.js.map +0 -1
  150. package/dist/assets/messages-DxTqgsHq.js +0 -4
  151. package/dist/assets/messages-DxTqgsHq.js.map +0 -1
  152. package/dist/assets/messages-E5_lTg7A.js +0 -4
  153. package/dist/assets/messages-E5_lTg7A.js.map +0 -1
  154. package/dist/assets/messages-UhunAjh1.js +0 -4
  155. package/dist/assets/messages-UhunAjh1.js.map +0 -1
  156. package/dist/assets/messages-Xg_3YLGw.js +0 -4
  157. package/dist/assets/messages-Xg_3YLGw.js.map +0 -1
  158. package/dist/assets/messages-iliBQHY2.js +0 -4
  159. package/dist/assets/messages-iliBQHY2.js.map +0 -1
  160. package/dist/assets/messages-lRprpIl-.js +0 -4
  161. package/dist/assets/messages-lRprpIl-.js.map +0 -1
  162. package/dist/assets/messages-pbPHQbz1.js +0 -4
  163. package/dist/assets/messages-pbPHQbz1.js.map +0 -1
  164. package/dist/assets/messages-q-O7ZQGs.js +0 -4
  165. package/dist/assets/messages-q-O7ZQGs.js.map +0 -1
  166. package/dist/lib/index.d.ts +0 -19
  167. package/dist/lib/index.d.ts.map +0 -1
  168. package/dist/lib/index.js +0 -47
  169. package/dist/lib/index.js.map +0 -1
  170. package/dist/tsconfig.backend.tsbuildinfo +0 -1
  171. package/lib/index.ts +0 -72
  172. package/rollup.config.js +0 -102
  173. package/src/backend-data.ts +0 -35
  174. package/src/hooks/use-csrf-token.ts +0 -5
  175. package/src/lib/backend-data.ts +0 -6
  176. package/src/lib/clsx.ts +0 -6
  177. package/src/locales/locale-context.ts +0 -19
  178. package/src/styles.css +0 -33
  179. package/tailwind.config.js +0 -31
  180. package/tsconfig.backend.json +0 -8
  181. package/tsconfig.frontend.tsbuildinfo +0 -1
  182. /package/{src/index.html → index.html} +0 -0
@@ -13,11 +13,11 @@ msgstr ""
13
13
  "Language-Team: \n"
14
14
  "Plural-Forms: \n"
15
15
 
16
- #: src/views/authorize/accept/accept-form.tsx:76
16
+ #: src/views/authorize/accept/accept-form.tsx:77
17
17
  msgid "<0/> is asking for permission to access your account (<1/>)."
18
18
  msgstr ""
19
19
 
20
- #: src/views/authorize/sign-in/sign-in-form.tsx:219
20
+ #: src/views/authorize/sign-in/sign-in-form.tsx:217
21
21
  msgid "2FA Confirmation"
22
22
  msgstr ""
23
23
 
@@ -25,23 +25,19 @@ msgstr ""
25
25
  msgid "A second authentication factor is required"
26
26
  msgstr ""
27
27
 
28
- #: src/views/authorize/accept/accept-form.tsx:144
28
+ #: src/views/authorize/accept/accept-form.tsx:149
29
29
  msgid "Access your account data (except chat messages)"
30
30
  msgstr ""
31
31
 
32
- #: src/views/authorize/accept/accept-form.tsx:146
32
+ #: src/views/authorize/accept/accept-form.tsx:151
33
33
  msgid "Access your chat messages"
34
34
  msgstr ""
35
35
 
36
- #: src/views/authorize/sign-in/sign-in-form.tsx:138
37
- msgid "Account"
38
- msgstr ""
39
-
40
36
  #: src/views/authorize/reset-password/reset-password-view.tsx:71
41
37
  msgid "Already have a code?"
42
38
  msgstr ""
43
39
 
44
- #: src/components/utils/client-name.tsx:35
40
+ #: src/components/utils/client-name.tsx:43
45
41
  msgid "An application on your device"
46
42
  msgstr ""
47
43
 
@@ -58,7 +54,7 @@ msgid "Authenticate"
58
54
  msgstr ""
59
55
 
60
56
  #: src/views/authorize/accept/accept-view.tsx:55
61
- #: src/views/authorize/accept/accept-form.tsx:56
57
+ #: src/views/authorize/accept/accept-form.tsx:57
62
58
  msgid "Authorize"
63
59
  msgstr ""
64
60
 
@@ -74,19 +70,23 @@ msgstr ""
74
70
  msgid "Between {minLength} and {maxLength} characters"
75
71
  msgstr ""
76
72
 
77
- #: src/views/authorize/accept/accept-form.tsx:89
73
+ #: src/views/authorize/accept/accept-form.tsx:90
78
74
  msgid "By clicking <0>Authorize</0>, you allow this application to perform the following actions in accordance with their <1>terms of service</1> and <2>privacy policy</2>:"
79
75
  msgstr ""
80
76
 
77
+ #. placeholder {0}: tosLink ? ( <LinkAnchor className="text-primary underline" link={tosLink}> <Trans>Terms of Service</Trans> </LinkAnchor> ) : ( <Trans>Terms of Service</Trans> )
78
+ #. placeholder {1}: ppLink ? ( <LinkAnchor className="text-primary underline" link={ppLink}> <Trans>Privacy Policy</Trans> </LinkAnchor> ) : ( <Trans>Privacy Policy</Trans> )
81
79
  #: src/views/authorize/sign-up/sign-up-disclaimer.tsx:30
82
80
  msgid "By creating an account you agree to the {0} and the {1} of this service."
83
81
  msgstr ""
84
82
 
85
83
  #: src/views/authorize/welcome/welcome-view.tsx:51
84
+ #: src/components/forms/form-card-async.tsx:85
86
85
  msgid "Cancel"
87
86
  msgstr ""
88
87
 
89
- #: src/views/authorize/sign-in/sign-in-form.tsx:232
88
+ #. placeholder {0}: secondFactor.hint
89
+ #: src/views/authorize/sign-in/sign-in-form.tsx:230
90
90
  msgid "Check your {0} email for a login code and enter it here."
91
91
  msgstr ""
92
92
 
@@ -106,7 +106,7 @@ msgstr ""
106
106
  msgid "Confirm your password to continue"
107
107
  msgstr ""
108
108
 
109
- #: src/views/authorize/sign-in/sign-in-form.tsx:223
109
+ #: src/views/authorize/sign-in/sign-in-form.tsx:221
110
110
  msgid "Confirmation code"
111
111
  msgstr ""
112
112
 
@@ -118,7 +118,7 @@ msgstr ""
118
118
  msgid "Create Account"
119
119
  msgstr ""
120
120
 
121
- #: src/views/authorize/accept/accept-form.tsx:60
121
+ #: src/views/authorize/accept/accept-form.tsx:61
122
122
  msgid "Deny access"
123
123
  msgstr ""
124
124
 
@@ -181,10 +181,11 @@ msgstr ""
181
181
  msgid "Forgot Password"
182
182
  msgstr ""
183
183
 
184
- #: src/views/authorize/sign-in/sign-in-form.tsx:178
184
+ #: src/views/authorize/sign-in/sign-in-form.tsx:181
185
185
  msgid "Forgot?"
186
186
  msgstr ""
187
187
 
188
+ #. placeholder {0}: account.preferred_username || account.email || account.sub
188
189
  #: src/views/authorize/accept/accept-view.tsx:40
189
190
  msgid "Grant access to your <0>{0}</0> account"
190
191
  msgstr ""
@@ -202,6 +203,7 @@ msgid "Home"
202
203
  msgstr ""
203
204
 
204
205
  #: src/views/authorize/sign-in/sign-in-picker.tsx:86
206
+ #: src/views/authorize/sign-in/sign-in-form.tsx:138
205
207
  msgid "Identifier"
206
208
  msgstr ""
207
209
 
@@ -222,7 +224,7 @@ msgstr ""
222
224
  msgid "Let's get your password reset!"
223
225
  msgstr ""
224
226
 
225
- #: src/views/authorize/authorize-view.tsx:172
227
+ #: src/views/authorize/authorize-view.tsx:178
226
228
  msgid "Login complete"
227
229
  msgstr ""
228
230
 
@@ -230,6 +232,10 @@ msgstr ""
230
232
  msgid "Login to account that is not listed"
231
233
  msgstr ""
232
234
 
235
+ #: src/components/layouts/layout-welcome.tsx:45
236
+ msgid "Logo"
237
+ msgstr ""
238
+
233
239
  #: src/components/forms/input-token.tsx:59
234
240
  msgid "Looks like {example}"
235
241
  msgstr ""
@@ -269,6 +275,7 @@ msgid "Only letters, numbers, and hyphens"
269
275
  msgstr ""
270
276
 
271
277
  #: src/views/authorize/sign-up/sign-up-account-form.tsx:128
278
+ #: src/views/authorize/sign-in/sign-in-form.tsx:162
272
279
  #: src/components/forms/input-password.tsx:53
273
280
  msgid "Password"
274
281
  msgstr ""
@@ -293,7 +300,7 @@ msgstr ""
293
300
  msgid "Password with at least {MIN_PASSWORD_LENGTH} characters"
294
301
  msgstr ""
295
302
 
296
- #: src/views/authorize/sign-in/sign-in-form.tsx:192
303
+ #: src/views/authorize/sign-in/sign-in-form.tsx:196
297
304
  msgid "Please verify the domain name of the website before entering your password. Never enter your password on a domain you do not trust."
298
305
  msgstr ""
299
306
 
@@ -303,12 +310,12 @@ msgstr ""
303
310
  msgid "Privacy Policy"
304
311
  msgstr ""
305
312
 
306
- #: src/views/authorize/sign-in/sign-in-form.tsx:206
307
- #: src/views/authorize/sign-in/sign-in-form.tsx:211
313
+ #: src/views/authorize/sign-in/sign-in-form.tsx:205
314
+ #: src/views/authorize/sign-in/sign-in-form.tsx:210
308
315
  msgid "Remember this account on this device"
309
316
  msgstr ""
310
317
 
311
- #: src/views/authorize/accept/accept-form.tsx:123
318
+ #: src/views/authorize/accept/accept-form.tsx:124
312
319
  msgid "Requested permissions"
313
320
  msgstr ""
314
321
 
@@ -320,7 +327,7 @@ msgstr ""
320
327
  msgid "Reset Password"
321
328
  msgstr ""
322
329
 
323
- #: src/views/authorize/sign-in/sign-in-form.tsx:176
330
+ #: src/views/authorize/sign-in/sign-in-form.tsx:179
324
331
  msgid "Reset your password"
325
332
  msgstr ""
326
333
 
@@ -332,14 +339,13 @@ msgstr ""
332
339
  msgid "Select from an existing account"
333
340
  msgstr ""
334
341
 
335
- #: src/views/authorize/sign-in/sign-in-form.tsx:202
336
- msgid "Session"
337
- msgstr ""
338
-
339
342
  #: src/views/authorize/welcome/welcome-view.tsx:45
343
+ #: src/views/authorize/sign-in/sign-in-view.tsx:48
344
+ #: src/views/authorize/sign-in/sign-in-form.tsx:135
340
345
  msgid "Sign in"
341
346
  msgstr ""
342
347
 
348
+ #. placeholder {0}: account.name
343
349
  #: src/views/authorize/sign-in/sign-in-picker.tsx:75
344
350
  msgid "Sign in as {0}"
345
351
  msgstr ""
@@ -426,7 +432,7 @@ msgstr ""
426
432
  msgid "Unexpected server response"
427
433
  msgstr ""
428
434
 
429
- #: src/views/authorize/accept/accept-form.tsx:142
435
+ #: src/views/authorize/accept/accept-form.tsx:147
430
436
  msgid "Uniquely identify you"
431
437
  msgstr ""
432
438
 
@@ -442,7 +448,7 @@ msgstr ""
442
448
  msgid "Verify you are human"
443
449
  msgstr ""
444
450
 
445
- #: src/views/authorize/sign-in/sign-in-form.tsx:189
451
+ #: src/views/authorize/sign-in/sign-in-form.tsx:193
446
452
  msgid "Warning"
447
453
  msgstr ""
448
454
 
@@ -458,7 +464,7 @@ msgstr ""
458
464
  msgid "Wrong identifier or password"
459
465
  msgstr ""
460
466
 
461
- #: src/views/authorize/authorize-view.tsx:173
467
+ #: src/views/authorize/authorize-view.tsx:179
462
468
  msgid "You are being redirected..."
463
469
  msgstr ""
464
470
 
@@ -478,6 +484,7 @@ msgstr ""
478
484
  msgid "Your account"
479
485
  msgstr ""
480
486
 
487
+ #. placeholder {0}: segment.length ? ( <strong className="text-gray-800 dark:text-gray-200"> {preview} </strong> ) : ( <span aria-hidden className="w-24 rounded-md bg-gray-300 p-2 dark:bg-slate-600" /> )
481
488
  #: src/views/authorize/sign-up/sign-up-handle-form.tsx:217
482
489
  msgid "Your full username will be: {0}"
483
490
  msgstr ""
@@ -13,11 +13,11 @@ msgstr ""
13
13
  "Language-Team: \n"
14
14
  "Plural-Forms: \n"
15
15
 
16
- #: src/views/authorize/accept/accept-form.tsx:76
16
+ #: src/views/authorize/accept/accept-form.tsx:77
17
17
  msgid "<0/> is asking for permission to access your account (<1/>)."
18
18
  msgstr ""
19
19
 
20
- #: src/views/authorize/sign-in/sign-in-form.tsx:219
20
+ #: src/views/authorize/sign-in/sign-in-form.tsx:217
21
21
  msgid "2FA Confirmation"
22
22
  msgstr ""
23
23
 
@@ -25,23 +25,19 @@ msgstr ""
25
25
  msgid "A second authentication factor is required"
26
26
  msgstr ""
27
27
 
28
- #: src/views/authorize/accept/accept-form.tsx:144
28
+ #: src/views/authorize/accept/accept-form.tsx:149
29
29
  msgid "Access your account data (except chat messages)"
30
30
  msgstr ""
31
31
 
32
- #: src/views/authorize/accept/accept-form.tsx:146
32
+ #: src/views/authorize/accept/accept-form.tsx:151
33
33
  msgid "Access your chat messages"
34
34
  msgstr ""
35
35
 
36
- #: src/views/authorize/sign-in/sign-in-form.tsx:138
37
- msgid "Account"
38
- msgstr ""
39
-
40
36
  #: src/views/authorize/reset-password/reset-password-view.tsx:71
41
37
  msgid "Already have a code?"
42
38
  msgstr ""
43
39
 
44
- #: src/components/utils/client-name.tsx:35
40
+ #: src/components/utils/client-name.tsx:43
45
41
  msgid "An application on your device"
46
42
  msgstr ""
47
43
 
@@ -58,7 +54,7 @@ msgid "Authenticate"
58
54
  msgstr ""
59
55
 
60
56
  #: src/views/authorize/accept/accept-view.tsx:55
61
- #: src/views/authorize/accept/accept-form.tsx:56
57
+ #: src/views/authorize/accept/accept-form.tsx:57
62
58
  msgid "Authorize"
63
59
  msgstr ""
64
60
 
@@ -74,19 +70,23 @@ msgstr ""
74
70
  msgid "Between {minLength} and {maxLength} characters"
75
71
  msgstr ""
76
72
 
77
- #: src/views/authorize/accept/accept-form.tsx:89
73
+ #: src/views/authorize/accept/accept-form.tsx:90
78
74
  msgid "By clicking <0>Authorize</0>, you allow this application to perform the following actions in accordance with their <1>terms of service</1> and <2>privacy policy</2>:"
79
75
  msgstr ""
80
76
 
77
+ #. placeholder {0}: tosLink ? ( <LinkAnchor className="text-primary underline" link={tosLink}> <Trans>Terms of Service</Trans> </LinkAnchor> ) : ( <Trans>Terms of Service</Trans> )
78
+ #. placeholder {1}: ppLink ? ( <LinkAnchor className="text-primary underline" link={ppLink}> <Trans>Privacy Policy</Trans> </LinkAnchor> ) : ( <Trans>Privacy Policy</Trans> )
81
79
  #: src/views/authorize/sign-up/sign-up-disclaimer.tsx:30
82
80
  msgid "By creating an account you agree to the {0} and the {1} of this service."
83
81
  msgstr ""
84
82
 
85
83
  #: src/views/authorize/welcome/welcome-view.tsx:51
84
+ #: src/components/forms/form-card-async.tsx:85
86
85
  msgid "Cancel"
87
86
  msgstr ""
88
87
 
89
- #: src/views/authorize/sign-in/sign-in-form.tsx:232
88
+ #. placeholder {0}: secondFactor.hint
89
+ #: src/views/authorize/sign-in/sign-in-form.tsx:230
90
90
  msgid "Check your {0} email for a login code and enter it here."
91
91
  msgstr ""
92
92
 
@@ -106,7 +106,7 @@ msgstr ""
106
106
  msgid "Confirm your password to continue"
107
107
  msgstr ""
108
108
 
109
- #: src/views/authorize/sign-in/sign-in-form.tsx:223
109
+ #: src/views/authorize/sign-in/sign-in-form.tsx:221
110
110
  msgid "Confirmation code"
111
111
  msgstr ""
112
112
 
@@ -118,7 +118,7 @@ msgstr ""
118
118
  msgid "Create Account"
119
119
  msgstr ""
120
120
 
121
- #: src/views/authorize/accept/accept-form.tsx:60
121
+ #: src/views/authorize/accept/accept-form.tsx:61
122
122
  msgid "Deny access"
123
123
  msgstr ""
124
124
 
@@ -181,10 +181,11 @@ msgstr ""
181
181
  msgid "Forgot Password"
182
182
  msgstr ""
183
183
 
184
- #: src/views/authorize/sign-in/sign-in-form.tsx:178
184
+ #: src/views/authorize/sign-in/sign-in-form.tsx:181
185
185
  msgid "Forgot?"
186
186
  msgstr ""
187
187
 
188
+ #. placeholder {0}: account.preferred_username || account.email || account.sub
188
189
  #: src/views/authorize/accept/accept-view.tsx:40
189
190
  msgid "Grant access to your <0>{0}</0> account"
190
191
  msgstr ""
@@ -202,6 +203,7 @@ msgid "Home"
202
203
  msgstr ""
203
204
 
204
205
  #: src/views/authorize/sign-in/sign-in-picker.tsx:86
206
+ #: src/views/authorize/sign-in/sign-in-form.tsx:138
205
207
  msgid "Identifier"
206
208
  msgstr ""
207
209
 
@@ -222,7 +224,7 @@ msgstr ""
222
224
  msgid "Let's get your password reset!"
223
225
  msgstr ""
224
226
 
225
- #: src/views/authorize/authorize-view.tsx:172
227
+ #: src/views/authorize/authorize-view.tsx:178
226
228
  msgid "Login complete"
227
229
  msgstr ""
228
230
 
@@ -230,6 +232,10 @@ msgstr ""
230
232
  msgid "Login to account that is not listed"
231
233
  msgstr ""
232
234
 
235
+ #: src/components/layouts/layout-welcome.tsx:45
236
+ msgid "Logo"
237
+ msgstr ""
238
+
233
239
  #: src/components/forms/input-token.tsx:59
234
240
  msgid "Looks like {example}"
235
241
  msgstr ""
@@ -269,6 +275,7 @@ msgid "Only letters, numbers, and hyphens"
269
275
  msgstr ""
270
276
 
271
277
  #: src/views/authorize/sign-up/sign-up-account-form.tsx:128
278
+ #: src/views/authorize/sign-in/sign-in-form.tsx:162
272
279
  #: src/components/forms/input-password.tsx:53
273
280
  msgid "Password"
274
281
  msgstr ""
@@ -293,7 +300,7 @@ msgstr ""
293
300
  msgid "Password with at least {MIN_PASSWORD_LENGTH} characters"
294
301
  msgstr ""
295
302
 
296
- #: src/views/authorize/sign-in/sign-in-form.tsx:192
303
+ #: src/views/authorize/sign-in/sign-in-form.tsx:196
297
304
  msgid "Please verify the domain name of the website before entering your password. Never enter your password on a domain you do not trust."
298
305
  msgstr ""
299
306
 
@@ -303,12 +310,12 @@ msgstr ""
303
310
  msgid "Privacy Policy"
304
311
  msgstr ""
305
312
 
306
- #: src/views/authorize/sign-in/sign-in-form.tsx:206
307
- #: src/views/authorize/sign-in/sign-in-form.tsx:211
313
+ #: src/views/authorize/sign-in/sign-in-form.tsx:205
314
+ #: src/views/authorize/sign-in/sign-in-form.tsx:210
308
315
  msgid "Remember this account on this device"
309
316
  msgstr ""
310
317
 
311
- #: src/views/authorize/accept/accept-form.tsx:123
318
+ #: src/views/authorize/accept/accept-form.tsx:124
312
319
  msgid "Requested permissions"
313
320
  msgstr ""
314
321
 
@@ -320,7 +327,7 @@ msgstr ""
320
327
  msgid "Reset Password"
321
328
  msgstr ""
322
329
 
323
- #: src/views/authorize/sign-in/sign-in-form.tsx:176
330
+ #: src/views/authorize/sign-in/sign-in-form.tsx:179
324
331
  msgid "Reset your password"
325
332
  msgstr ""
326
333
 
@@ -332,14 +339,13 @@ msgstr ""
332
339
  msgid "Select from an existing account"
333
340
  msgstr ""
334
341
 
335
- #: src/views/authorize/sign-in/sign-in-form.tsx:202
336
- msgid "Session"
337
- msgstr ""
338
-
339
342
  #: src/views/authorize/welcome/welcome-view.tsx:45
343
+ #: src/views/authorize/sign-in/sign-in-view.tsx:48
344
+ #: src/views/authorize/sign-in/sign-in-form.tsx:135
340
345
  msgid "Sign in"
341
346
  msgstr ""
342
347
 
348
+ #. placeholder {0}: account.name
343
349
  #: src/views/authorize/sign-in/sign-in-picker.tsx:75
344
350
  msgid "Sign in as {0}"
345
351
  msgstr ""
@@ -426,7 +432,7 @@ msgstr ""
426
432
  msgid "Unexpected server response"
427
433
  msgstr ""
428
434
 
429
- #: src/views/authorize/accept/accept-form.tsx:142
435
+ #: src/views/authorize/accept/accept-form.tsx:147
430
436
  msgid "Uniquely identify you"
431
437
  msgstr ""
432
438
 
@@ -442,7 +448,7 @@ msgstr ""
442
448
  msgid "Verify you are human"
443
449
  msgstr ""
444
450
 
445
- #: src/views/authorize/sign-in/sign-in-form.tsx:189
451
+ #: src/views/authorize/sign-in/sign-in-form.tsx:193
446
452
  msgid "Warning"
447
453
  msgstr ""
448
454
 
@@ -458,7 +464,7 @@ msgstr ""
458
464
  msgid "Wrong identifier or password"
459
465
  msgstr ""
460
466
 
461
- #: src/views/authorize/authorize-view.tsx:173
467
+ #: src/views/authorize/authorize-view.tsx:179
462
468
  msgid "You are being redirected..."
463
469
  msgstr ""
464
470
 
@@ -478,6 +484,7 @@ msgstr ""
478
484
  msgid "Your account"
479
485
  msgstr ""
480
486
 
487
+ #. placeholder {0}: segment.length ? ( <strong className="text-gray-800 dark:text-gray-200"> {preview} </strong> ) : ( <span aria-hidden className="w-24 rounded-md bg-gray-300 p-2 dark:bg-slate-600" /> )
481
488
  #: src/views/authorize/sign-up/sign-up-handle-form.tsx:217
482
489
  msgid "Your full username will be: {0}"
483
490
  msgstr ""
@@ -1,48 +1,73 @@
1
1
  import { I18n } from '@lingui/core'
2
2
  import { I18nProvider } from '@lingui/react'
3
- import { ReactNode, useEffect, useMemo, useState } from 'react'
3
+ import {
4
+ ReactNode,
5
+ createContext,
6
+ useContext,
7
+ useEffect,
8
+ useMemo,
9
+ useState,
10
+ } from 'react'
4
11
  // @NOTE run "pnpm run po:compile" to compile the messages from the PO files
5
12
  import { messages as en } from './en/messages.ts'
6
13
  import { loadMessages } from './load.ts'
7
- import { LocaleContext, LocaleContextValue } from './locale-context.ts'
8
- import { KnownLocale, knownLocales, locales, resolveLocale } from './locales.ts'
14
+ import { Locale, detectLocale, isLocale, locales } from './locales.ts'
9
15
 
10
- export type LocaleProviderProps = {
11
- availableLocales?: readonly string[]
12
- children?: ReactNode
16
+ export type LocaleContextValue = {
17
+ locale: string
18
+ locales: Partial<Record<Locale, { name: string; flag?: string }>>
19
+ setLocale: (locale: Locale) => void
20
+ }
21
+
22
+ const LocaleContext = createContext<LocaleContextValue | null>(null)
23
+
24
+ export function useLocaleContext(): LocaleContextValue {
25
+ const context = useContext(LocaleContext)
26
+ if (!context) {
27
+ throw new Error('useLocaleContext must be used within a LocaleProvider')
28
+ }
29
+ return context
13
30
  }
14
31
 
15
32
  export function LocaleProvider({
16
- availableLocales,
33
+ userLocales = [],
17
34
  children,
18
- }: LocaleProviderProps) {
35
+ }: {
36
+ userLocales?: readonly string[]
37
+ children?: ReactNode
38
+ }) {
19
39
  // Bundle "en" messages with the app
20
- const [i18n] = useState(() => new I18n({ locale: 'en', messages: { en } }))
40
+ const i18n = useMemo(() => new I18n({ locale: 'en', messages: { en } }), [])
21
41
 
22
- const [desiredLocale, setDesiredLocale] = useState<KnownLocale>(() =>
23
- detectLocale(
24
- knownLocales.filter(
25
- (l) => !availableLocales || availableLocales.includes(l),
26
- ),
27
- ),
28
- )
29
42
  const [currentLocale, setCurrentLocale] = useState<string>(() => i18n.locale)
43
+ const [desiredLocale, setDesiredLocale] = useState<Locale>(() => {
44
+ return detectLocale(userLocales)
45
+ })
30
46
 
31
- const [loaded, setLoaded] = useState(desiredLocale === currentLocale)
47
+ // A boolean that is used to avoid flickering of "en" content during initial
48
+ // load.
49
+ const [initialized, setInitialized] = useState(
50
+ desiredLocale === currentLocale,
51
+ )
32
52
 
33
- // Keep currentLocale in sync with i18n
53
+ // Protect against illegal change of the locale directly through the i18n object
34
54
  useEffect(() => {
35
- const onChange = () => {
36
- setCurrentLocale(i18n.locale)
37
- document.documentElement.setAttribute('lang', i18n.locale)
55
+ if (!isLocale(currentLocale)) {
56
+ setDesiredLocale('en')
38
57
  }
58
+ }, [locales, currentLocale])
59
+
60
+ // Keep currentLocale in sync with i18n's locale prop
61
+ useEffect(() => {
62
+ const onChange = () => setCurrentLocale(i18n.locale)
39
63
  i18n.on('change', onChange)
40
64
  return () => i18n.removeListener('change', onChange)
41
65
  }, [i18n])
42
66
 
67
+ // Trigger loading of `desiredLocale`
43
68
  useEffect(() => {
44
69
  if (currentLocale === desiredLocale) {
45
- setLoaded(true)
70
+ setInitialized(true)
46
71
  return
47
72
  }
48
73
 
@@ -56,7 +81,7 @@ export function LocaleProvider({
56
81
  console.error(`Failed to load locale "${desiredLocale}":`, err)
57
82
  })
58
83
  .finally(() => {
59
- if (!canceled) setLoaded(true)
84
+ if (!canceled) setInitialized(true)
60
85
  })
61
86
  return () => {
62
87
  canceled = true
@@ -66,47 +91,18 @@ export function LocaleProvider({
66
91
  const value = useMemo<LocaleContextValue>(
67
92
  () => ({
68
93
  locale: currentLocale,
69
- locales: Object.fromEntries(
70
- knownLocales
71
- .filter((l) => !availableLocales || availableLocales.includes(l))
72
- .map((l) => [l, locales[l]]),
73
- ),
74
- setLocale: setDesiredLocale,
94
+ locales,
95
+ setLocale: (locale) => {
96
+ if (isLocale(locale)) setDesiredLocale(locale)
97
+ else throw new TypeError(`"${locale}" is not an available locale`)
98
+ },
75
99
  }),
76
- [currentLocale, availableLocales, locales, setDesiredLocale],
100
+ [locales, currentLocale],
77
101
  )
78
102
 
79
103
  return (
80
104
  <LocaleContext value={value}>
81
- <I18nProvider i18n={i18n}>{loaded && children}</I18nProvider>
105
+ <I18nProvider i18n={i18n}>{initialized && children}</I18nProvider>
82
106
  </LocaleContext>
83
107
  )
84
108
  }
85
-
86
- function detectLocale<L extends string>(
87
- availableLocales: readonly L[],
88
- fallbackLocale: L | 'en' = 'en',
89
- ): L {
90
- // Use, in priority, the locale that was set by the backend
91
- if (typeof document === 'object') {
92
- const htmlLang = document.documentElement.getAttribute('lang')
93
- const resolved = htmlLang && resolveLocale(htmlLang, availableLocales)
94
- if (resolved) return resolved
95
- }
96
-
97
- // Should that fail (though it should probably never), negotiate with the browser
98
- if (typeof navigator === 'object' && navigator.languages) {
99
- for (const locale of navigator.languages) {
100
- const resolved = resolveLocale(locale, availableLocales)
101
- if (resolved) return resolved
102
- }
103
- }
104
-
105
- const fallback = resolveLocale(fallbackLocale, availableLocales)
106
- if (fallback) return fallback
107
-
108
- // Type-safety
109
- throw new TypeError(
110
- `Available locales should always contain "${fallbackLocale}"`,
111
- )
112
- }
@@ -1,7 +1,7 @@
1
1
  import { useLingui } from '@lingui/react/macro'
2
+ import { clsx } from 'clsx'
2
3
  import { JSX } from 'react'
3
- import { clsx } from '../lib/clsx.ts'
4
- import { useLocaleContext } from './locale-context.ts'
4
+ import { useLocaleContext } from './locale-provider.tsx'
5
5
 
6
6
  export type LocaleSelectorProps = Omit<
7
7
  JSX.IntrinsicElements['select'],
@@ -20,22 +20,22 @@ export function LocaleSelector({
20
20
  <select
21
21
  {...props}
22
22
  className={clsx(
23
- 'accent-brand',
23
+ 'accent-primary',
24
24
  // Background
25
- 'bg-gray-100 focus:bg-slate-200 has-[:focus]:bg-slate-200',
26
- 'dark:bg-slate-800 dark:focus:bg-slate-700 dark:has-[:focus]:bg-slate-700',
25
+ 'bg-contrast-25',
26
+ 'hover:bg-contrast-0 focus:bg-contrast-0 dark:hover:bg-contrast-0',
27
+ 'focus:bg-contrast-0 dark:focus:bg-contrast-0',
27
28
  // Border
28
- 'outline-none',
29
- 'border-solid border-2 border-transparent',
30
- 'focus:border-brand has-[:focus]:border-brand',
31
- 'hover:border-gray-400 hover:focus:border-gray-400',
32
- 'dark:hover:border-gray-500 dark:hover:focus:border-gray-500',
29
+ 'outline-hidden',
30
+ 'border-contrast-100 border',
33
31
  // Border
34
- 'rounded-lg',
32
+ 'rounded-full',
35
33
  // Font
36
34
  'text-slate-600 dark:text-slate-300',
37
35
  // Layout
38
- 'py-1 px-2',
36
+ 'px-2 py-1',
37
+ // Misc
38
+ 'cursor-pointer',
39
39
  className,
40
40
  )}
41
41
  value={locale}
@@ -49,8 +49,7 @@ export function LocaleSelector({
49
49
  >
50
50
  {Object.entries(locales).map(([key, { name, flag }]) => (
51
51
  <option key={key} value={key}>
52
- {name}
53
- {flag ? ` ${flag}` : ''}
52
+ {flag ? `${flag} ${name}` : name}
54
53
  </option>
55
54
  ))}
56
55
  </select>