diff options
45 files changed, 1661 insertions, 984 deletions
diff --git a/README.md b/README.md index 64bcbcea5..f86d52b53 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ The Bluesky Social application encompasses a set of schemas and APIs built in th - Open an issue and give some time for discussion before submitting a PR. - Stay away from PRs like... - Changing "Post" to "Skeet." - - Refactoring the codebase, e.g., to replace MobX with Redux or something. + - Refactoring the codebase, e.g., to replace React Query with Redux Toolkit or something. - Adding entirely new features without prior discussion. Remember, we serve a wide community of users. Our day-to-day involves us constantly asking "which top priority is our top priority." If you submit well-written PRs that solve problems concisely, that's an awesome contribution. Otherwise, as much as we'd love to accept your ideas and contributions, we really don't have the bandwidth. That's what forking is for! diff --git a/assets/icons/verifiedCheck.svg b/assets/icons/verifiedCheck.svg index f76955ac8..d66a9926f 100644 --- a/assets/icons/verifiedCheck.svg +++ b/assets/icons/verifiedCheck.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle cx="12" cy="12" r="12" fill="#208BFE"/><path fill="#fff" fill-rule="evenodd" d="M18.311 7.421a1.437 1.437 0 0 1 0 2.033l-6.571 6.571a1.437 1.437 0 0 1-2.033 0L6.42 12.74a1.438 1.438 0 0 1 2.033-2.033l2.27 2.269 5.554-5.555a1.437 1.437 0 0 1 2.033 0Z" clip-rule="evenodd"/></svg> +<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><circle cx="12" cy="12" r="11.5" fill="#1183FE"/><path fill="#fff" fill-rule="evenodd" d="M17.659 8.175a1.36 1.36 0 0 1 0 1.925l-6.224 6.223a1.36 1.36 0 0 1-1.925 0L6.4 13.212a1.361 1.361 0 0 1 1.925-1.925l2.149 2.148 5.26-5.26a1.36 1.36 0 0 1 1.925 0Z" clip-rule="evenodd"/></svg> diff --git a/assets/icons/verifierCheck.svg b/assets/icons/verifierCheck.svg index 71158eb13..d49b37ee2 100644 --- a/assets/icons/verifierCheck.svg +++ b/assets/icons/verifierCheck.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#208BFE" d="M8.792 1.54a4.11 4.11 0 0 1 6.416 0 4.13 4.13 0 0 0 3.146 1.54c2.616.04 4.544 2.5 4 5.1a4.28 4.28 0 0 0 .777 3.462c1.6 2.104.912 5.17-1.427 6.36a4.21 4.21 0 0 0-2.177 2.774c-.62 2.584-3.408 3.948-5.781 2.83a4.1 4.1 0 0 0-3.492 0c-2.373 1.118-5.16-.246-5.78-2.83a4.21 4.21 0 0 0-2.178-2.775c-2.34-1.19-3.028-4.256-1.427-6.36a4.28 4.28 0 0 0 .777-3.46c-.544-2.602 1.384-5.06 4-5.1a4.13 4.13 0 0 0 3.146-1.54Z"/><path fill="#fff" fill-rule="evenodd" d="M17.659 8.399a1.36 1.36 0 0 1 0 1.925l-6.224 6.223a1.36 1.36 0 0 1-1.925 0L6.4 13.435a1.361 1.361 0 1 1 1.925-1.925l2.149 2.15 5.26-5.261a1.36 1.36 0 0 1 1.925 0Z" clip-rule="evenodd"/></svg> +<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="#1185FE" d="M8.792 1.615a4.154 4.154 0 0 1 6.416 0 4.15 4.15 0 0 0 3.146 1.515 4.154 4.154 0 0 1 4 5.017 4.15 4.15 0 0 0 .777 3.404 4.154 4.154 0 0 1-1.427 6.255 4.15 4.15 0 0 0-2.177 2.73 4.154 4.154 0 0 1-5.781 2.784 4.15 4.15 0 0 0-3.492 0 4.154 4.154 0 0 1-5.78-2.784 4.15 4.15 0 0 0-2.178-2.73A4.154 4.154 0 0 1 .87 11.551a4.15 4.15 0 0 0 .776-3.404 4.154 4.154 0 0 1 4-5.017 4.15 4.15 0 0 0 3.146-1.515Z"/><path fill="#fff" fill-rule="evenodd" d="M17.861 8.26a1.44 1.44 0 0 1 0 2.033l-6.571 6.571a1.437 1.437 0 0 1-2.033 0L5.97 13.58a1.438 1.438 0 0 1 2.033-2.033l2.27 2.269 5.554-5.555a1.437 1.437 0 0 1 2.033 0Z" clip-rule="evenodd"/></svg> diff --git a/docs/deploy-ota.md b/docs/deploy-ota.md index 391a6bf6b..e75ac1b3a 100644 --- a/docs/deploy-ota.md +++ b/docs/deploy-ota.md @@ -1,95 +1,138 @@ # OTA Deployments -## Overview +## Automatic internal OTAs - +OTA deployments to TestFlight/APK installs happen automatically upon all merges +into main. In cases where the fingerprint diff shows incompatible native +changes, a new client build will automatically be ran and deployed to TestFlight +(iOS) or delivered in Slack (Android). -## Internal Deployments +## Production OTAs -Internal OTA deployments should be performed automatically upon all merges into main. In cases where the fingerprint -diff results in incompatible native changes, a new client build will automatically be ran and deployed to TestFlight -(iOS) or delivered in Slack (Android). +Production OTAs can only update the JavaScript bundle. Changes to native modules +must be done as a full release cycle through the app stores. + +> [!TIP] +> If you're using a TestFlight build, in order to reference the correct build +> number and to verify the success of an OTA, you will need to delete the +> TestFlight app itself, delete the Bluesky app entirely, and re-install from +> the App Store. + +### 1. Find the build numbers + +Find the latest production build numbers for iOS and Android in Slack. These are +spit out into `#bot-client-builds` after each release. You can also find this +information under the `About` section in app settings. + +| Slack | In app | +| ----- | ------ | +|  |  | + +### 2. Ensure the release is tagged + +You need to ensure that the latest release was properly tagged using the format +`1.X.0`. If the commit is not properly tagged, then the OTA deployment will +simply fail since the GitHub Action will not be able to find a commit to +fingerprint and diff against. + +### 3. Create an OTA branch + +Create a branch based off the last commit that was deployed in the most recent +release. This could be the commit that was tagged `1.x.0`, or a later commit, +but it **needs to be the tip of the latest production release** in any case. +Double check yourself by ensuring that the `version` in `package.json` matches +what's in the latest release. + +This new OTA branch should follow the format `1.X.0-ota-1`. If one or more OTAs +have already been deployed for this release, incremement the branch name e.g. +`1.x.0-ota-2`. + +### 4. Add commits to the OTA branch + +Cherry pick in the commits that need to be deployed on top of the most recent +release or OTA. + +### 5. Manually set build numbers + +Log in to the EAS CLI with `eas login` and manually set the build numbers to the +values you found in **Step 1**. + +```sh +> npx eas build:version:set -p ios +> +> Project @blueskysocial/bluesky with bundle identifier "xyz.blueskyweb.app" is configured with buildNumber 1011. +> ✔ What version would you like to set? … 1009 +> +> npx eas build:version:set -p android +> +> Project @blueskysocial/bluesky with application ID "xyz.blueskyweb.app" is configured with versionCode 641. +> ✔ What version would you like to set? … 639 +``` -## Production Deployments - -### Prerequisites - -- Find the latest production build number for both iOS and Android in Slack. These are listed in #client-builds - - Production builds always send the Version Number and Build Number in the Slack message. Search for the latest - production version number, and you should find the correct information. - -  - -- It may also be useful to check the current production clients for these values. This will also help for testing. Note -that you will need to _fully_ remove the existing internal client build from your device, otherwise the given values in -the app may differ from the actual production values. - -  - -- You should have signed in to EAS locally through npx eas login. You will need to modify the build number in a -subsequent step. -- Ensure that the commit the initial client was cut from is properly tagged in git. The tag should be in the format of 1.X.0 - - Note: If the commit is not properly tagged, then the OTA deployment will simply fail since the GitHub Action will - not be able to find a commit to fingerprint and diff against. - -### Preparation - -- Create a new branch from the git tag that the initial release was cut from if no OTA deployment has been made yet for this -client. Name this branch `1.X.0-ota-1` -- If a deployment has been made previously for this release, increment the branch name, i.e. `1.x.0-ota-2` -- If necessary, cherry-pick the commit(s) that you wish to deploy -- Ensure that the package.json’s version field is set to the appropriate value. As long as used the correct git tag -to create your branch from, this should be properly set. - -### Deployment - -- Update the build number through EAS to match the build numbers of the - production iOS/Android apps - - Note: This isn’t strictly necessary, but having a step that takes you off of GitHub and into the terminal provides - a little “friction” to avoid fat fingering a release. Since there are legitimate reasons to just “click and deploy” - for internal builds, I felt it useful to make sure it doesn’t accidentally become a prod deployment. - - Set the build numbers to the values found in the prerequisite steps. Again, this should be the - build number for the current production release you want to deploy for. - - `npx eas build:version:set -p ios` - - `npx eas build:version:set -p android` - - These steps should spit out what the current build number is, save those values - for later too -- Run the deployment - - Navigate to https://github.com/bluesky-social/social-app/actions/workflows/bundle-deploy-eas-update.yml - - Select the “Run Workflow” dropdown - -  - - - Select the branch for the deployment you are releasing. - -  - - - Double check the branch selection. - - Select the production channel - - Enter the version for the client you are releasing to, i.e. 1.80.0 - - Note: If you do enter an incorrect version here, the deployment will either: - - Fail because the action cannot find a commit with your misentered version - - Succeed - but with no users receiving the update. This is because the version you entered will not properly - correlate to a _build number_ as well, so no clients in the wild will be able to receive the update. - -  - - - Triple check the branch selection. - - You selected the correct branch - - You selected the "Production" channel - - You entered the correct version in the format of `1.X.0`. - - Press “Run Workflow” - -In about five minutes, the new deployment should be available for download. To test: - -- Remove the internal build of the app from your device -- Download the app from the App Store/Google Play -- Launch the app once and wait approximately 15 seconds -- Relaunch the app -- Check the Settings page and scroll to the bottom. The commit hash should now be the latest commit on your deployed branch. - -### Post Deployment - -- Reset both platforms build numbers to what they were before the OTA - deployment. These values should have been logged by the EAS CLI when you - reset them to the production values prior to OTA. +👉 **Save the previous values,** in this case `1011` and `641`, so you can reset +them after the OTA completes. + +### 6. Run the GitHub actions +You'll need to run two separate actions: one to deploy the iOS/Android OTA +itself, and one to build the web Docker container. + +**For the iOS/Android OTA,** head to [Actions > Bundle and Deploy EAS +Update](https://github.com/bluesky-social/social-app/actions/workflows/bundle-deploy-eas-update.yml) +and run the action. + +| Steps | | +| ----- | --- | +| Select your OTA branch `1.x.0-ota-x`, select `production` in the dropdown, enter the git tag of the latest release `1.x.0`, and click "Run workflow" |  | + +> [!NOTE] +> If you do enter an incorrect version here, the deployment will either: +> - Fail, because the action cannot find a commit with your misentered version +> - Succeed, but with no users receiving the update. This is because the version +> you entered will not properly correlate to a _build number_ as well, so no +> clients in the wild will be able to receive the update. + +**For web,** head to [Actions > +build-and-push-bskyweb-aws](https://github.com/bluesky-social/social-app/actions/workflows/build-and-push-bskyweb-aws.yaml) +and run the action. + +| Steps | | +| ----- | --- | +| Select your OTA branch `1.x.0-ota-x` and click "Run workflow" |  | + +### 7. Deploy web + +Once the web Docker container build finishes, go to your `1.x.0-ota-x` branch, +copy the most recent commit hash. Post this hash in `#ops-deploys` and request +someone with web deploy access deploy the built container. + +### 8. Confirm successful deployment + +In about five minutes, the new deployment should be deployed and devices will +begin downloading and installing in the background. + +To confirm this, as mentioned above, you must completely clear the TestFlight +build from your device and re-install from the App Store. Then, you'll need to: +- Launch the app (or quit and reopen) and wait ~15s for the download to complete +- Quit and reopen the app +- Check the `Settings > About` page and confirm the has matches the most recent has on your OTA branch + +### 9. Reset build numbers + +Grab the build numbers you saved in **Step 5** and reverse the EAS CLI commands +to reset the build numbers. + +```sh +> npx eas build:version:set -p ios +> +> Project @blueskysocial/bluesky with bundle identifier "xyz.blueskyweb.app" is configured with buildNumber 1009. +> ✔ What version would you like to set? … 1011 +> +> npx eas build:version:set -p android +> +> Project @blueskysocial/bluesky with application ID "xyz.blueskyweb.app" is configured with versionCode 639. +> ✔ What version would you like to set? … 641 +``` + +## Overview diagram + + diff --git a/docs/img/ios_settings_about.jpeg b/docs/img/ios_settings_about.jpeg new file mode 100644 index 000000000..ff2db7119 --- /dev/null +++ b/docs/img/ios_settings_about.jpeg Binary files differdiff --git a/docs/img/ota_action.png b/docs/img/ota_action.png new file mode 100644 index 000000000..56911400a --- /dev/null +++ b/docs/img/ota_action.png Binary files differdiff --git a/docs/img/slack_client_builds.jpeg b/docs/img/slack_client_builds.jpeg new file mode 100644 index 000000000..4973a2ca7 --- /dev/null +++ b/docs/img/slack_client_builds.jpeg Binary files differdiff --git a/docs/img/web_action.png b/docs/img/web_action.png new file mode 100644 index 000000000..f02c0aa6d --- /dev/null +++ b/docs/img/web_action.png Binary files differdiff --git a/package.json b/package.json index e4ba9be9e..2ed14061f 100644 --- a/package.json +++ b/package.json @@ -80,10 +80,6 @@ "@mattermost/react-native-paste-input": "^0.7.1", "@miblanchard/react-native-slider": "^2.3.1", "@mozzius/expo-dynamic-app-icon": "^1.5.0", - "@radix-ui/react-dismissable-layer": "^1.1.5", - "@radix-ui/react-dropdown-menu": "2.1.6", - "@radix-ui/react-focus-guards": "^1.1.1", - "@radix-ui/react-focus-scope": "^1.1.2", "@react-native-async-storage/async-storage": "1.23.1", "@react-native-menu/menu": "^1.1.7", "@react-native-picker/picker": "2.10.3", @@ -167,6 +163,7 @@ "patch-package": "^6.5.1", "postinstall-postinstall": "^2.1.0", "psl": "^1.9.0", + "radix-ui": "^1.2.0", "react": "18.3.1", "react-compiler-runtime": "19.0.0-beta-a7bf2bd-20241110", "react-dom": "18.3.1", diff --git a/src/components/Button.tsx b/src/components/Button.tsx index 123e6ee42..2d6ddc834 100644 --- a/src/components/Button.tsx +++ b/src/components/Button.tsx @@ -1,23 +1,23 @@ import React from 'react' import { - AccessibilityProps, - GestureResponderEvent, - MouseEvent, - NativeSyntheticEvent, + type AccessibilityProps, + type GestureResponderEvent, + type MouseEvent, + type NativeSyntheticEvent, Pressable, - PressableProps, - StyleProp, + type PressableProps, + type StyleProp, StyleSheet, - TargetedEvent, - TextProps, - TextStyle, + type TargetedEvent, + type TextProps, + type TextStyle, View, - ViewStyle, + type ViewStyle, } from 'react-native' import {LinearGradient} from 'expo-linear-gradient' import {atoms as a, flatten, select, tokens, useTheme} from '#/alf' -import {Props as SVGIconProps} from '#/components/icons/common' +import {type Props as SVGIconProps} from '#/components/icons/common' import {Text} from '#/components/Typography' export type ButtonVariant = 'solid' | 'outline' | 'ghost' | 'gradient' @@ -597,7 +597,7 @@ export function useSharedButtonTextStyles() { if (variant === 'solid' || variant === 'gradient') { if (!disabled) { baseStyles.push({ - color: t.palette.contrast_100, + color: t.palette.contrast_50, }) } else { baseStyles.push({ diff --git a/src/components/Dialog/context.ts b/src/components/Dialog/context.ts index 331ff3f33..eb892403f 100644 --- a/src/components/Dialog/context.ts +++ b/src/components/Dialog/context.ts @@ -2,9 +2,9 @@ import React from 'react' import {useDialogStateContext} from '#/state/dialogs' import { - DialogContextProps, - DialogControlRefProps, - DialogOuterProps, + type DialogContextProps, + type DialogControlRefProps, + type DialogOuterProps, } from '#/components/Dialog/types' import {BottomSheetSnapPoint} from '../../../modules/bottom-sheet/src/BottomSheet.types' diff --git a/src/components/Dialog/index.web.tsx b/src/components/Dialog/index.web.tsx index 153954691..12bd8819b 100644 --- a/src/components/Dialog/index.web.tsx +++ b/src/components/Dialog/index.web.tsx @@ -1,17 +1,15 @@ import React, {useImperativeHandle} from 'react' import { FlatList, - FlatListProps, - StyleProp, + type FlatListProps, + type StyleProp, TouchableWithoutFeedback, View, - ViewStyle, + type ViewStyle, } from 'react-native' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {DismissableLayer} from '@radix-ui/react-dismissable-layer' -import {useFocusGuards} from '@radix-ui/react-focus-guards' -import {FocusScope} from '@radix-ui/react-focus-scope' +import {DismissableLayer, FocusGuards, FocusScope} from 'radix-ui/internal' import {RemoveScrollBar} from 'react-remove-scroll-bar' import {logger} from '#/logger' @@ -21,9 +19,9 @@ import {atoms as a, flatten, useBreakpoints, useTheme, web} from '#/alf' import {Button, ButtonIcon} from '#/components/Button' import {Context} from '#/components/Dialog/context' import { - DialogControlProps, - DialogInnerProps, - DialogOuterProps, + type DialogControlProps, + type DialogInnerProps, + type DialogOuterProps, } from '#/components/Dialog/types' import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times' import {Portal} from '#/components/Portal' @@ -162,9 +160,9 @@ export function Inner({ const {close} = React.useContext(Context) const {gtMobile} = useBreakpoints() const {reduceMotionEnabled} = useA11y() - useFocusGuards() + FocusGuards.useFocusGuards() return ( - <FocusScope loop asChild trapped> + <FocusScope.FocusScope loop asChild trapped> <View role="dialog" aria-role="dialog" @@ -191,7 +189,7 @@ export function Inner({ !reduceMotionEnabled && a.zoom_fade_in, style, ])}> - <DismissableLayer + <DismissableLayer.DismissableLayer onInteractOutside={preventDefault} onFocusOutside={preventDefault} onDismiss={close} @@ -200,9 +198,9 @@ export function Inner({ <View style={[gtMobile ? a.p_2xl : a.p_xl, contentContainerStyle]}> {children} </View> - </DismissableLayer> + </DismissableLayer.DismissableLayer> </View> - </FocusScope> + </FocusScope.FocusScope> ) } diff --git a/src/components/Menu/index.web.tsx b/src/components/Menu/index.web.tsx index ae021dcf1..27678bf2f 100644 --- a/src/components/Menu/index.web.tsx +++ b/src/components/Menu/index.web.tsx @@ -1,12 +1,12 @@ import React from 'react' -import {Pressable, StyleProp, View, ViewStyle} from 'react-native' +import {Pressable, type StyleProp, View, type ViewStyle} from 'react-native' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import * as DropdownMenu from '@radix-ui/react-dropdown-menu' +import {DropdownMenu} from 'radix-ui' import {useA11y} from '#/state/a11y' import {atoms as a, flatten, useTheme, web} from '#/alf' -import * as Dialog from '#/components/Dialog' +import type * as Dialog from '#/components/Dialog' import {useInteractionState} from '#/components/hooks/useInteractionState' import { Context, @@ -15,13 +15,13 @@ import { useMenuItemContext, } from '#/components/Menu/context' import { - ContextType, - GroupProps, - ItemIconProps, - ItemProps, - ItemTextProps, - RadixPassThroughTriggerProps, - TriggerProps, + type ContextType, + type GroupProps, + type ItemIconProps, + type ItemProps, + type ItemTextProps, + type RadixPassThroughTriggerProps, + type TriggerProps, } from '#/components/Menu/types' import {Portal} from '#/components/Portal' import {Text} from '#/components/Typography' diff --git a/src/components/Prompt.tsx b/src/components/Prompt.tsx index ed8c15f15..f21c98ff8 100644 --- a/src/components/Prompt.tsx +++ b/src/components/Prompt.tsx @@ -52,9 +52,7 @@ export function Outer({ <Dialog.ScrollableInner accessibilityLabelledBy={titleId} accessibilityDescribedBy={descriptionId} - style={[ - gtMobile ? {width: 'auto', maxWidth: 400, minWidth: 200} : a.w_full, - ]}> + style={[gtMobile ? {width: 400} : a.w_full]}> {children} </Dialog.ScrollableInner> </Context.Provider> diff --git a/src/components/dialogs/Context.tsx b/src/components/dialogs/Context.tsx index c9dff9a99..fda904b8b 100644 --- a/src/components/dialogs/Context.tsx +++ b/src/components/dialogs/Context.tsx @@ -1,32 +1,66 @@ -import React from 'react' +import {createContext, useContext, useMemo, useState} from 'react' import * as Dialog from '#/components/Dialog' -type Control = Dialog.DialogOuterProps['control'] +type Control = Dialog.DialogControlProps + +export type StatefulControl<T> = { + control: Control + open: (value: T) => void + clear: () => void + value: T | undefined +} type ControlsContext = { mutedWordsDialogControl: Control signinDialogControl: Control + inAppBrowserConsentControl: StatefulControl<string> } -const ControlsContext = React.createContext({ - mutedWordsDialogControl: {} as Control, - signinDialogControl: {} as Control, -}) +const ControlsContext = createContext<ControlsContext | null>(null) export function useGlobalDialogsControlContext() { - return React.useContext(ControlsContext) + const ctx = useContext(ControlsContext) + if (!ctx) { + throw new Error( + 'useGlobalDialogsControlContext must be used within a Provider', + ) + } + return ctx } export function Provider({children}: React.PropsWithChildren<{}>) { const mutedWordsDialogControl = Dialog.useDialogControl() const signinDialogControl = Dialog.useDialogControl() - const ctx = React.useMemo<ControlsContext>( - () => ({mutedWordsDialogControl, signinDialogControl}), - [mutedWordsDialogControl, signinDialogControl], + const inAppBrowserConsentControl = useStatefulDialogControl<string>() + + const ctx = useMemo<ControlsContext>( + () => ({ + mutedWordsDialogControl, + signinDialogControl, + inAppBrowserConsentControl, + }), + [mutedWordsDialogControl, signinDialogControl, inAppBrowserConsentControl], ) return ( <ControlsContext.Provider value={ctx}>{children}</ControlsContext.Provider> ) } + +function useStatefulDialogControl<T>(initialValue?: T): StatefulControl<T> { + const [value, setValue] = useState(initialValue) + const control = Dialog.useDialogControl() + return useMemo( + () => ({ + control, + open: (v: T) => { + setValue(v) + control.open() + }, + clear: () => setValue(initialValue), + value, + }), + [control, value, initialValue], + ) +} diff --git a/src/components/dialogs/InAppBrowserConsent.tsx b/src/components/dialogs/InAppBrowserConsent.tsx new file mode 100644 index 000000000..4459c64db --- /dev/null +++ b/src/components/dialogs/InAppBrowserConsent.tsx @@ -0,0 +1,111 @@ +import {useCallback} from 'react' +import {View} from 'react-native' +import {msg, Trans} from '@lingui/macro' +import {useLingui} from '@lingui/react' + +import {useOpenLink} from '#/lib/hooks/useOpenLink' +import {isWeb} from '#/platform/detection' +import {useSetInAppBrowser} from '#/state/preferences/in-app-browser' +import {atoms as a, useTheme} from '#/alf' +import {Button, ButtonIcon, ButtonText} from '#/components/Button' +import * as Dialog from '#/components/Dialog' +import {SquareArrowTopRight_Stroke2_Corner0_Rounded as External} from '#/components/icons/SquareArrowTopRight' +import {Text} from '#/components/Typography' +import {useGlobalDialogsControlContext} from './Context' + +export function InAppBrowserConsentDialog() { + const {inAppBrowserConsentControl} = useGlobalDialogsControlContext() + + if (isWeb) return null + + return ( + <Dialog.Outer + control={inAppBrowserConsentControl.control} + nativeOptions={{preventExpansion: true}} + onClose={inAppBrowserConsentControl.clear}> + <Dialog.Handle /> + <InAppBrowserConsentInner href={inAppBrowserConsentControl.value} /> + </Dialog.Outer> + ) +} + +function InAppBrowserConsentInner({href}: {href?: string}) { + const control = Dialog.useDialogContext() + const {_} = useLingui() + const t = useTheme() + const setInAppBrowser = useSetInAppBrowser() + const openLink = useOpenLink() + + const onUseIAB = useCallback(() => { + control.close(() => { + setInAppBrowser(true) + if (href) { + openLink(href, true) + } + }) + }, [control, setInAppBrowser, href, openLink]) + + const onUseLinking = useCallback(() => { + control.close(() => { + setInAppBrowser(false) + if (href) { + openLink(href, false) + } + }) + }, [control, setInAppBrowser, href, openLink]) + + const onCancel = useCallback(() => { + control.close() + }, [control]) + + return ( + <Dialog.ScrollableInner label={_(msg`How should we open this link?`)}> + <View style={[a.gap_2xl]}> + <View style={[a.gap_sm]}> + <Text style={[a.font_heavy, a.text_2xl]}> + <Trans>How should we open this link?</Trans> + </Text> + <Text style={[t.atoms.text_contrast_high, a.leading_snug, a.text_md]}> + <Trans> + Your choice will be remembered for future links. You can change it + at any time in settings. + </Trans> + </Text> + </View> + <View style={[a.gap_sm]}> + <Button + label={_(msg`Use in-app browser`)} + onPress={onUseIAB} + size="large" + variant="solid" + color="primary"> + <ButtonText> + <Trans>Use in-app browser</Trans> + </ButtonText> + </Button> + <Button + label={_(msg`Use my default browser`)} + onPress={onUseLinking} + size="large" + variant="solid" + color="secondary"> + <ButtonText> + <Trans>Use my default browser</Trans> + </ButtonText> + <ButtonIcon position="right" icon={External} /> + </Button> + <Button + label={_(msg`Cancel`)} + onPress={onCancel} + size="large" + variant="ghost" + color="secondary"> + <ButtonText> + <Trans>Cancel</Trans> + </ButtonText> + </Button> + </View> + </View> + </Dialog.ScrollableInner> + ) +} diff --git a/src/components/dms/EmojiReactionPicker.web.tsx b/src/components/dms/EmojiReactionPicker.web.tsx index d9e1c87f7..cdd3ce414 100644 --- a/src/components/dms/EmojiReactionPicker.web.tsx +++ b/src/components/dms/EmojiReactionPicker.web.tsx @@ -4,10 +4,10 @@ import {type ChatBskyConvoDefs} from '@atproto/api' import EmojiPicker from '@emoji-mart/react' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import * as DropdownMenu from '@radix-ui/react-dropdown-menu' +import {DropdownMenu} from 'radix-ui' import {useSession} from '#/state/session' -import {type Emoji} from '#/view/com/composer/text-input/web/EmojiPicker.web' +import {type Emoji} from '#/view/com/composer/text-input/web/EmojiPicker' import {useWebPreloadEmoji} from '#/view/com/composer/text-input/web/useWebPreloadEmoji' import {atoms as a, flatten, useTheme} from '#/alf' import {DotGrid_Stroke2_Corner0_Rounded as DotGridIcon} from '#/components/icons/DotGrid' diff --git a/src/components/icons/VerifiedCheck.tsx b/src/components/icons/VerifiedCheck.tsx index 9299eb6e3..9d0aa9158 100644 --- a/src/components/icons/VerifiedCheck.tsx +++ b/src/components/icons/VerifiedCheck.tsx @@ -18,12 +18,12 @@ export const VerifiedCheck = React.forwardRef<Svg, Props>(function LogoImpl( width={size} height={size} style={[style]}> - <Circle cx="12" cy="12" r="12" fill={fill} /> + <Circle cx="12" cy="12" r="11.5" fill={fill} /> <Path fill="#fff" fillRule="evenodd" clipRule="evenodd" - d="M18.311 7.421a1.437 1.437 0 0 1 0 2.033l-6.571 6.571a1.437 1.437 0 0 1-2.033 0L6.42 12.74a1.438 1.438 0 0 1 2.033-2.033l2.27 2.269 5.554-5.555a1.437 1.437 0 0 1 2.033 0Z" + d="M17.659 8.175a1.361 1.361 0 0 1 0 1.925l-6.224 6.223a1.361 1.361 0 0 1-1.925 0L6.4 13.212a1.361 1.361 0 0 1 1.925-1.925l2.149 2.148 5.26-5.26a1.361 1.361 0 0 1 1.925 0Z" /> </Svg> ) diff --git a/src/components/icons/VerifierCheck.tsx b/src/components/icons/VerifierCheck.tsx index 7c3a0149d..143c24b97 100644 --- a/src/components/icons/VerifierCheck.tsx +++ b/src/components/icons/VerifierCheck.tsx @@ -22,13 +22,13 @@ export const VerifierCheck = React.forwardRef<Svg, Props>(function LogoImpl( fill={fill} fillRule="evenodd" clipRule="evenodd" - d="M8.792 1.54a4.11 4.11 0 0 1 6.416 0 4.128 4.128 0 0 0 3.146 1.54c2.616.04 4.544 2.5 4 5.1a4.277 4.277 0 0 0 .777 3.462c1.6 2.104.912 5.17-1.427 6.36a4.21 4.21 0 0 0-2.177 2.774c-.62 2.584-3.408 3.948-5.781 2.83a4.092 4.092 0 0 0-3.492 0c-2.373 1.118-5.16-.246-5.78-2.83a4.21 4.21 0 0 0-2.178-2.775c-2.34-1.19-3.028-4.256-1.427-6.36a4.277 4.277 0 0 0 .776-3.46c-.543-2.602 1.385-5.06 4.001-5.1a4.128 4.128 0 0 0 3.146-1.54Z" + d="M8.792 1.615a4.154 4.154 0 0 1 6.416 0 4.154 4.154 0 0 0 3.146 1.515 4.154 4.154 0 0 1 4 5.017 4.154 4.154 0 0 0 .777 3.404 4.154 4.154 0 0 1-1.427 6.255 4.153 4.153 0 0 0-2.177 2.73 4.154 4.154 0 0 1-5.781 2.784 4.154 4.154 0 0 0-3.492 0 4.154 4.154 0 0 1-5.78-2.784 4.154 4.154 0 0 0-2.178-2.73A4.154 4.154 0 0 1 .87 11.551a4.154 4.154 0 0 0 .776-3.404A4.154 4.154 0 0 1 5.646 3.13a4.154 4.154 0 0 0 3.146-1.515Z" /> <Path fill="#fff" fillRule="evenodd" clipRule="evenodd" - d="M17.659 8.399a1.361 1.361 0 0 1 0 1.925l-6.224 6.223a1.361 1.361 0 0 1-1.925 0L6.4 13.435a1.361 1.361 0 1 1 1.925-1.925l2.149 2.15 5.26-5.261a1.361 1.361 0 0 1 1.925 0Z" + d="M17.861 8.26a1.438 1.438 0 0 1 0 2.033l-6.571 6.571a1.437 1.437 0 0 1-2.033 0L5.97 13.58a1.438 1.438 0 0 1 2.033-2.033l2.27 2.269 5.554-5.555a1.437 1.437 0 0 1 2.033 0Z" /> </Svg> ) diff --git a/src/components/verification/VerificationCreatePrompt.tsx b/src/components/verification/VerificationCreatePrompt.tsx index 39ac6dbf6..eb57d7c36 100644 --- a/src/components/verification/VerificationCreatePrompt.tsx +++ b/src/components/verification/VerificationCreatePrompt.tsx @@ -1,15 +1,19 @@ -import {useCallback} from 'react' +import {useCallback, useState} from 'react' import {View} from 'react-native' -import {msg} from '@lingui/macro' +import {msg, Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {logger} from '#/logger' import {useModerationOpts} from '#/state/preferences/moderation-opts' import {useVerificationCreateMutation} from '#/state/queries/verification/useVerificationCreateMutation' import * as Toast from '#/view/com/util/Toast' -import {atoms as a} from '#/alf' +import {atoms as a, useBreakpoints} from '#/alf' +import {Admonition} from '#/components/Admonition' +import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {type DialogControlProps} from '#/components/Dialog' +import * as Dialog from '#/components/Dialog' import {VerifiedCheck} from '#/components/icons/VerifiedCheck' +import {Loader} from '#/components/Loader' import * as ProfileCard from '#/components/ProfileCard' import * as Prompt from '#/components/Prompt' import type * as bsky from '#/types/bsky' @@ -22,19 +26,22 @@ export function VerificationCreatePrompt({ profile: bsky.profile.AnyProfileView }) { const {_} = useLingui() + const {gtMobile} = useBreakpoints() const moderationOpts = useModerationOpts() - const {mutateAsync: create} = useVerificationCreateMutation() + const {mutateAsync: create, isPending} = useVerificationCreateMutation() + const [error, setError] = useState(``) const onConfirm = useCallback(async () => { try { await create({profile}) Toast.show(_(msg`Successfully verified`)) + control.close() } catch (e) { - Toast.show(_(msg`Failed to create a verification`), 'xmark') + setError(_(msg`Verification failed, please try again.`)) logger.error('Failed to create a verification', { safeMessage: e, }) } - }, [_, profile, create]) + }, [_, profile, create, control]) return ( <Prompt.Outer control={control}> @@ -47,24 +54,51 @@ export function VerificationCreatePrompt({ <Prompt.DescriptionText> {_(msg`This action can be undone at any time.`)} </Prompt.DescriptionText> - <View style={[a.pb_xl]}> - {moderationOpts ? ( - <ProfileCard.Header> - <ProfileCard.Avatar - profile={profile} - moderationOpts={moderationOpts} - /> - <ProfileCard.NameAndHandle - profile={profile} - moderationOpts={moderationOpts} - /> - </ProfileCard.Header> - ) : null} + + {moderationOpts ? ( + <ProfileCard.Header> + <ProfileCard.Avatar + profile={profile} + moderationOpts={moderationOpts} + /> + <ProfileCard.NameAndHandle + profile={profile} + moderationOpts={moderationOpts} + /> + </ProfileCard.Header> + ) : null} + + {error && ( + <View style={[a.pt_lg]}> + <Admonition type="error">{error}</Admonition> + </View> + )} + + <View style={[a.pt_xl]}> + {profile.displayName ? ( + <Prompt.Actions> + <Button + variant="solid" + color="primary" + size={gtMobile ? 'small' : 'large'} + label={_(msg`Verify account`)} + onPress={onConfirm}> + <ButtonText>{_(msg`Verify account`)}</ButtonText> + {isPending && <ButtonIcon icon={Loader} />} + </Button> + <Prompt.Cancel /> + </Prompt.Actions> + ) : ( + <Admonition type="warning"> + <Trans> + This user does not have a display name, and therefore cannot be + verified. + </Trans> + </Admonition> + )} </View> - <Prompt.Actions> - <Prompt.Action cta={_(msg`Verify account`)} onPress={onConfirm} /> - <Prompt.Cancel /> - </Prompt.Actions> + + <Dialog.Close /> </Prompt.Outer> ) } diff --git a/src/lib/hooks/useOpenLink.ts b/src/lib/hooks/useOpenLink.ts index a949dacc6..28c1bca3d 100644 --- a/src/lib/hooks/useOpenLink.ts +++ b/src/lib/hooks/useOpenLink.ts @@ -12,16 +12,18 @@ import { toNiceDomain, } from '#/lib/strings/url-helpers' import {isNative} from '#/platform/detection' -import {useModalControls} from '#/state/modals' import {useInAppBrowser} from '#/state/preferences/in-app-browser' import {useTheme} from '#/alf' +import {useDialogContext} from '#/components/Dialog' import {useSheetWrapper} from '#/components/Dialog/sheet-wrapper' +import {useGlobalDialogsControlContext} from '#/components/dialogs/Context' export function useOpenLink() { - const {openModal} = useModalControls() const enabled = useInAppBrowser() const t = useTheme() const sheetWrapper = useSheetWrapper() + const dialogContext = useDialogContext() + const {inAppBrowserConsentControl} = useGlobalDialogsControlContext() const openLink = useCallback( async (url: string, override?: boolean, shouldProxy?: boolean) => { @@ -42,10 +44,17 @@ export function useOpenLink() { if (isNative && !url.startsWith('mailto:')) { if (override === undefined && enabled === undefined) { - openModal({ - name: 'in-app-browser-consent', - href: url, - }) + // consent dialog is a global dialog, and while it's possible to nest dialogs, + // the actual components need to be nested. sibling dialogs on iOS are not supported. + // thus, check if we're in a dialog, and if so, close the existing dialog before opening the + // consent dialog -sfn + if (dialogContext.isWithinDialog) { + dialogContext.close(() => { + inAppBrowserConsentControl.open(url) + }) + } else { + inAppBrowserConsentControl.open(url) + } return } else if (override ?? enabled) { await sheetWrapper( @@ -62,7 +71,7 @@ export function useOpenLink() { } Linking.openURL(url) }, - [enabled, openModal, t, sheetWrapper], + [enabled, inAppBrowserConsentControl, t, sheetWrapper, dialogContext], ) return openLink diff --git a/src/lib/media/manip.ts b/src/lib/media/manip.ts index 7f052068d..f6ef8347d 100644 --- a/src/lib/media/manip.ts +++ b/src/lib/media/manip.ts @@ -178,15 +178,20 @@ async function doResize(localUri: string, opts: DoResizeOpts): Promise<Image> { height: imageRes.height, }) - for (let i = 0; i < 9; i++) { - // nearest 10th - const quality = Math.round((1 - 0.1 * i) * 10) / 10 + let minQualityPercentage = 0 + let maxQualityPercentage = 101 // exclusive + let newDataUri + + while (maxQualityPercentage - minQualityPercentage > 1) { + const qualityPercentage = Math.round( + (maxQualityPercentage + minQualityPercentage) / 2, + ) const resizeRes = await manipulateAsync( localUri, [{resize: newDimensions}], { format: SaveFormat.JPEG, - compress: quality, + compress: qualityPercentage / 100, }, ) @@ -198,8 +203,8 @@ async function doResize(localUri: string, opts: DoResizeOpts): Promise<Image> { } if (fileInfo.size < opts.maxSize) { - safeDeleteAsync(imageRes.uri) - return { + minQualityPercentage = qualityPercentage + newDataUri = { path: normalizePath(resizeRes.uri), mime: 'image/jpeg', size: fileInfo.size, @@ -207,9 +212,17 @@ async function doResize(localUri: string, opts: DoResizeOpts): Promise<Image> { height: resizeRes.height, } } else { - safeDeleteAsync(resizeRes.uri) + maxQualityPercentage = qualityPercentage } + + safeDeleteAsync(resizeRes.uri) } + + if (newDataUri) { + safeDeleteAsync(imageRes.uri) + return newDataUri + } + throw new Error( `This image is too big! We couldn't compress it down to ${opts.maxSize} bytes`, ) diff --git a/src/lib/media/manip.web.ts b/src/lib/media/manip.web.ts index 4761f2fe0..ffef7314d 100644 --- a/src/lib/media/manip.web.ts +++ b/src/lib/media/manip.web.ts @@ -72,17 +72,28 @@ interface DoResizeOpts { async function doResize(dataUri: string, opts: DoResizeOpts): Promise<RNImage> { let newDataUri - for (let i = 0; i <= 10; i++) { - newDataUri = await createResizedImage(dataUri, { + let minQualityPercentage = 0 + let maxQualityPercentage = 101 //exclusive + + while (maxQualityPercentage - minQualityPercentage > 1) { + const qualityPercentage = Math.round( + (maxQualityPercentage + minQualityPercentage) / 2, + ) + const tempDataUri = await createResizedImage(dataUri, { width: opts.width, height: opts.height, - quality: 1 - i * 0.1, + quality: qualityPercentage / 100, mode: opts.mode, }) - if (getDataUriSize(newDataUri) < opts.maxSize) { - break + + if (getDataUriSize(tempDataUri) < opts.maxSize) { + minQualityPercentage = qualityPercentage + newDataUri = tempDataUri + } else { + maxQualityPercentage = qualityPercentage } } + if (!newDataUri) { throw new Error('Failed to compress image') } diff --git a/src/locale/locales/en/messages.po b/src/locale/locales/en/messages.po index d5c02a4cd..6ad7d50f3 100644 --- a/src/locale/locales/en/messages.po +++ b/src/locale/locales/en/messages.po @@ -22,8 +22,7 @@ msgstr "" msgid "(contains embedded content)" msgstr "" -#: src/screens/Settings/AccountSettings.tsx:65 -#: src/view/com/modals/VerifyEmail.tsx:150 +#: src/screens/Settings/AccountSettings.tsx:67 msgid "(no email)" msgstr "" @@ -417,7 +416,7 @@ msgstr "" msgid "<0>You</0> and<1> </1><2>{0} </2>are included in your starter pack" msgstr "" -#: src/screens/Profile/Header/Handle.tsx:52 +#: src/screens/Profile/Header/Handle.tsx:53 msgid "⚠Invalid Handle" msgstr "" @@ -446,10 +445,10 @@ msgstr "" msgid "A new form of verification" msgstr "" -#: src/Navigation.tsx:400 +#: src/Navigation.tsx:401 #: src/screens/Settings/AboutSettings.tsx:72 -#: src/screens/Settings/Settings.tsx:223 -#: src/screens/Settings/Settings.tsx:226 +#: src/screens/Settings/Settings.tsx:224 +#: src/screens/Settings/Settings.tsx:227 msgid "About" msgstr "" @@ -468,20 +467,20 @@ msgid "Accept Request" msgstr "" #: src/screens/Settings/AccessibilitySettings.tsx:46 -#: src/screens/Settings/Settings.tsx:199 -#: src/screens/Settings/Settings.tsx:202 +#: src/screens/Settings/Settings.tsx:200 +#: src/screens/Settings/Settings.tsx:203 msgid "Accessibility" msgstr "" -#: src/Navigation.tsx:352 +#: src/Navigation.tsx:353 msgid "Accessibility Settings" msgstr "" -#: src/Navigation.tsx:368 +#: src/Navigation.tsx:369 #: src/screens/Login/LoginForm.tsx:194 -#: src/screens/Settings/AccountSettings.tsx:45 -#: src/screens/Settings/Settings.tsx:161 -#: src/screens/Settings/Settings.tsx:164 +#: src/screens/Settings/AccountSettings.tsx:47 +#: src/screens/Settings/Settings.tsx:162 +#: src/screens/Settings/Settings.tsx:165 msgid "Account" msgstr "" @@ -512,11 +511,11 @@ msgstr "" msgid "Account Muted by List" msgstr "" -#: src/screens/Settings/Settings.tsx:480 +#: src/screens/Settings/Settings.tsx:499 msgid "Account options" msgstr "" -#: src/screens/Settings/Settings.tsx:516 +#: src/screens/Settings/Settings.tsx:535 msgid "Account removed from quick access" msgstr "" @@ -584,8 +583,8 @@ msgstr "" msgid "Add alt text (optional)" msgstr "" -#: src/screens/Settings/Settings.tsx:423 -#: src/screens/Settings/Settings.tsx:426 +#: src/screens/Settings/Settings.tsx:442 +#: src/screens/Settings/Settings.tsx:445 #: src/view/shell/desktop/LeftNav.tsx:281 #: src/view/shell/desktop/LeftNav.tsx:285 msgid "Add another account" @@ -713,6 +712,10 @@ msgstr "" msgid "Advanced" msgstr "" +#: src/components/dialogs/ChangeEmailDialog.tsx:143 +msgid "alice@example.com" +msgstr "" + #: src/view/screens/Notifications.tsx:86 msgid "All" msgstr "" @@ -792,15 +795,14 @@ msgid "Alt text will be truncated. {MAX_ALT_TEXT, plural, other {Limit: {0} char msgstr "" #: src/screens/Settings/components/DisableEmail2FADialog.tsx:93 -#: src/view/com/modals/VerifyEmail.tsx:132 msgid "An email has been sent to {0}. It includes a confirmation code which you can enter below." msgstr "" -#: src/view/com/modals/ChangeEmail.tsx:114 -msgid "An email has been sent to your previous address, {0}. It includes a confirmation code which you can enter below." +#: src/components/dialogs/ChangeEmailDialog.tsx:59 +msgid "An email has been sent to your previous address, {currentEmail}. It includes a confirmation code which you can enter below." msgstr "" -#: src/components/dialogs/VerifyEmailDialog.tsx:91 +#: src/components/dialogs/VerifyEmailDialog.tsx:120 msgid "An email has been sent! Please enter the confirmation code included in the email below." msgstr "" @@ -916,7 +918,7 @@ msgstr "" msgid "Anybody can interact" msgstr "" -#: src/Navigation.tsx:408 +#: src/Navigation.tsx:409 #: src/screens/Settings/AppIconSettings/index.tsx:67 #: src/screens/Settings/AppIconSettings/SettingsListItem.tsx:18 #: src/screens/Settings/AppIconSettings/SettingsListItem.tsx:23 @@ -953,7 +955,7 @@ msgstr "" msgid "App passwords" msgstr "" -#: src/Navigation.tsx:320 +#: src/Navigation.tsx:321 #: src/screens/Settings/AppPasswords.tsx:51 msgid "App Passwords" msgstr "" @@ -989,10 +991,10 @@ msgstr "" msgid "Appeal this decision" msgstr "" -#: src/Navigation.tsx:360 +#: src/Navigation.tsx:361 #: src/screens/Settings/AppearanceSettings.tsx:85 -#: src/screens/Settings/Settings.tsx:191 -#: src/screens/Settings/Settings.tsx:194 +#: src/screens/Settings/Settings.tsx:192 +#: src/screens/Settings/Settings.tsx:195 msgid "Appearance" msgstr "" @@ -1128,7 +1130,7 @@ msgid "Before you may message another user, you must first verify your email." msgstr "" #: src/components/dialogs/BirthDateSettings.tsx:103 -#: src/screens/Settings/AccountSettings.tsx:109 +#: src/screens/Settings/AccountSettings.tsx:111 msgid "Birthday" msgstr "" @@ -1195,8 +1197,8 @@ msgstr "" msgid "Blocked accounts" msgstr "" -#: src/Navigation.tsx:161 -#: src/view/screens/ModerationBlockedAccounts.tsx:110 +#: src/Navigation.tsx:162 +#: src/view/screens/ModerationBlockedAccounts.tsx:104 msgid "Blocked Accounts" msgstr "" @@ -1205,7 +1207,7 @@ msgstr "" msgid "Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you." msgstr "" -#: src/view/screens/ModerationBlockedAccounts.tsx:121 +#: src/view/screens/ModerationBlockedAccounts.tsx:190 msgid "Blocked accounts cannot reply in your threads, mention you, or otherwise interact with you. You will not see their content and they will be prevented from seeing yours." msgstr "" @@ -1373,9 +1375,11 @@ msgstr "" msgid "Camera" msgstr "" +#: src/components/dialogs/InAppBrowserConsent.tsx:98 +#: src/components/dialogs/InAppBrowserConsent.tsx:104 #: src/components/Menu/index.tsx:306 +#: src/components/Prompt.tsx:138 #: src/components/Prompt.tsx:140 -#: src/components/Prompt.tsx:142 #: src/screens/Deactivated.tsx:158 #: src/screens/Profile/Header/EditProfileDialog.tsx:227 #: src/screens/Profile/Header/EditProfileDialog.tsx:235 @@ -1384,24 +1388,18 @@ msgstr "" #: src/screens/Settings/AppIconSettings/index.tsx:225 #: src/screens/Settings/components/ChangeHandleDialog.tsx:78 #: src/screens/Settings/components/ChangeHandleDialog.tsx:85 -#: src/screens/Settings/Settings.tsx:268 +#: src/screens/Settings/Settings.tsx:269 #: src/screens/Takendown.tsx:99 #: src/screens/Takendown.tsx:102 #: src/view/com/composer/Composer.tsx:937 #: src/view/com/composer/Composer.tsx:948 -#: src/view/com/modals/ChangeEmail.tsx:213 -#: src/view/com/modals/ChangeEmail.tsx:215 #: src/view/com/modals/ChangePassword.tsx:279 #: src/view/com/modals/ChangePassword.tsx:282 #: src/view/com/modals/CreateOrEditList.tsx:335 #: src/view/com/modals/CropImage.web.tsx:97 #: src/view/com/modals/EditProfile.tsx:269 -#: src/view/com/modals/InAppBrowserConsent.tsx:75 -#: src/view/com/modals/InAppBrowserConsent.tsx:77 #: src/view/com/modals/LinkWarning.tsx:105 #: src/view/com/modals/LinkWarning.tsx:107 -#: src/view/com/modals/VerifyEmail.tsx:255 -#: src/view/com/modals/VerifyEmail.tsx:261 #: src/view/com/util/post-ctrls/RepostButton.tsx:213 #: src/view/shell/desktop/LeftNav.tsx:209 msgid "Cancel" @@ -1459,8 +1457,7 @@ msgstr "" msgid "Captions & alt text" msgstr "" -#: src/screens/Settings/components/Email2FAToggle.tsx:60 -#: src/view/com/modals/VerifyEmail.tsx:160 +#: src/screens/Settings/components/Email2FAToggle.tsx:76 msgid "Change" msgstr "" @@ -1473,13 +1470,13 @@ msgstr "" msgid "Change app icon to \"{0}\"" msgstr "" -#: src/screens/Settings/AccountSettings.tsx:97 -#: src/screens/Settings/AccountSettings.tsx:101 +#: src/screens/Settings/AccountSettings.tsx:99 +#: src/screens/Settings/AccountSettings.tsx:103 msgid "Change email" msgstr "" -#: src/components/dialogs/VerifyEmailDialog.tsx:162 -#: src/components/dialogs/VerifyEmailDialog.tsx:187 +#: src/components/dialogs/VerifyEmailDialog.tsx:200 +#: src/components/dialogs/VerifyEmailDialog.tsx:225 msgid "Change email address" msgstr "" @@ -1492,10 +1489,6 @@ msgstr "" msgid "Change moderation service" msgstr "" -#: src/view/com/modals/VerifyEmail.tsx:155 -msgid "Change my email" -msgstr "" - #: src/view/com/modals/ChangePassword.tsx:153 msgid "Change Password" msgstr "" @@ -1508,11 +1501,11 @@ msgstr "" msgid "Change report reason" msgstr "" -#: src/view/com/modals/ChangeEmail.tsx:104 +#: src/components/dialogs/ChangeEmailDialog.tsx:53 msgid "Change Your Email" msgstr "" -#: src/components/dialogs/VerifyEmailDialog.tsx:171 +#: src/components/dialogs/VerifyEmailDialog.tsx:209 msgid "Change your email address" msgstr "" @@ -1525,7 +1518,7 @@ msgstr "" msgid "Changes hosting provider" msgstr "" -#: src/Navigation.tsx:425 +#: src/Navigation.tsx:426 #: src/view/shell/bottom-bar/BottomBar.tsx:205 #: src/view/shell/desktop/LeftNav.tsx:535 #: src/view/shell/Drawer.tsx:438 @@ -1543,7 +1536,7 @@ msgctxt "toast" msgid "Chat muted" msgstr "" -#: src/Navigation.tsx:435 +#: src/Navigation.tsx:436 #: src/screens/Messages/components/InboxPreview.tsx:24 msgid "Chat request inbox" msgstr "" @@ -1554,7 +1547,7 @@ msgid "Chat requests" msgstr "" #: src/components/dms/ConvoMenu.tsx:75 -#: src/Navigation.tsx:430 +#: src/Navigation.tsx:431 #: src/screens/Messages/ChatList.tsx:328 msgid "Chat settings" msgstr "" @@ -1626,11 +1619,11 @@ msgstr "" msgid "Choose your username" msgstr "" -#: src/screens/Settings/Settings.tsx:401 +#: src/screens/Settings/Settings.tsx:420 msgid "Clear all storage data" msgstr "" -#: src/screens/Settings/Settings.tsx:403 +#: src/screens/Settings/Settings.tsx:422 msgid "Clear all storage data (restart after this)" msgstr "" @@ -1671,11 +1664,14 @@ msgstr "" msgid "Clip 🐴 clop 🐴" msgstr "" +#: src/components/dialogs/ChangeEmailDialog.tsx:244 +#: src/components/dialogs/ChangeEmailDialog.tsx:250 #: src/components/dialogs/GifSelect.tsx:281 #: src/components/dialogs/nuxs/InitialVerificationAnnouncement.tsx:174 #: src/components/dialogs/nuxs/InitialVerificationAnnouncement.tsx:183 #: src/components/dialogs/SearchablePeopleList.tsx:295 -#: src/components/dialogs/VerifyEmailDialog.tsx:289 +#: src/components/dialogs/VerifyEmailDialog.tsx:346 +#: src/components/dialogs/VerifyEmailDialog.tsx:352 #: src/components/dms/EmojiPopup.android.tsx:58 #: src/components/dms/ReportDialog.tsx:381 #: src/components/dms/ReportDialog.tsx:390 @@ -1692,8 +1688,8 @@ msgstr "" msgid "Close" msgstr "" -#: src/components/Dialog/index.web.tsx:113 -#: src/components/Dialog/index.web.tsx:261 +#: src/components/Dialog/index.web.tsx:111 +#: src/components/Dialog/index.web.tsx:259 msgid "Close active dialog" msgstr "" @@ -1715,8 +1711,8 @@ msgstr "" msgid "Close drawer menu" msgstr "" -#: src/view/com/composer/text-input/web/EmojiPicker.web.tsx:137 -#: src/view/com/composer/text-input/web/EmojiPicker.web.tsx:173 +#: src/view/com/composer/text-input/web/EmojiPicker.web.tsx:136 +#: src/view/com/composer/text-input/web/EmojiPicker.web.tsx:172 msgid "Close emoji picker" msgstr "" @@ -1750,8 +1746,8 @@ msgstr "" msgid "Closes post composer and discards post draft" msgstr "" -#: src/view/com/composer/text-input/web/EmojiPicker.web.tsx:138 -#: src/view/com/composer/text-input/web/EmojiPicker.web.tsx:174 +#: src/view/com/composer/text-input/web/EmojiPicker.web.tsx:137 +#: src/view/com/composer/text-input/web/EmojiPicker.web.tsx:173 msgid "Closes the emoji picker" msgstr "" @@ -1786,7 +1782,7 @@ msgstr "" msgid "Comics" msgstr "" -#: src/Navigation.tsx:310 +#: src/Navigation.tsx:311 #: src/view/screens/CommunityGuidelines.tsx:34 msgid "Community Guidelines" msgstr "" @@ -1823,23 +1819,17 @@ msgstr "" msgid "Configured in <0>moderation settings</0>." msgstr "" -#: src/components/dialogs/VerifyEmailDialog.tsx:253 -#: src/components/dialogs/VerifyEmailDialog.tsx:260 -#: src/components/dialogs/VerifyEmailDialog.tsx:283 -#: src/components/Prompt.tsx:183 -#: src/components/Prompt.tsx:186 +#: src/components/dialogs/ChangeEmailDialog.tsx:203 +#: src/components/dialogs/ChangeEmailDialog.tsx:210 +#: src/components/dialogs/VerifyEmailDialog.tsx:316 +#: src/components/dialogs/VerifyEmailDialog.tsx:323 +#: src/components/Prompt.tsx:181 +#: src/components/Prompt.tsx:184 #: src/screens/Settings/components/DisableEmail2FADialog.tsx:185 #: src/screens/Settings/components/DisableEmail2FADialog.tsx:188 -#: src/view/com/modals/VerifyEmail.tsx:239 -#: src/view/com/modals/VerifyEmail.tsx:241 msgid "Confirm" msgstr "" -#: src/view/com/modals/ChangeEmail.tsx:188 -#: src/view/com/modals/ChangeEmail.tsx:190 -msgid "Confirm Change" -msgstr "" - #: src/view/com/modals/lang-settings/ConfirmLanguagesButton.tsx:34 msgid "Confirm content language settings" msgstr "" @@ -1856,18 +1846,18 @@ msgstr "" msgid "Confirm your birthdate" msgstr "" -#: src/components/dialogs/VerifyEmailDialog.tsx:214 +#: src/components/dialogs/ChangeEmailDialog.tsx:160 +#: src/components/dialogs/ChangeEmailDialog.tsx:164 +#: src/components/dialogs/VerifyEmailDialog.tsx:252 #: src/screens/Login/LoginForm.tsx:274 #: src/screens/Settings/components/DisableEmail2FADialog.tsx:144 #: src/screens/Settings/components/DisableEmail2FADialog.tsx:150 -#: src/view/com/modals/ChangeEmail.tsx:152 #: src/view/com/modals/DeleteAccount.tsx:220 #: src/view/com/modals/DeleteAccount.tsx:226 -#: src/view/com/modals/VerifyEmail.tsx:173 msgid "Confirmation code" msgstr "" -#: src/components/dialogs/VerifyEmailDialog.tsx:210 +#: src/components/dialogs/VerifyEmailDialog.tsx:248 msgid "Confirmation Code" msgstr "" @@ -1885,12 +1875,12 @@ msgid "Content & Media" msgstr "" #: src/screens/Settings/AccessibilitySettings.tsx:109 -#: src/screens/Settings/Settings.tsx:183 -#: src/screens/Settings/Settings.tsx:186 +#: src/screens/Settings/Settings.tsx:184 +#: src/screens/Settings/Settings.tsx:187 msgid "Content and media" msgstr "" -#: src/Navigation.tsx:384 +#: src/Navigation.tsx:385 msgid "Content and Media" msgstr "" @@ -2063,7 +2053,7 @@ msgstr "" msgid "Copy TXT record value" msgstr "" -#: src/Navigation.tsx:315 +#: src/Navigation.tsx:316 #: src/view/screens/CopyrightPolicy.tsx:31 msgid "Copyright Policy" msgstr "" @@ -2099,7 +2089,7 @@ msgstr "" #: src/components/StarterPack/ProfileStarterPacks.tsx:178 #: src/components/StarterPack/ProfileStarterPacks.tsx:274 -#: src/Navigation.tsx:460 +#: src/Navigation.tsx:461 msgid "Create a starter pack" msgstr "" @@ -2204,13 +2194,13 @@ msgstr "" msgid "Date of birth" msgstr "" -#: src/screens/Settings/AccountSettings.tsx:146 -#: src/screens/Settings/AccountSettings.tsx:151 +#: src/screens/Settings/AccountSettings.tsx:148 +#: src/screens/Settings/AccountSettings.tsx:153 #: src/screens/Settings/components/DeactivateAccountDialog.tsx:73 msgid "Deactivate account" msgstr "" -#: src/screens/Settings/Settings.tsx:382 +#: src/screens/Settings/Settings.tsx:394 msgid "Debug Moderation" msgstr "" @@ -2237,8 +2227,8 @@ msgstr "" msgid "Delete" msgstr "" -#: src/screens/Settings/AccountSettings.tsx:156 -#: src/screens/Settings/AccountSettings.tsx:161 +#: src/screens/Settings/AccountSettings.tsx:158 +#: src/screens/Settings/AccountSettings.tsx:163 msgid "Delete account" msgstr "" @@ -2259,7 +2249,7 @@ msgstr "" msgid "Delete chat" msgstr "" -#: src/screens/Settings/Settings.tsx:389 +#: src/screens/Settings/Settings.tsx:401 msgid "Delete chat declaration record" msgstr "" @@ -2370,8 +2360,8 @@ msgctxt "toast" msgid "Developer mode enabled" msgstr "" -#: src/screens/Settings/Settings.tsx:250 -#: src/screens/Settings/Settings.tsx:253 +#: src/screens/Settings/Settings.tsx:251 +#: src/screens/Settings/Settings.tsx:254 msgid "Developer options" msgstr "" @@ -2610,7 +2600,7 @@ msgstr "" msgid "Each code works once. You'll receive more invite codes periodically." msgstr "" -#: src/screens/Settings/AccountSettings.tsx:112 +#: src/screens/Settings/AccountSettings.tsx:114 #: src/screens/StarterPack/StarterPackScreen.tsx:583 #: src/screens/StarterPack/Wizard/index.tsx:534 #: src/screens/StarterPack/Wizard/index.tsx:541 @@ -2656,7 +2646,7 @@ msgstr "" msgid "Edit Moderation List" msgstr "" -#: src/Navigation.tsx:325 +#: src/Navigation.tsx:326 #: src/view/screens/Feeds.tsx:515 msgid "Edit My Feeds" msgstr "" @@ -2706,7 +2696,7 @@ msgstr "" msgid "Edit your profile description" msgstr "" -#: src/Navigation.tsx:465 +#: src/Navigation.tsx:466 msgid "Edit your starter pack" msgstr "" @@ -2719,9 +2709,8 @@ msgstr "" msgid "Either the creator of this list has blocked you or you have blocked the creator." msgstr "" -#: src/screens/Settings/AccountSettings.tsx:60 +#: src/screens/Settings/AccountSettings.tsx:62 #: src/screens/Signup/StepInfo/index.tsx:193 -#: src/view/com/modals/ChangeEmail.tsx:136 msgid "Email" msgstr "" @@ -2742,19 +2731,8 @@ msgstr "" msgid "Email Resent" msgstr "" -#: src/view/com/modals/ChangeEmail.tsx:54 -#: src/view/com/modals/ChangeEmail.tsx:83 -msgctxt "toast" -msgid "Email updated" -msgstr "" - -#: src/view/com/modals/ChangeEmail.tsx:106 -msgid "Email Updated" -msgstr "" - -#: src/view/com/modals/VerifyEmail.tsx:85 -msgctxt "toast" -msgid "Email verified" +#: src/components/dialogs/ChangeEmailDialog.tsx:63 +msgid "Email Updated!" msgstr "" #: src/components/intents/VerifyEmailIntentDialog.tsx:79 @@ -2780,8 +2758,8 @@ msgstr "" msgid "Embedded video player" msgstr "" -#: src/screens/Settings/components/Email2FAToggle.tsx:56 #: src/screens/Settings/components/Email2FAToggle.tsx:60 +#: src/screens/Settings/components/Email2FAToggle.tsx:76 msgid "Enable" msgstr "" @@ -2793,7 +2771,7 @@ msgstr "" msgid "Enable adult content" msgstr "" -#: src/screens/Settings/components/Email2FAToggle.tsx:53 +#: src/screens/Settings/components/Email2FAToggle.tsx:57 msgid "Enable Email 2FA" msgstr "" @@ -2855,14 +2833,10 @@ msgstr "" msgid "Enter a word or tag" msgstr "" -#: src/components/dialogs/VerifyEmailDialog.tsx:89 +#: src/components/dialogs/VerifyEmailDialog.tsx:118 msgid "Enter Code" msgstr "" -#: src/view/com/modals/VerifyEmail.tsx:113 -msgid "Enter Confirmation Code" -msgstr "" - #: src/view/com/util/post-embeds/VideoEmbedInner/web-controls/VideoControls.tsx:405 msgid "Enter fullscreen" msgstr "" @@ -2892,11 +2866,7 @@ msgstr "" msgid "Enter your email address" msgstr "" -#: src/view/com/modals/ChangeEmail.tsx:42 -msgid "Enter your new email above" -msgstr "" - -#: src/view/com/modals/ChangeEmail.tsx:112 +#: src/components/dialogs/ChangeEmailDialog.tsx:138 msgid "Enter your new email address below." msgstr "" @@ -3035,15 +3005,15 @@ msgstr "" msgid "Explicit sexual images." msgstr "" -#: src/Navigation.tsx:649 +#: src/Navigation.tsx:650 #: src/screens/Search/Shell.tsx:307 #: src/view/shell/desktop/LeftNav.tsx:617 #: src/view/shell/Drawer.tsx:386 msgid "Explore" msgstr "" -#: src/screens/Settings/AccountSettings.tsx:137 -#: src/screens/Settings/AccountSettings.tsx:141 +#: src/screens/Settings/AccountSettings.tsx:139 +#: src/screens/Settings/AccountSettings.tsx:143 msgid "Export my data" msgstr "" @@ -3066,7 +3036,7 @@ msgstr "" msgid "External media may allow websites to collect information about you and your device. No information is sent or requested until you press the \"play\" button." msgstr "" -#: src/Navigation.tsx:344 +#: src/Navigation.tsx:345 #: src/screens/Settings/ExternalMediaPreferences.tsx:31 msgid "External Media Preferences" msgstr "" @@ -3085,10 +3055,6 @@ msgstr "" msgid "Failed to change handle. Please try again." msgstr "" -#: src/components/verification/VerificationCreatePrompt.tsx:32 -msgid "Failed to create a verification" -msgstr "" - #: src/screens/Settings/components/AddAppPasswordDialog.tsx:173 msgid "Failed to create app password. Please try again." msgstr "" @@ -3218,7 +3184,7 @@ msgstr "" msgid "Failed to verify handle. Please try again." msgstr "" -#: src/Navigation.tsx:260 +#: src/Navigation.tsx:261 msgid "Feed" msgstr "" @@ -3247,7 +3213,7 @@ msgctxt "toast" msgid "Feedback sent!" msgstr "" -#: src/Navigation.tsx:445 +#: src/Navigation.tsx:446 #: src/screens/Search/SearchResults.tsx:68 #: src/screens/StarterPack/StarterPackScreen.tsx:185 #: src/view/screens/Feeds.tsx:508 @@ -3412,7 +3378,7 @@ msgstr "" msgid "Followed by <0>{0}</0>, <1>{1}</1>, and {2, plural, one {# other} other {# others}}" msgstr "" -#: src/Navigation.tsx:214 +#: src/Navigation.tsx:215 msgid "Followers of @{0} that you know" msgstr "" @@ -3451,7 +3417,7 @@ msgstr "" msgid "Following feed preferences" msgstr "" -#: src/Navigation.tsx:331 +#: src/Navigation.tsx:332 #: src/screens/Settings/FollowingFeedPreferences.tsx:53 msgid "Following Feed Preferences" msgstr "" @@ -3536,9 +3502,9 @@ msgstr "" msgid "Get help" msgstr "" -#: src/view/com/modals/VerifyEmail.tsx:197 -#: src/view/com/modals/VerifyEmail.tsx:199 -msgid "Get Started" +#: src/components/dialogs/VerifyEmailDialog.tsx:263 +#: src/components/dialogs/VerifyEmailDialog.tsx:269 +msgid "Get started" msgstr "" #: src/components/ProgressGuide/List.tsx:35 @@ -3633,8 +3599,8 @@ msgstr "" msgid "Half way there!" msgstr "" -#: src/screens/Settings/AccountSettings.tsx:126 -#: src/screens/Settings/AccountSettings.tsx:131 +#: src/screens/Settings/AccountSettings.tsx:128 +#: src/screens/Settings/AccountSettings.tsx:133 msgid "Handle" msgstr "" @@ -3660,7 +3626,7 @@ msgstr "" msgid "Harassment, trolling, or intolerance" msgstr "" -#: src/Navigation.tsx:415 +#: src/Navigation.tsx:416 msgid "Hashtag" msgstr "" @@ -3672,8 +3638,8 @@ msgstr "" msgid "Having trouble?" msgstr "" -#: src/screens/Settings/Settings.tsx:215 -#: src/screens/Settings/Settings.tsx:219 +#: src/screens/Settings/Settings.tsx:216 +#: src/screens/Settings/Settings.tsx:220 #: src/view/shell/desktop/RightNav.tsx:120 #: src/view/shell/desktop/RightNav.tsx:121 #: src/view/shell/Drawer.tsx:353 @@ -3812,8 +3778,8 @@ msgstr "" msgid "Hold up! We’re gradually giving access to video, and you’re still waiting in line. Check back soon!" msgstr "" -#: src/Navigation.tsx:644 -#: src/Navigation.tsx:664 +#: src/Navigation.tsx:645 +#: src/Navigation.tsx:665 #: src/view/shell/bottom-bar/BottomBar.tsx:162 #: src/view/shell/desktop/LeftNav.tsx:599 #: src/view/shell/Drawer.tsx:412 @@ -3840,25 +3806,20 @@ msgstr "" msgid "Hot replies first" msgstr "" -#: src/view/com/modals/InAppBrowserConsent.tsx:41 +#: src/components/dialogs/InAppBrowserConsent.tsx:62 +#: src/components/dialogs/InAppBrowserConsent.tsx:66 msgid "How should we open this link?" msgstr "" +#: src/components/dialogs/ChangeEmailDialog.tsx:189 +#: src/components/dialogs/ChangeEmailDialog.tsx:196 +#: src/components/dialogs/VerifyEmailDialog.tsx:302 +#: src/components/dialogs/VerifyEmailDialog.tsx:309 #: src/screens/Settings/components/DisableEmail2FADialog.tsx:133 #: src/screens/Settings/components/DisableEmail2FADialog.tsx:136 -#: src/view/com/modals/VerifyEmail.tsx:222 msgid "I have a code" msgstr "" -#: src/components/dialogs/VerifyEmailDialog.tsx:239 -#: src/components/dialogs/VerifyEmailDialog.tsx:246 -msgid "I Have a Code" -msgstr "" - -#: src/view/com/modals/VerifyEmail.tsx:224 -msgid "I have a confirmation code" -msgstr "" - #: src/screens/Settings/components/ChangeHandleDialog.tsx:280 #: src/screens/Settings/components/ChangeHandleDialog.tsx:286 msgid "I have my own domain" @@ -4095,13 +4056,13 @@ msgstr "" msgid "Language selection" msgstr "" -#: src/Navigation.tsx:187 +#: src/Navigation.tsx:188 msgid "Language Settings" msgstr "" #: src/screens/Settings/LanguageSettings.tsx:71 -#: src/screens/Settings/Settings.tsx:207 -#: src/screens/Settings/Settings.tsx:210 +#: src/screens/Settings/Settings.tsx:208 +#: src/screens/Settings/Settings.tsx:211 msgid "Languages" msgstr "" @@ -4246,8 +4207,8 @@ msgstr "" msgid "Like this labeler" msgstr "" -#: src/Navigation.tsx:265 -#: src/Navigation.tsx:270 +#: src/Navigation.tsx:266 +#: src/Navigation.tsx:271 msgid "Liked by" msgstr "" @@ -4282,7 +4243,7 @@ msgstr "" msgid "Linear" msgstr "" -#: src/Navigation.tsx:220 +#: src/Navigation.tsx:221 msgid "List" msgstr "" @@ -4340,7 +4301,7 @@ msgctxt "toast" msgid "List unmuted" msgstr "" -#: src/Navigation.tsx:141 +#: src/Navigation.tsx:142 #: src/view/screens/Lists.tsx:62 #: src/view/screens/Profile.tsx:221 #: src/view/screens/Profile.tsx:229 @@ -4376,7 +4337,7 @@ msgstr "" msgid "Loading..." msgstr "" -#: src/Navigation.tsx:290 +#: src/Navigation.tsx:291 msgid "Log" msgstr "" @@ -4450,6 +4411,11 @@ msgstr "" msgid "Marked all as read" msgstr "" +#: src/components/dialogs/VerifyEmailDialog.tsx:273 +#: src/components/dialogs/VerifyEmailDialog.tsx:281 +msgid "Maybe later" +msgstr "" + #: src/view/screens/Profile.tsx:224 msgid "Media" msgstr "" @@ -4508,7 +4474,7 @@ msgstr "" msgid "Message options" msgstr "" -#: src/Navigation.tsx:659 +#: src/Navigation.tsx:660 msgid "Messages" msgstr "" @@ -4527,10 +4493,10 @@ msgstr "" msgid "Misleading Post" msgstr "" -#: src/Navigation.tsx:146 +#: src/Navigation.tsx:147 #: src/screens/Moderation/index.tsx:93 -#: src/screens/Settings/Settings.tsx:175 -#: src/screens/Settings/Settings.tsx:178 +#: src/screens/Settings/Settings.tsx:176 +#: src/screens/Settings/Settings.tsx:179 msgid "Moderation" msgstr "" @@ -4566,7 +4532,7 @@ msgstr "" msgid "Moderation lists" msgstr "" -#: src/Navigation.tsx:151 +#: src/Navigation.tsx:152 #: src/view/screens/ModerationModlists.tsx:62 msgid "Moderation Lists" msgstr "" @@ -4575,7 +4541,7 @@ msgstr "" msgid "moderation settings" msgstr "" -#: src/Navigation.tsx:280 +#: src/Navigation.tsx:281 msgid "Moderation states" msgstr "" @@ -4698,12 +4664,12 @@ msgstr "" msgid "Muted accounts" msgstr "" -#: src/Navigation.tsx:156 -#: src/view/screens/ModerationMutedAccounts.tsx:123 +#: src/Navigation.tsx:157 +#: src/view/screens/ModerationMutedAccounts.tsx:118 msgid "Muted Accounts" msgstr "" -#: src/view/screens/ModerationMutedAccounts.tsx:135 +#: src/view/screens/ModerationMutedAccounts.tsx:204 msgid "Muted accounts have their posts removed from your feed and from your notifications. Mutes are completely private." msgstr "" @@ -4771,7 +4737,7 @@ msgstr "" msgid "Navigates to your profile" msgstr "" -#: src/components/dialogs/VerifyEmailDialog.tsx:196 +#: src/components/dialogs/VerifyEmailDialog.tsx:234 msgid "Need to change it?" msgstr "" @@ -4804,6 +4770,10 @@ msgstr "" msgid "New chat" msgstr "" +#: src/components/dialogs/ChangeEmailDialog.tsx:142 +msgid "New email address" +msgstr "" + #: src/components/dialogs/nuxs/InitialVerificationAnnouncement.tsx:63 msgid "New Feature" msgstr "" @@ -5027,16 +4997,11 @@ msgstr "" msgid "Not followed by anyone you're following" msgstr "" -#: src/Navigation.tsx:136 +#: src/Navigation.tsx:137 #: src/view/screens/Profile.tsx:122 msgid "Not Found" msgstr "" -#: src/view/com/modals/VerifyEmail.tsx:254 -#: src/view/com/modals/VerifyEmail.tsx:260 -msgid "Not right now" -msgstr "" - #: src/view/com/profile/ProfileMenu.tsx:442 #: src/view/com/util/forms/PostDropdownBtnMenuItems.tsx:791 #: src/view/com/util/post-ctrls/PostCtrls.tsx:361 @@ -5055,7 +5020,7 @@ msgstr "" msgid "Notification filters" msgstr "" -#: src/Navigation.tsx:440 +#: src/Navigation.tsx:441 #: src/view/screens/Notifications.tsx:134 msgid "Notification settings" msgstr "" @@ -5072,7 +5037,7 @@ msgstr "" msgid "Notification Sounds" msgstr "" -#: src/Navigation.tsx:654 +#: src/Navigation.tsx:655 #: src/view/screens/Notifications.tsx:128 #: src/view/shell/bottom-bar/BottomBar.tsx:236 #: src/view/shell/desktop/LeftNav.tsx:636 @@ -5135,7 +5100,7 @@ msgstr "" msgid "on<0><1/><2><3/></2></0>" msgstr "" -#: src/screens/Settings/Settings.tsx:354 +#: src/screens/Settings/Settings.tsx:355 msgid "Onboarding reset" msgstr "" @@ -5232,7 +5197,7 @@ msgstr "" msgid "Open message options" msgstr "" -#: src/screens/Settings/Settings.tsx:380 +#: src/screens/Settings/Settings.tsx:392 msgid "Open moderation debug page" msgstr "" @@ -5252,12 +5217,12 @@ msgstr "" msgid "Open starter pack menu" msgstr "" -#: src/screens/Settings/Settings.tsx:373 -#: src/screens/Settings/Settings.tsx:387 +#: src/screens/Settings/Settings.tsx:385 +#: src/screens/Settings/Settings.tsx:399 msgid "Open storybook page" msgstr "" -#: src/screens/Settings/Settings.tsx:366 +#: src/screens/Settings/Settings.tsx:378 msgid "Open system log" msgstr "" @@ -5289,7 +5254,7 @@ msgstr "" msgid "Opens captions and alt text dialog" msgstr "" -#: src/screens/Settings/AccountSettings.tsx:127 +#: src/screens/Settings/AccountSettings.tsx:129 msgid "Opens change handle dialog" msgstr "" @@ -5319,7 +5284,7 @@ msgstr "" msgid "Opens GIF select dialog" msgstr "" -#: src/screens/Settings/Settings.tsx:216 +#: src/screens/Settings/Settings.tsx:217 msgid "Opens helpdesk in browser" msgstr "" @@ -5413,8 +5378,8 @@ msgid "Page Not Found" msgstr "" #: src/screens/Login/LoginForm.tsx:228 -#: src/screens/Settings/AccountSettings.tsx:117 -#: src/screens/Settings/AccountSettings.tsx:121 +#: src/screens/Settings/AccountSettings.tsx:119 +#: src/screens/Settings/AccountSettings.tsx:123 #: src/screens/Signup/StepInfo/index.tsx:228 #: src/view/com/modals/DeleteAccount.tsx:239 #: src/view/com/modals/DeleteAccount.tsx:246 @@ -5453,11 +5418,11 @@ msgstr "" msgid "People" msgstr "" -#: src/Navigation.tsx:207 +#: src/Navigation.tsx:208 msgid "People followed by @{0}" msgstr "" -#: src/Navigation.tsx:200 +#: src/Navigation.tsx:201 msgid "People following @{0}" msgstr "" @@ -5577,10 +5542,6 @@ msgstr "" msgid "Please complete the verification captcha." msgstr "" -#: src/view/com/modals/ChangeEmail.tsx:65 -msgid "Please confirm your email before changing it. This is a temporary requirement while email-updating tools are added, and it will soon be removed." -msgstr "" - #: src/screens/Signup/StepInfo/index.tsx:109 msgid "Please double-check that you have entered your email address correctly." msgstr "" @@ -5643,7 +5604,7 @@ msgstr "" msgid "Please sign in as @{0}" msgstr "" -#: src/view/com/modals/VerifyEmail.tsx:109 +#: src/components/dialogs/VerifyEmailDialog.tsx:108 msgid "Please Verify Your Email" msgstr "" @@ -5676,10 +5637,10 @@ msgstr "" msgid "Post by {0}" msgstr "" -#: src/Navigation.tsx:233 -#: src/Navigation.tsx:240 -#: src/Navigation.tsx:247 -#: src/Navigation.tsx:254 +#: src/Navigation.tsx:234 +#: src/Navigation.tsx:241 +#: src/Navigation.tsx:248 +#: src/Navigation.tsx:255 msgid "Post by @{0}" msgstr "" @@ -5714,7 +5675,7 @@ msgstr "" msgid "Post interaction settings" msgstr "" -#: src/Navigation.tsx:167 +#: src/Navigation.tsx:168 #: src/screens/ModerationInteractionSettings/index.tsx:34 msgid "Post Interaction Settings" msgstr "" @@ -5802,17 +5763,17 @@ msgstr "" msgid "Privacy" msgstr "" -#: src/screens/Settings/Settings.tsx:169 -#: src/screens/Settings/Settings.tsx:172 +#: src/screens/Settings/Settings.tsx:170 +#: src/screens/Settings/Settings.tsx:173 msgid "Privacy and security" msgstr "" -#: src/Navigation.tsx:376 +#: src/Navigation.tsx:377 #: src/screens/Settings/PrivacyAndSecuritySettings.tsx:36 msgid "Privacy and Security" msgstr "" -#: src/Navigation.tsx:300 +#: src/Navigation.tsx:301 #: src/screens/Settings/AboutSettings.tsx:89 #: src/screens/Settings/AboutSettings.tsx:92 #: src/view/screens/PrivacyPolicy.tsx:31 @@ -6017,7 +5978,7 @@ msgstr "" #: src/components/FeedCard.tsx:343 #: src/components/StarterPack/Wizard/WizardListCard.tsx:102 #: src/components/StarterPack/Wizard/WizardListCard.tsx:109 -#: src/screens/Settings/Settings.tsx:518 +#: src/screens/Settings/Settings.tsx:537 #: src/view/com/feeds/FeedSourceCard.tsx:322 #: src/view/com/modals/UserAddRemoveLists.tsx:235 #: src/view/com/posts/PostFeedErrorMessage.tsx:213 @@ -6032,8 +5993,8 @@ msgstr "" msgid "Remove {historyItem}" msgstr "" -#: src/screens/Settings/Settings.tsx:497 -#: src/screens/Settings/Settings.tsx:500 +#: src/screens/Settings/Settings.tsx:516 +#: src/screens/Settings/Settings.tsx:519 msgid "Remove account" msgstr "" @@ -6074,7 +6035,7 @@ msgstr "" msgid "Remove from my feeds" msgstr "" -#: src/screens/Settings/Settings.tsx:510 +#: src/screens/Settings/Settings.tsx:529 msgid "Remove from quick access?" msgstr "" @@ -6377,9 +6338,9 @@ msgstr "" msgid "Reposts of this post" msgstr "" -#: src/view/com/modals/ChangeEmail.tsx:176 -#: src/view/com/modals/ChangeEmail.tsx:178 -msgid "Request Change" +#: src/components/dialogs/ChangeEmailDialog.tsx:175 +#: src/components/dialogs/ChangeEmailDialog.tsx:182 +msgid "Request change" msgstr "" #: src/view/com/modals/ChangePassword.tsx:253 @@ -6392,7 +6353,7 @@ msgstr "" msgid "Require alt text before posting" msgstr "" -#: src/screens/Settings/components/Email2FAToggle.tsx:54 +#: src/screens/Settings/components/Email2FAToggle.tsx:58 msgid "Require an email code to sign in to your account." msgstr "" @@ -6404,13 +6365,15 @@ msgstr "" msgid "Required in your region" msgstr "" +#: src/components/dialogs/ChangeEmailDialog.tsx:217 +#: src/components/dialogs/ChangeEmailDialog.tsx:227 +#: src/components/dialogs/VerifyEmailDialog.tsx:330 +#: src/components/dialogs/VerifyEmailDialog.tsx:340 #: src/screens/Settings/components/DisableEmail2FADialog.tsx:173 #: src/screens/Settings/components/DisableEmail2FADialog.tsx:176 msgid "Resend email" msgstr "" -#: src/components/dialogs/VerifyEmailDialog.tsx:267 -#: src/components/dialogs/VerifyEmailDialog.tsx:277 #: src/components/intents/VerifyEmailIntentDialog.tsx:130 msgid "Resend Email" msgstr "" @@ -6427,8 +6390,8 @@ msgstr "" msgid "Reset Code" msgstr "" -#: src/screens/Settings/Settings.tsx:394 -#: src/screens/Settings/Settings.tsx:396 +#: src/screens/Settings/Settings.tsx:406 +#: src/screens/Settings/Settings.tsx:408 msgid "Reset onboarding state" msgstr "" @@ -6597,7 +6560,7 @@ msgstr "" msgid "Search" msgstr "" -#: src/Navigation.tsx:226 +#: src/Navigation.tsx:227 #: src/screens/Profile/ProfileSearch.tsx:37 msgid "Search @{0}'s posts" msgstr "" @@ -6670,7 +6633,7 @@ msgstr "" msgid "Searches for profiles" msgstr "" -#: src/view/com/modals/ChangeEmail.tsx:105 +#: src/components/dialogs/ChangeEmailDialog.tsx:57 msgid "Security Step Required" msgstr "" @@ -6804,19 +6767,14 @@ msgstr "" msgid "Send a neat website!" msgstr "" -#: src/components/dialogs/VerifyEmailDialog.tsx:232 -msgid "Send Confirmation" +#: src/components/dialogs/VerifyEmailDialog.tsx:295 +msgid "Send confirmation" msgstr "" -#: src/components/dialogs/VerifyEmailDialog.tsx:225 +#: src/components/dialogs/VerifyEmailDialog.tsx:288 msgid "Send confirmation email" msgstr "" -#: src/view/com/modals/VerifyEmail.tsx:210 -#: src/view/com/modals/VerifyEmail.tsx:212 -msgid "Send Confirmation Email" -msgstr "" - #: src/view/com/modals/DeleteAccount.tsx:145 msgid "Send email" msgstr "" @@ -6892,8 +6850,8 @@ msgstr "" msgid "Sets email for password reset" msgstr "" -#: src/Navigation.tsx:182 -#: src/screens/Settings/Settings.tsx:88 +#: src/Navigation.tsx:183 +#: src/screens/Settings/Settings.tsx:89 #: src/view/shell/desktop/LeftNav.tsx:709 #: src/view/shell/Drawer.tsx:555 msgid "Settings" @@ -6981,7 +6939,7 @@ msgstr "" msgid "Share your favorite feed!" msgstr "" -#: src/Navigation.tsx:285 +#: src/Navigation.tsx:286 msgid "Shared Preferences Tester" msgstr "" @@ -7097,7 +7055,7 @@ msgstr "" msgid "Shows information about when this post was created" msgstr "" -#: src/screens/Settings/Settings.tsx:112 +#: src/screens/Settings/Settings.tsx:113 msgid "Shows other accounts you can switch to" msgstr "" @@ -7149,9 +7107,9 @@ msgstr "" msgid "Sign in to Bluesky or create a new account" msgstr "" -#: src/screens/Settings/Settings.tsx:233 -#: src/screens/Settings/Settings.tsx:235 -#: src/screens/Settings/Settings.tsx:267 +#: src/screens/Settings/Settings.tsx:234 +#: src/screens/Settings/Settings.tsx:236 +#: src/screens/Settings/Settings.tsx:268 #: src/screens/SignupQueued.tsx:93 #: src/screens/SignupQueued.tsx:96 #: src/screens/Takendown.tsx:85 @@ -7165,7 +7123,7 @@ msgstr "" msgid "Sign Out" msgstr "" -#: src/screens/Settings/Settings.tsx:264 +#: src/screens/Settings/Settings.tsx:265 #: src/view/shell/desktop/LeftNav.tsx:205 msgid "Sign out?" msgstr "" @@ -7197,6 +7155,10 @@ msgstr "" msgid "Smaller" msgstr "" +#: src/components/dialogs/VerifyEmailDialog.tsx:274 +msgid "Snoozes the reminder" +msgstr "" + #: src/screens/Onboarding/index.tsx:37 #: src/screens/Onboarding/state.ts:100 msgid "Software Dev" @@ -7313,8 +7275,8 @@ msgstr "" msgid "Start chat with {displayName}" msgstr "" -#: src/Navigation.tsx:450 -#: src/Navigation.tsx:455 +#: src/Navigation.tsx:451 +#: src/Navigation.tsx:456 #: src/screens/StarterPack/Wizard/index.tsx:186 msgid "Starter Pack" msgstr "" @@ -7354,12 +7316,12 @@ msgstr "" msgid "Step {0} of {1}" msgstr "" -#: src/screens/Settings/Settings.tsx:359 +#: src/screens/Settings/Settings.tsx:360 msgid "Storage cleared, you need to restart the app now." msgstr "" -#: src/Navigation.tsx:275 -#: src/screens/Settings/Settings.tsx:375 +#: src/Navigation.tsx:276 +#: src/screens/Settings/Settings.tsx:387 msgid "Storybook" msgstr "" @@ -7404,11 +7366,11 @@ msgstr "" msgid "Subscribe to this list" msgstr "" -#: src/components/dialogs/VerifyEmailDialog.tsx:95 +#: src/components/dialogs/VerifyEmailDialog.tsx:124 msgid "Success!" msgstr "" -#: src/components/verification/VerificationCreatePrompt.tsx:30 +#: src/components/verification/VerificationCreatePrompt.tsx:36 msgid "Successfully verified" msgstr "" @@ -7435,15 +7397,15 @@ msgctxt "Name of app icon variant" msgid "Sunset" msgstr "" -#: src/Navigation.tsx:295 +#: src/Navigation.tsx:296 #: src/view/screens/Support.tsx:31 #: src/view/screens/Support.tsx:34 msgid "Support" msgstr "" -#: src/screens/Settings/Settings.tsx:110 -#: src/screens/Settings/Settings.tsx:124 -#: src/screens/Settings/Settings.tsx:462 +#: src/screens/Settings/Settings.tsx:111 +#: src/screens/Settings/Settings.tsx:125 +#: src/screens/Settings/Settings.tsx:481 #: src/view/shell/desktop/LeftNav.tsx:243 msgid "Switch account" msgstr "" @@ -7470,7 +7432,7 @@ msgstr "" #: src/screens/Settings/AboutSettings.tsx:104 #: src/screens/Settings/AboutSettings.tsx:107 -#: src/screens/Settings/Settings.tsx:368 +#: src/screens/Settings/Settings.tsx:380 msgid "System log" msgstr "" @@ -7522,7 +7484,7 @@ msgstr "" msgid "Terms" msgstr "" -#: src/Navigation.tsx:305 +#: src/Navigation.tsx:306 #: src/screens/Settings/AboutSettings.tsx:81 #: src/screens/Settings/AboutSettings.tsx:84 #: src/view/screens/TermsOfService.tsx:31 @@ -7555,7 +7517,7 @@ msgstr "" msgid "Text input field" msgstr "" -#: src/components/dialogs/VerifyEmailDialog.tsx:96 +#: src/components/dialogs/VerifyEmailDialog.tsx:125 msgid "Thank you! Your email has been successfully verified." msgstr "" @@ -7627,6 +7589,10 @@ msgstr "" msgid "The Discover feed now knows what you like" msgstr "" +#: src/components/dialogs/ChangeEmailDialog.tsx:74 +msgid "The email address you entered is the same as your current email address." +msgstr "" + #: src/screens/StarterPack/StarterPackLandingScreen.tsx:324 msgid "The experience is better in the app. Download Bluesky now and we'll pick back up where you left off." msgstr "" @@ -7815,7 +7781,7 @@ msgstr "" msgid "This account is blocked by one or more of your moderation lists. To unblock, please visit the lists directly and remove this user." msgstr "" -#: src/components/verification/VerificationCreatePrompt.tsx:48 +#: src/components/verification/VerificationCreatePrompt.tsx:55 msgid "This action can be undone at any time." msgstr "" @@ -7890,10 +7856,6 @@ msgstr "" msgid "This information is not shared with other users." msgstr "" -#: src/view/com/modals/VerifyEmail.tsx:127 -msgid "This is important in case you ever need to change your email or reset your password." -msgstr "" - #: src/components/moderation/ModerationDetailsDialog.tsx:168 msgid "This label was applied by the author." msgstr "" @@ -7967,6 +7929,10 @@ msgstr "" msgid "This should create a domain record at:" msgstr "" +#: src/components/verification/VerificationCreatePrompt.tsx:93 +msgid "This user does not have a display name, and therefore cannot be verified." +msgstr "" + #: src/view/com/profile/ProfileFollowers.tsx:95 msgid "This user doesn't have any followers." msgstr "" @@ -8004,7 +7970,7 @@ msgstr "" msgid "This will delete \"{0}\" from your muted words. You can always add it back later." msgstr "" -#: src/screens/Settings/Settings.tsx:512 +#: src/screens/Settings/Settings.tsx:531 msgid "This will remove @{0} from the quick access list." msgstr "" @@ -8035,7 +8001,7 @@ msgstr "" msgid "Threaded mode" msgstr "" -#: src/Navigation.tsx:338 +#: src/Navigation.tsx:339 msgid "Threads Preferences" msgstr "" @@ -8081,7 +8047,7 @@ msgstr "" msgid "Top" msgstr "" -#: src/Navigation.tsx:420 +#: src/Navigation.tsx:421 msgid "Topic" msgstr "" @@ -8302,6 +8268,11 @@ msgstr "" msgid "Unpinned from your feeds" msgstr "" +#: src/screens/Settings/Settings.tsx:413 +#: src/screens/Settings/Settings.tsx:415 +msgid "Unsnooze email reminder" +msgstr "" + #: src/screens/Profile/Header/ProfileHeaderLabeler.tsx:246 msgid "Unsubscribe" msgstr "" @@ -8410,8 +8381,8 @@ msgstr "" msgid "Use default provider" msgstr "" -#: src/view/com/modals/InAppBrowserConsent.tsx:53 -#: src/view/com/modals/InAppBrowserConsent.tsx:55 +#: src/components/dialogs/InAppBrowserConsent.tsx:77 +#: src/components/dialogs/InAppBrowserConsent.tsx:83 msgid "Use in-app browser" msgstr "" @@ -8420,8 +8391,8 @@ msgstr "" msgid "Use in-app browser to open links" msgstr "" -#: src/view/com/modals/InAppBrowserConsent.tsx:63 -#: src/view/com/modals/InAppBrowserConsent.tsx:65 +#: src/components/dialogs/InAppBrowserConsent.tsx:87 +#: src/components/dialogs/InAppBrowserConsent.tsx:93 msgid "Use my default browser" msgstr "" @@ -8514,11 +8485,15 @@ msgstr "" msgid "Value:" msgstr "" +#: src/components/verification/VerificationCreatePrompt.tsx:39 +msgid "Verification failed, please try again." +msgstr "" + #: src/screens/Moderation/index.tsx:288 msgid "Verification settings" msgstr "" -#: src/Navigation.tsx:175 +#: src/Navigation.tsx:176 #: src/screens/Moderation/VerificationSettings.tsx:32 msgid "Verification Settings" msgstr "" @@ -8535,7 +8510,8 @@ msgstr "" msgid "Verified email required" msgstr "" -#: src/components/verification/VerificationCreatePrompt.tsx:65 +#: src/components/verification/VerificationCreatePrompt.tsx:84 +#: src/components/verification/VerificationCreatePrompt.tsx:86 #: src/view/com/profile/ProfileMenu.tsx:308 #: src/view/com/profile/ProfileMenu.tsx:311 msgid "Verify account" @@ -8546,14 +8522,15 @@ msgstr "" msgid "Verify DNS Record" msgstr "" -#: src/components/dialogs/VerifyEmailDialog.tsx:134 -#: src/components/intents/VerifyEmailIntentDialog.tsx:67 -msgid "Verify email dialog" +#: src/components/dialogs/ChangeEmailDialog.tsx:234 +#: src/components/dialogs/ChangeEmailDialog.tsx:240 +msgid "Verify email" msgstr "" -#: src/view/com/modals/ChangeEmail.tsx:200 -#: src/view/com/modals/ChangeEmail.tsx:202 -msgid "Verify New Email" +#: src/components/dialogs/ChangeEmailDialog.tsx:122 +#: src/components/dialogs/VerifyEmailDialog.tsx:163 +#: src/components/intents/VerifyEmailIntentDialog.tsx:67 +msgid "Verify email dialog" msgstr "" #: src/view/com/composer/videos/SelectVideoBtn.tsx:131 @@ -8565,17 +8542,16 @@ msgstr "" msgid "Verify Text File" msgstr "" -#: src/components/verification/VerificationCreatePrompt.tsx:44 +#: src/components/verification/VerificationCreatePrompt.tsx:51 msgid "Verify this account?" msgstr "" -#: src/screens/Settings/AccountSettings.tsx:75 -#: src/screens/Settings/AccountSettings.tsx:91 +#: src/screens/Settings/AccountSettings.tsx:77 +#: src/screens/Settings/AccountSettings.tsx:93 msgid "Verify your email" msgstr "" -#: src/components/dialogs/VerifyEmailDialog.tsx:85 -#: src/view/com/modals/VerifyEmail.tsx:111 +#: src/components/dialogs/VerifyEmailDialog.tsx:114 msgid "Verify Your Email" msgstr "" @@ -8593,7 +8569,7 @@ msgstr "" msgid "Video failed to process" msgstr "" -#: src/Navigation.tsx:471 +#: src/Navigation.tsx:472 msgid "Video Feed" msgstr "" @@ -9170,11 +9146,11 @@ msgstr "" msgid "You have no lists." msgstr "" -#: src/view/screens/ModerationBlockedAccounts.tsx:138 +#: src/view/screens/ModerationBlockedAccounts.tsx:164 msgid "You have not blocked any accounts yet. To block an account, go to their profile and select \"Block account\" from the menu on their account." msgstr "" -#: src/view/screens/ModerationMutedAccounts.tsx:151 +#: src/view/screens/ModerationMutedAccounts.tsx:179 msgid "You have not muted any accounts yet. To mute an account, go to their profile and select \"Mute account\" from the menu on their account." msgstr "" @@ -9239,10 +9215,18 @@ msgstr "" msgid "You must select at least one labeler for a report" msgstr "" +#: src/screens/Settings/components/Email2FAToggle.tsx:67 +msgid "You need to verify your email address before you can enable email 2FA." +msgstr "" + #: src/screens/Deactivated.tsx:128 msgid "You previously deactivated @{0}." msgstr "" +#: src/screens/Settings/Settings.tsx:371 +msgid "You probably want to restart the app now." +msgstr "" + #: src/components/dms/MessageItem.tsx:135 msgid "You reacted {0}" msgstr "" @@ -9251,7 +9235,7 @@ msgstr "" msgid "You reacted {0} to {1}" msgstr "" -#: src/screens/Settings/Settings.tsx:265 +#: src/screens/Settings/Settings.tsx:266 #: src/view/shell/desktop/LeftNav.tsx:206 msgid "You will be signed out of all your accounts." msgstr "" @@ -9296,7 +9280,7 @@ msgstr "" msgid "You'll follow these people right away" msgstr "" -#: src/components/dialogs/VerifyEmailDialog.tsx:178 +#: src/components/dialogs/VerifyEmailDialog.tsx:216 msgid "You'll receive an email at <0>{0}</0> to verify it's you." msgstr "" @@ -9382,14 +9366,18 @@ msgstr "" msgid "Your chats have been disabled" msgstr "" -#: src/view/com/modals/InAppBrowserConsent.tsx:44 -msgid "Your choice will be saved, but can be changed later in settings." +#: src/components/dialogs/InAppBrowserConsent.tsx:69 +msgid "Your choice will be remembered for future links. You can change it at any time in settings." msgstr "" #: src/screens/Settings/components/ChangeHandleDialog.tsx:513 msgid "Your current handle <0>{0}</0> will automatically remain reserved for you. You can switch back to it at any time from this account." msgstr "" +#: src/components/dialogs/ChangeEmailDialog.tsx:65 +msgid "Your email address has been updated but it is not yet verified. As a next step, please verify your new email." +msgstr "" + #: src/screens/Login/ForgotPasswordForm.tsx:51 #: src/screens/Signup/state.ts:270 #: src/screens/Signup/StepInfo/index.tsx:98 @@ -9397,11 +9385,7 @@ msgstr "" msgid "Your email appears to be invalid." msgstr "" -#: src/view/com/modals/ChangeEmail.tsx:120 -msgid "Your email has been updated but not verified. As a next step, please verify your new email." -msgstr "" - -#: src/view/com/modals/VerifyEmail.tsx:122 +#: src/components/dialogs/VerifyEmailDialog.tsx:110 msgid "Your email has not yet been verified. This is an important security step which we recommend." msgstr "" @@ -9425,7 +9409,7 @@ msgstr "" msgid "Your full username will be <0>@{0}</0>" msgstr "" -#: src/Navigation.tsx:392 +#: src/Navigation.tsx:393 #: src/screens/Search/modules/ExploreInterestsCard.tsx:67 #: src/screens/Settings/ContentAndMediaSettings.tsx:92 #: src/screens/Settings/ContentAndMediaSettings.tsx:95 diff --git a/src/screens/Messages/components/MessageInput.tsx b/src/screens/Messages/components/MessageInput.tsx index 69cba07f7..6cde1d4fe 100644 --- a/src/screens/Messages/components/MessageInput.tsx +++ b/src/screens/Messages/components/MessageInput.tsx @@ -24,7 +24,7 @@ import { useMessageDraft, useSaveMessageDraft, } from '#/state/messages/message-drafts' -import {type EmojiPickerPosition} from '#/view/com/composer/text-input/web/EmojiPicker.web' +import {type EmojiPickerPosition} from '#/view/com/composer/text-input/web/EmojiPicker' import * as Toast from '#/view/com/util/Toast' import {android, atoms as a, useTheme} from '#/alf' import {useSharedInputStyles} from '#/components/forms/TextField' diff --git a/src/screens/Messages/components/MessageInput.web.tsx b/src/screens/Messages/components/MessageInput.web.tsx index bac163685..0dce99ad6 100644 --- a/src/screens/Messages/components/MessageInput.web.tsx +++ b/src/screens/Messages/components/MessageInput.web.tsx @@ -15,9 +15,9 @@ import { } from '#/state/messages/message-drafts' import {textInputWebEmitter} from '#/view/com/composer/text-input/textInputWebEmitter' import { - Emoji, - EmojiPickerPosition, -} from '#/view/com/composer/text-input/web/EmojiPicker.web' + type Emoji, + type EmojiPickerPosition, +} from '#/view/com/composer/text-input/web/EmojiPicker' import * as Toast from '#/view/com/util/Toast' import {atoms as a, useTheme} from '#/alf' import {Button} from '#/components/Button' diff --git a/src/screens/Messages/components/MessagesList.tsx b/src/screens/Messages/components/MessagesList.tsx index b400bc578..ce33ca3aa 100644 --- a/src/screens/Messages/components/MessagesList.tsx +++ b/src/screens/Messages/components/MessagesList.tsx @@ -1,5 +1,5 @@ import {useCallback, useEffect, useRef, useState} from 'react' -import {LayoutChangeEvent, View} from 'react-native' +import {type LayoutChangeEvent, View} from 'react-native' import {useKeyboardHandler} from 'react-native-keyboard-controller' import Animated, { runOnJS, @@ -8,10 +8,10 @@ import Animated, { useAnimatedStyle, useSharedValue, } from 'react-native-reanimated' -import {ReanimatedScrollEvent} from 'react-native-reanimated/lib/typescript/hook/commonTypes' +import {type ReanimatedScrollEvent} from 'react-native-reanimated/lib/typescript/hook/commonTypes' import { - $Typed, - AppBskyEmbedRecord, + type $Typed, + type AppBskyEmbedRecord, AppBskyRichtextFacet, RichText, } from '@atproto/api' @@ -26,19 +26,23 @@ import {logger} from '#/logger' import {isNative} from '#/platform/detection' import {isWeb} from '#/platform/detection' import { - ActiveConvoStates, + type ActiveConvoStates, isConvoActive, useConvoActive, } from '#/state/messages/convo' -import {ConvoItem, ConvoState, ConvoStatus} from '#/state/messages/convo/types' +import { + type ConvoItem, + type ConvoState, + ConvoStatus, +} from '#/state/messages/convo/types' import {useGetPost} from '#/state/queries/post' import {useAgent} from '#/state/session' import {useShellLayout} from '#/state/shell/shell-layout' import { EmojiPicker, - EmojiPickerState, -} from '#/view/com/composer/text-input/web/EmojiPicker.web' -import {List, ListMethods} from '#/view/com/util/List' + type EmojiPickerState, +} from '#/view/com/composer/text-input/web/EmojiPicker' +import {List, type ListMethods} from '#/view/com/util/List' import {ChatDisabled} from '#/screens/Messages/components/ChatDisabled' import {MessageInput} from '#/screens/Messages/components/MessageInput' import {MessageListError} from '#/screens/Messages/components/MessageListError' diff --git a/src/screens/Search/modules/ExploreTrendingTopics.tsx b/src/screens/Search/modules/ExploreTrendingTopics.tsx index 167f6d193..1d3bc2d86 100644 --- a/src/screens/Search/modules/ExploreTrendingTopics.tsx +++ b/src/screens/Search/modules/ExploreTrendingTopics.tsx @@ -265,12 +265,12 @@ export function TrendingTopicRowSkeleton({}: {withPosts: boolean}) { style={[a.rounded_full]} /> </View> - <LoadingPlaceholder width={90} height={18} /> + <LoadingPlaceholder width={90} height={17} /> </View> <View style={[a.flex_row, a.gap_sm, a.align_center, {paddingLeft: 20}]}> - <LoadingPlaceholder width={70} height={18} /> - <LoadingPlaceholder width={40} height={18} /> - <LoadingPlaceholder width={60} height={18} /> + <LoadingPlaceholder width={70} height={16} /> + <LoadingPlaceholder width={40} height={16} /> + <LoadingPlaceholder width={60} height={16} /> </View> </View> <View style={[a.flex_shrink_0]}> diff --git a/src/state/gallery.ts b/src/state/gallery.ts index f4c8b712e..f03ed2afe 100644 --- a/src/state/gallery.ts +++ b/src/state/gallery.ts @@ -5,8 +5,8 @@ import { moveAsync, } from 'expo-file-system' import { - Action, - ActionCrop, + type Action, + type ActionCrop, manipulateAsync, SaveFormat, } from 'expo-image-manipulator' @@ -210,17 +210,21 @@ export async function compressImage(img: ComposerImage): Promise<ImageMeta> { const source = img.transformed || img.source const [w, h] = containImageRes(source.width, source.height, POST_IMG_MAX) - const cacheDir = isNative && getImageCacheDirectory() - for (let i = 10; i > 0; i--) { - // Float precision - const factor = i / 10 + let minQualityPercentage = 0 + let maxQualityPercentage = 101 // exclusive + let newDataUri + + while (maxQualityPercentage - minQualityPercentage > 1) { + const qualityPercentage = Math.round( + (maxQualityPercentage + minQualityPercentage) / 2, + ) const res = await manipulateAsync( source.path, [{resize: {width: w, height: h}}], { - compress: factor, + compress: qualityPercentage / 100, format: SaveFormat.JPEG, base64: true, }, @@ -229,17 +233,20 @@ export async function compressImage(img: ComposerImage): Promise<ImageMeta> { const base64 = res.base64 if (base64 !== undefined && getDataUriSize(base64) <= POST_IMG_MAX.size) { - return { + minQualityPercentage = qualityPercentage + newDataUri = { path: await moveIfNecessary(res.uri), width: res.width, height: res.height, mime: 'image/jpeg', } + } else { + maxQualityPercentage = qualityPercentage } + } - if (cacheDir) { - await deleteAsync(res.uri) - } + if (newDataUri) { + return newDataUri } throw new Error(`Unable to compress image`) diff --git a/src/state/modals/index.tsx b/src/state/modals/index.tsx index 45c4fb467..f79f6213f 100644 --- a/src/state/modals/index.tsx +++ b/src/state/modals/index.tsx @@ -66,11 +66,6 @@ export interface LinkWarningModal { share?: boolean } -export interface InAppBrowserConsentModal { - name: 'in-app-browser-consent' - href: string -} - export type Modal = // Account | DeleteAccountModal @@ -96,7 +91,6 @@ export type Modal = // Generic | LinkWarningModal - | InAppBrowserConsentModal const ModalContext = React.createContext<{ isModalActive: boolean diff --git a/src/state/shell/composer/index.tsx b/src/state/shell/composer/index.tsx index 33634c047..b425873fc 100644 --- a/src/state/shell/composer/index.tsx +++ b/src/state/shell/composer/index.tsx @@ -1,8 +1,8 @@ import React from 'react' import { - AppBskyActorDefs, - AppBskyFeedDefs, - ModerationDecision, + type AppBskyActorDefs, + type AppBskyFeedDefs, + type ModerationDecision, } from '@atproto/api' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' @@ -12,7 +12,7 @@ import {useNonReactiveCallback} from '#/lib/hooks/useNonReactiveCallback' import {postUriToRelativePath, toBskyAppUrl} from '#/lib/strings/url-helpers' import {purgeTemporaryImageFiles} from '#/state/gallery' import {precacheResolveLinkQuery} from '#/state/queries/resolve-link' -import type {EmojiPickerPosition} from '#/view/com/composer/text-input/web/EmojiPicker.web' +import {type EmojiPickerPosition} from '#/view/com/composer/text-input/web/EmojiPicker' import * as Toast from '#/view/com/util/Toast' export interface ComposerOptsPostRef { diff --git a/src/view/com/composer/text-input/TextInput.web.tsx b/src/view/com/composer/text-input/TextInput.web.tsx index 8ec4fefa8..06ff9836c 100644 --- a/src/view/com/composer/text-input/TextInput.web.tsx +++ b/src/view/com/composer/text-input/TextInput.web.tsx @@ -12,14 +12,14 @@ import {Placeholder} from '@tiptap/extension-placeholder' import {Text as TiptapText} from '@tiptap/extension-text' import {generateJSON} from '@tiptap/html' import {Fragment, Node, Slice} from '@tiptap/pm/model' -import {EditorContent, JSONContent, useEditor} from '@tiptap/react' +import {EditorContent, type JSONContent, useEditor} from '@tiptap/react' import {useColorSchemeStyle} from '#/lib/hooks/useColorSchemeStyle' import {usePalette} from '#/lib/hooks/usePalette' import {blobToDataUri, isUriImage} from '#/lib/media/util' import {useActorAutocompleteFn} from '#/state/queries/actor-autocomplete' import { - LinkFacetMatch, + type LinkFacetMatch, suggestLinkCardUri, } from '#/view/com/composer/text-input/text-input-util' import {textInputWebEmitter} from '#/view/com/composer/text-input/textInputWebEmitter' @@ -28,7 +28,7 @@ import {normalizeTextStyles} from '#/alf/typography' import {Portal} from '#/components/Portal' import {Text} from '../../util/text/Text' import {createSuggestion} from './web/Autocomplete' -import {Emoji} from './web/EmojiPicker.web' +import {type Emoji} from './web/EmojiPicker' import {LinkDecorator} from './web/LinkDecorator' import {TagDecorator} from './web/TagDecorator' diff --git a/src/view/com/composer/text-input/web/EmojiPicker.tsx b/src/view/com/composer/text-input/web/EmojiPicker.tsx new file mode 100644 index 000000000..5001753a5 --- /dev/null +++ b/src/view/com/composer/text-input/web/EmojiPicker.tsx @@ -0,0 +1,37 @@ +export type Emoji = { + aliases?: string[] + emoticons: string[] + id: string + keywords: string[] + name: string + native: string + shortcodes?: string + unified: string +} + +export interface EmojiPickerPosition { + top: number + left: number + right: number + bottom: number + nextFocusRef: React.MutableRefObject<HTMLElement> | null +} + +export interface EmojiPickerState { + isOpen: boolean + pos: EmojiPickerPosition +} + +interface IProps { + state: EmojiPickerState + close: () => void + /** + * If `true`, overrides position and ensures picker is pinned to the top of + * the target element. + */ + pinToTop?: boolean +} + +export function EmojiPicker(_opts: IProps) { + return null +} diff --git a/src/view/com/composer/text-input/web/EmojiPicker.web.tsx b/src/view/com/composer/text-input/web/EmojiPicker.web.tsx index b3659f22d..c0cae620f 100644 --- a/src/view/com/composer/text-input/web/EmojiPicker.web.tsx +++ b/src/view/com/composer/text-input/web/EmojiPicker.web.tsx @@ -3,8 +3,7 @@ import {Pressable, useWindowDimensions, View} from 'react-native' import Picker from '@emoji-mart/react' import {msg} from '@lingui/macro' import {useLingui} from '@lingui/react' -import {DismissableLayer} from '@radix-ui/react-dismissable-layer' -import {FocusScope} from '@radix-ui/react-focus-scope' +import {DismissableLayer, FocusScope} from 'radix-ui/internal' import {textInputWebEmitter} from '#/view/com/composer/text-input/textInputWebEmitter' import {atoms as a, flatten} from '#/alf' @@ -121,7 +120,7 @@ export function EmojiPicker({state, close, pinToTop}: IProps) { return ( <Portal> - <FocusScope + <FocusScope.FocusScope loop trapped onUnmountAutoFocus={e => { @@ -154,7 +153,7 @@ export function EmojiPicker({state, close, pinToTop}: IProps) { }, ])}> <View style={[{position: 'absolute'}, position]}> - <DismissableLayer + <DismissableLayer.DismissableLayer onFocusOutside={evt => evt.preventDefault()} onDismiss={close}> <Picker @@ -164,7 +163,7 @@ export function EmojiPicker({state, close, pinToTop}: IProps) { onEmojiSelect={onInsert} autoFocus={true} /> - </DismissableLayer> + </DismissableLayer.DismissableLayer> </View> </View> @@ -175,7 +174,7 @@ export function EmojiPicker({state, close, pinToTop}: IProps) { onPress={close} style={[a.fixed, a.inset_0]} /> - </FocusScope> + </FocusScope.FocusScope> </Portal> ) } diff --git a/src/view/com/modals/InAppBrowserConsent.tsx b/src/view/com/modals/InAppBrowserConsent.tsx deleted file mode 100644 index 105edfbc6..000000000 --- a/src/view/com/modals/InAppBrowserConsent.tsx +++ /dev/null @@ -1,99 +0,0 @@ -import React from 'react' -import {StyleSheet, View} from 'react-native' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' - -import {useOpenLink} from '#/lib/hooks/useOpenLink' -import {usePalette} from '#/lib/hooks/usePalette' -import {s} from '#/lib/styles' -import {useModalControls} from '#/state/modals' -import {useSetInAppBrowser} from '#/state/preferences/in-app-browser' -import {ScrollView} from '#/view/com/modals/util' -import {Button} from '#/view/com/util/forms/Button' -import {Text} from '#/view/com/util/text/Text' - -export const snapPoints = [350] - -export function Component({href}: {href: string}) { - const pal = usePalette('default') - const {closeModal} = useModalControls() - const {_} = useLingui() - const setInAppBrowser = useSetInAppBrowser() - const openLink = useOpenLink() - - const onUseIAB = React.useCallback(() => { - setInAppBrowser(true) - closeModal() - openLink(href, true) - }, [closeModal, setInAppBrowser, href, openLink]) - - const onUseLinking = React.useCallback(() => { - setInAppBrowser(false) - closeModal() - openLink(href, false) - }, [closeModal, setInAppBrowser, href, openLink]) - - return ( - <ScrollView - testID="inAppBrowserConsentModal" - style={[s.flex1, pal.view, {paddingHorizontal: 20, paddingTop: 10}]}> - <Text style={[pal.text, styles.title]}> - <Trans>How should we open this link?</Trans> - </Text> - <Text style={pal.text}> - <Trans> - Your choice will be saved, but can be changed later in settings. - </Trans> - </Text> - <View style={[styles.btnContainer]}> - <Button - testID="confirmBtn" - type="inverted" - onPress={onUseIAB} - accessibilityLabel={_(msg`Use in-app browser`)} - accessibilityHint="" - label={_(msg`Use in-app browser`)} - labelContainerStyle={{justifyContent: 'center', padding: 8}} - labelStyle={[s.f18]} - /> - <Button - testID="confirmBtn" - type="inverted" - onPress={onUseLinking} - accessibilityLabel={_(msg`Use my default browser`)} - accessibilityHint="" - label={_(msg`Use my default browser`)} - labelContainerStyle={{justifyContent: 'center', padding: 8}} - labelStyle={[s.f18]} - /> - <Button - testID="cancelBtn" - type="default" - onPress={() => { - closeModal() - }} - accessibilityLabel={_(msg`Cancel`)} - accessibilityHint="" - label={_(msg`Cancel`)} - labelContainerStyle={{justifyContent: 'center', padding: 8}} - labelStyle={[s.f18]} - /> - </View> - </ScrollView> - ) -} - -const styles = StyleSheet.create({ - title: { - textAlign: 'center', - fontWeight: '600', - fontSize: 24, - marginBottom: 12, - }, - btnContainer: { - marginTop: 20, - flexDirection: 'column', - justifyContent: 'center', - rowGap: 10, - }, -}) diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx index d0b50c857..8fd927f16 100644 --- a/src/view/com/modals/Modal.tsx +++ b/src/view/com/modals/Modal.tsx @@ -11,7 +11,6 @@ import * as ChangePasswordModal from './ChangePassword' import * as CreateOrEditListModal from './CreateOrEditList' import * as DeleteAccountModal from './DeleteAccount' import * as EditProfileModal from './EditProfile' -import * as InAppBrowserConsentModal from './InAppBrowserConsent' import * as InviteCodesModal from './InviteCodes' import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguagesSettings' import * as PostLanguagesSettingsModal from './lang-settings/PostLanguagesSettings' @@ -76,9 +75,6 @@ export function ModalsContainer() { } else if (activeModal?.name === 'link-warning') { snapPoints = LinkWarningModal.snapPoints element = <LinkWarningModal.Component {...activeModal} /> - } else if (activeModal?.name === 'in-app-browser-consent') { - snapPoints = InAppBrowserConsentModal.snapPoints - element = <InAppBrowserConsentModal.Component {...activeModal} /> } else { return null } diff --git a/src/view/com/util/PostMeta.tsx b/src/view/com/util/PostMeta.tsx index d5af32236..fd8e3a38b 100644 --- a/src/view/com/util/PostMeta.tsx +++ b/src/view/com/util/PostMeta.tsx @@ -107,11 +107,11 @@ let PostMeta = (opts: PostMetaOpts): React.ReactNode => { a.pl_2xs, a.self_center, { - marginTop: platform({web: -1, ios: -1, android: -2}), + marginTop: platform({web: 0, ios: 0, android: -1}), }, ]}> <VerificationCheck - width={14} + width={platform({android: 13, default: 12})} verifier={verification.role === 'verifier'} /> </View> diff --git a/src/view/com/util/forms/NativeDropdown.web.tsx b/src/view/com/util/forms/NativeDropdown.web.tsx index b3ec319e3..9b4a84e05 100644 --- a/src/view/com/util/forms/NativeDropdown.web.tsx +++ b/src/view/com/util/forms/NativeDropdown.web.tsx @@ -1,9 +1,15 @@ import React from 'react' -import {Pressable, StyleSheet, Text, View, ViewStyle} from 'react-native' -import {IconProp} from '@fortawesome/fontawesome-svg-core' +import { + Pressable, + StyleSheet, + Text, + type View, + type ViewStyle, +} from 'react-native' +import {type IconProp} from '@fortawesome/fontawesome-svg-core' import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' -import * as DropdownMenu from '@radix-ui/react-dropdown-menu' -import {MenuItemCommonProps} from 'zeego/lib/typescript/menu' +import {DropdownMenu} from 'radix-ui' +import {type MenuItemCommonProps} from 'zeego/lib/typescript/menu' import {HITSLOP_10} from '#/lib/constants' import {usePalette} from '#/lib/hooks/usePalette' diff --git a/src/view/screens/ModerationBlockedAccounts.tsx b/src/view/screens/ModerationBlockedAccounts.tsx index cefa29f6c..bb94f8083 100644 --- a/src/view/screens/ModerationBlockedAccounts.tsx +++ b/src/view/screens/ModerationBlockedAccounts.tsx @@ -1,19 +1,10 @@ -import React from 'react' -import { - ActivityIndicator, - FlatList, - RefreshControl, - StyleSheet, - View, -} from 'react-native' +import {useCallback, useMemo, useState} from 'react' +import {type StyleProp, View, type ViewStyle} from 'react-native' import {type AppBskyActorDefs as ActorDefs} from '@atproto/api' -import {msg, Trans} from '@lingui/macro' -import {useLingui} from '@lingui/react' +import {Trans} from '@lingui/macro' import {useFocusEffect} from '@react-navigation/native' import {type NativeStackScreenProps} from '@react-navigation/native-stack' -import {usePalette} from '#/lib/hooks/usePalette' -import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {type CommonNavigatorParams} from '#/lib/routes/types' import {cleanError} from '#/lib/strings/errors' import {logger} from '#/logger' @@ -21,11 +12,12 @@ import {useModerationOpts} from '#/state/preferences/moderation-opts' import {useMyBlockedAccountsQuery} from '#/state/queries/my-blocked-accounts' import {useSetMinimalShellMode} from '#/state/shell' import {ErrorScreen} from '#/view/com/util/error/ErrorScreen' -import {Text} from '#/view/com/util/text/Text' -import {ViewHeader} from '#/view/com/util/ViewHeader' +import {List} from '#/view/com/util/List' import {atoms as a, useTheme} from '#/alf' import * as Layout from '#/components/Layout' +import {ListFooter} from '#/components/Lists' import * as ProfileCard from '#/components/ProfileCard' +import {Text} from '#/components/Typography' type Props = NativeStackScreenProps< CommonNavigatorParams, @@ -33,13 +25,10 @@ type Props = NativeStackScreenProps< > export function ModerationBlockedAccounts({}: Props) { const t = useTheme() - const pal = usePalette('default') - const {_} = useLingui() const setMinimalShellMode = useSetMinimalShellMode() - const {isTabletOrDesktop} = useWebMediaQueries() const moderationOpts = useModerationOpts() - const [isPTRing, setIsPTRing] = React.useState(false) + const [isPTRing, setIsPTRing] = useState(false) const { data, isFetching, @@ -51,7 +40,7 @@ export function ModerationBlockedAccounts({}: Props) { isFetchingNextPage, } = useMyBlockedAccountsQuery() const isEmpty = !isFetching && !data?.pages[0]?.blocks.length - const profiles = React.useMemo(() => { + const profiles = useMemo(() => { if (data?.pages) { return data.pages.flatMap(page => page.blocks) } @@ -59,12 +48,12 @@ export function ModerationBlockedAccounts({}: Props) { }, [data]) useFocusEffect( - React.useCallback(() => { + useCallback(() => { setMinimalShellMode(false) }, [setMinimalShellMode]), ) - const onRefresh = React.useCallback(async () => { + const onRefresh = useCallback(async () => { setIsPTRing(true) try { await refetch() @@ -74,7 +63,7 @@ export function ModerationBlockedAccounts({}: Props) { setIsPTRing(false) }, [refetch, setIsPTRing]) - const onEndReached = React.useCallback(async () => { + const onEndReached = useCallback(async () => { if (isFetching || !hasNextPage || isError) return try { @@ -104,28 +93,22 @@ export function ModerationBlockedAccounts({}: Props) { </View> ) } + return ( <Layout.Screen testID="blockedAccountsScreen"> - <Layout.Center style={[a.flex_1, {paddingBottom: 100}]}> - <ViewHeader title={_(msg`Blocked Accounts`)} showOnDesktop /> - <Text - type="sm" - style={[ - styles.description, - pal.text, - isTabletOrDesktop && styles.descriptionDesktop, - { - marginTop: 20, - }, - ]}> - <Trans> - Blocked accounts cannot reply in your threads, mention you, or - otherwise interact with you. You will not see their content and they - will be prevented from seeing yours. - </Trans> - </Text> + <Layout.Center> + <Layout.Header.Outer> + <Layout.Header.BackButton /> + <Layout.Header.Content> + <Layout.Header.TitleText> + <Trans>Blocked Accounts</Trans> + </Layout.Header.TitleText> + </Layout.Header.Content> + <Layout.Header.Slot /> + </Layout.Header.Outer> {isEmpty ? ( - <View style={[pal.border]}> + <View> + <Info style={[a.border_b]} /> {isError ? ( <ErrorScreen title="Oops!" @@ -133,42 +116,29 @@ export function ModerationBlockedAccounts({}: Props) { onPressTryAgain={refetch} /> ) : ( - <View style={[styles.empty, pal.viewLight]}> - <Text type="lg" style={[pal.text, styles.emptyText]}> - <Trans> - You have not blocked any accounts yet. To block an account, - go to their profile and select "Block account" from the menu - on their account. - </Trans> - </Text> - </View> + <Empty /> )} </View> ) : ( - <FlatList - style={[!isTabletOrDesktop && styles.flex1]} + <List data={profiles} keyExtractor={(item: ActorDefs.ProfileView) => item.did} - refreshControl={ - <RefreshControl - refreshing={isPTRing} - onRefresh={onRefresh} - tintColor={pal.colors.text} - titleColor={pal.colors.text} - /> - } + refreshing={isPTRing} + onRefresh={onRefresh} onEndReached={onEndReached} renderItem={renderItem} initialNumToRender={15} // FIXME(dan) - ListFooterComponent={() => ( - <View style={styles.footer}> - {(isFetching || isFetchingNextPage) && <ActivityIndicator />} - </View> - )} - // @ts-ignore our .web version only -prf - desktopFixedHeight + ListHeaderComponent={Info} + ListFooterComponent={ + <ListFooter + isFetchingNextPage={isFetchingNextPage} + hasNextPage={hasNextPage} + error={cleanError(error)} + onRetry={fetchNextPage} + /> + } /> )} </Layout.Center> @@ -176,37 +146,53 @@ export function ModerationBlockedAccounts({}: Props) { ) } -const styles = StyleSheet.create({ - title: { - textAlign: 'center', - marginTop: 12, - marginBottom: 12, - }, - description: { - textAlign: 'center', - paddingHorizontal: 30, - marginBottom: 14, - }, - descriptionDesktop: { - marginTop: 14, - }, - - flex1: { - flex: 1, - }, - empty: { - paddingHorizontal: 20, - paddingVertical: 20, - borderRadius: 16, - marginHorizontal: 24, - marginTop: 10, - }, - emptyText: { - textAlign: 'center', - }, +function Empty() { + const t = useTheme() + return ( + <View style={[a.pt_2xl, a.px_xl, a.align_center]}> + <View + style={[ + a.py_md, + a.px_lg, + a.rounded_sm, + t.atoms.bg_contrast_25, + a.border, + t.atoms.border_contrast_low, + {maxWidth: 400}, + ]}> + <Text style={[a.text_sm, a.text_center, t.atoms.text_contrast_high]}> + <Trans> + You have not blocked any accounts yet. To block an account, go to + their profile and select "Block account" from the menu on their + account. + </Trans> + </Text> + </View> + </View> + ) +} - footer: { - height: 200, - paddingTop: 20, - }, -}) +function Info({style}: {style?: StyleProp<ViewStyle>}) { + const t = useTheme() + return ( + <View + style={[ + a.w_full, + t.atoms.bg_contrast_25, + a.py_md, + a.px_xl, + a.border_t, + {marginTop: a.border.borderWidth * -1}, + t.atoms.border_contrast_low, + style, + ]}> + <Text style={[a.text_center, a.text_sm, t.atoms.text_contrast_high]}> + <Trans> + Blocked accounts cannot reply in your threads, mention you, or + otherwise interact with you. You will not see their content and they + will be prevented from seeing yours. + </Trans> + </Text> + </View> + ) +} diff --git a/src/view/screens/ModerationMutedAccounts.tsx b/src/view/screens/ModerationMutedAccounts.tsx index f49337b7c..11d787ca1 100644 --- a/src/view/screens/ModerationMutedAccounts.tsx +++ b/src/view/screens/ModerationMutedAccounts.tsx @@ -1,19 +1,11 @@ -import React from 'react' -import { - ActivityIndicator, - FlatList, - RefreshControl, - StyleSheet, - View, -} from 'react-native' +import {useCallback, useMemo, useState} from 'react' +import {type StyleProp, View, type ViewStyle} from 'react-native' import {type AppBskyActorDefs as ActorDefs} from '@atproto/api' -import {msg, Trans} from '@lingui/macro' +import {Trans} from '@lingui/macro' import {useLingui} from '@lingui/react' import {useFocusEffect} from '@react-navigation/native' import {type NativeStackScreenProps} from '@react-navigation/native-stack' -import {usePalette} from '#/lib/hooks/usePalette' -import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' import {type CommonNavigatorParams} from '#/lib/routes/types' import {cleanError} from '#/lib/strings/errors' import {logger} from '#/logger' @@ -21,11 +13,12 @@ import {useModerationOpts} from '#/state/preferences/moderation-opts' import {useMyMutedAccountsQuery} from '#/state/queries/my-muted-accounts' import {useSetMinimalShellMode} from '#/state/shell' import {ErrorScreen} from '#/view/com/util/error/ErrorScreen' -import {Text} from '#/view/com/util/text/Text' -import {ViewHeader} from '#/view/com/util/ViewHeader' +import {List} from '#/view/com/util/List' import {atoms as a, useTheme} from '#/alf' import * as Layout from '#/components/Layout' +import {ListFooter} from '#/components/Lists' import * as ProfileCard from '#/components/ProfileCard' +import {Text} from '#/components/Typography' type Props = NativeStackScreenProps< CommonNavigatorParams, @@ -33,13 +26,11 @@ type Props = NativeStackScreenProps< > export function ModerationMutedAccounts({}: Props) { const t = useTheme() - const pal = usePalette('default') + const moderationOpts = useModerationOpts() const {_} = useLingui() const setMinimalShellMode = useSetMinimalShellMode() - const {isTabletOrDesktop} = useWebMediaQueries() - const moderationOpts = useModerationOpts() - const [isPTRing, setIsPTRing] = React.useState(false) + const [isPTRing, setIsPTRing] = useState(false) const { data, isFetching, @@ -51,7 +42,7 @@ export function ModerationMutedAccounts({}: Props) { isFetchingNextPage, } = useMyMutedAccountsQuery() const isEmpty = !isFetching && !data?.pages[0]?.mutes.length - const profiles = React.useMemo(() => { + const profiles = useMemo(() => { if (data?.pages) { return data.pages.flatMap(page => page.mutes) } @@ -59,12 +50,12 @@ export function ModerationMutedAccounts({}: Props) { }, [data]) useFocusEffect( - React.useCallback(() => { + useCallback(() => { setMinimalShellMode(false) }, [setMinimalShellMode]), ) - const onRefresh = React.useCallback(async () => { + const onRefresh = useCallback(async () => { setIsPTRing(true) try { await refetch() @@ -74,7 +65,7 @@ export function ModerationMutedAccounts({}: Props) { setIsPTRing(false) }, [refetch, setIsPTRing]) - const onEndReached = React.useCallback(async () => { + const onEndReached = useCallback(async () => { if (isFetching || !hasNextPage || isError) return try { @@ -120,25 +111,19 @@ export function ModerationMutedAccounts({}: Props) { } return ( <Layout.Screen testID="mutedAccountsScreen"> - <ViewHeader title={_(msg`Muted Accounts`)} showOnDesktop /> - <Layout.Center style={[a.flex_1, {paddingBottom: 100}]}> - <Text - type="sm" - style={[ - styles.description, - pal.text, - isTabletOrDesktop && styles.descriptionDesktop, - { - marginTop: 20, - }, - ]}> - <Trans> - Muted accounts have their posts removed from your feed and from your - notifications. Mutes are completely private. - </Trans> - </Text> + <Layout.Header.Outer> + <Layout.Header.BackButton /> + <Layout.Header.Content> + <Layout.Header.TitleText> + <Trans>Muted Accounts</Trans> + </Layout.Header.TitleText> + </Layout.Header.Content> + <Layout.Header.Slot /> + </Layout.Header.Outer> + <Layout.Center> {isEmpty ? ( - <View style={[pal.border]}> + <View> + <Info style={[a.border_b]} /> {isError ? ( <ErrorScreen title="Oops!" @@ -146,42 +131,29 @@ export function ModerationMutedAccounts({}: Props) { onPressTryAgain={refetch} /> ) : ( - <View style={[styles.empty, pal.viewLight]}> - <Text type="lg" style={[pal.text, styles.emptyText]}> - <Trans> - You have not muted any accounts yet. To mute an account, go - to their profile and select "Mute account" from the menu on - their account. - </Trans> - </Text> - </View> + <Empty /> )} </View> ) : ( - <FlatList - style={[!isTabletOrDesktop && styles.flex1]} + <List data={profiles} keyExtractor={item => item.did} - refreshControl={ - <RefreshControl - refreshing={isPTRing} - onRefresh={onRefresh} - tintColor={pal.colors.text} - titleColor={pal.colors.text} - /> - } + refreshing={isPTRing} + onRefresh={onRefresh} onEndReached={onEndReached} renderItem={renderItem} initialNumToRender={15} // FIXME(dan) - ListFooterComponent={() => ( - <View style={styles.footer}> - {(isFetching || isFetchingNextPage) && <ActivityIndicator />} - </View> - )} - // @ts-ignore our .web version only -prf - desktopFixedHeight + ListHeaderComponent={Info} + ListFooterComponent={ + <ListFooter + isFetchingNextPage={isFetchingNextPage} + hasNextPage={hasNextPage} + error={cleanError(error)} + onRetry={fetchNextPage} + /> + } /> )} </Layout.Center> @@ -189,37 +161,51 @@ export function ModerationMutedAccounts({}: Props) { ) } -const styles = StyleSheet.create({ - title: { - textAlign: 'center', - marginTop: 12, - marginBottom: 12, - }, - description: { - textAlign: 'center', - paddingHorizontal: 30, - marginBottom: 14, - }, - descriptionDesktop: { - marginTop: 14, - }, - - flex1: { - flex: 1, - }, - empty: { - paddingHorizontal: 20, - paddingVertical: 20, - borderRadius: 16, - marginHorizontal: 24, - marginTop: 10, - }, - emptyText: { - textAlign: 'center', - }, +function Empty() { + const t = useTheme() + return ( + <View style={[a.pt_2xl, a.px_xl, a.align_center]}> + <View + style={[ + a.py_md, + a.px_lg, + a.rounded_sm, + t.atoms.bg_contrast_25, + a.border, + t.atoms.border_contrast_low, + {maxWidth: 400}, + ]}> + <Text style={[a.text_sm, a.text_center, t.atoms.text_contrast_high]}> + <Trans> + You have not muted any accounts yet. To mute an account, go to their + profile and select "Mute account" from the menu on their account. + </Trans> + </Text> + </View> + </View> + ) +} - footer: { - height: 200, - paddingTop: 20, - }, -}) +function Info({style}: {style?: StyleProp<ViewStyle>}) { + const t = useTheme() + return ( + <View + style={[ + a.w_full, + t.atoms.bg_contrast_25, + a.py_md, + a.px_xl, + a.border_t, + {marginTop: a.border.borderWidth * -1}, + t.atoms.border_contrast_low, + style, + ]}> + <Text style={[a.text_center, a.text_sm, t.atoms.text_contrast_high]}> + <Trans> + Muted accounts have their posts removed from your feed and from your + notifications. Mutes are completely private. + </Trans> + </Text> + </View> + ) +} diff --git a/src/view/shell/Composer.web.tsx b/src/view/shell/Composer.web.tsx index b76e88372..ce3695212 100644 --- a/src/view/shell/Composer.web.tsx +++ b/src/view/shell/Composer.web.tsx @@ -1,18 +1,16 @@ import React from 'react' import {StyleSheet, View} from 'react-native' -import {DismissableLayer} from '@radix-ui/react-dismissable-layer' -import {useFocusGuards} from '@radix-ui/react-focus-guards' -import {FocusScope} from '@radix-ui/react-focus-scope' +import {DismissableLayer, FocusGuards, FocusScope} from 'radix-ui/internal' import {RemoveScrollBar} from 'react-remove-scroll-bar' import {useA11y} from '#/state/a11y' import {useModals} from '#/state/modals' -import {ComposerOpts, useComposerState} from '#/state/shell/composer' +import {type ComposerOpts, useComposerState} from '#/state/shell/composer' import { EmojiPicker, - EmojiPickerPosition, - EmojiPickerState, -} from '#/view/com/composer/text-input/web/EmojiPicker.web' + type EmojiPickerPosition, + type EmojiPickerState, +} from '#/view/com/composer/text-input/web/EmojiPicker' import {atoms as a, flatten, useBreakpoints, useTheme} from '#/alf' import {ComposePost, useComposerCancelRef} from '../com/composer/Composer' @@ -66,11 +64,11 @@ function Inner({state}: {state: ComposerOpts}) { })) }, []) - useFocusGuards() + FocusGuards.useFocusGuards() return ( - <FocusScope loop trapped asChild> - <DismissableLayer + <FocusScope.FocusScope loop trapped asChild> + <DismissableLayer.DismissableLayer role="dialog" aria-modal style={flatten([ @@ -114,8 +112,8 @@ function Inner({state}: {state: ComposerOpts}) { /> </View> <EmojiPicker state={pickerState} close={onClosePicker} /> - </DismissableLayer> - </FocusScope> + </DismissableLayer.DismissableLayer> + </FocusScope.FocusScope> ) } diff --git a/src/view/shell/createNativeStackNavigatorWithAuth.tsx b/src/view/shell/createNativeStackNavigatorWithAuth.tsx index 11beaa2e9..868bba5b0 100644 --- a/src/view/shell/createNativeStackNavigatorWithAuth.tsx +++ b/src/view/shell/createNativeStackNavigatorWithAuth.tsx @@ -5,21 +5,21 @@ import {View} from 'react-native' // Copyright (c) 2017 React Navigation Contributors import { createNavigatorFactory, - EventArg, - ParamListBase, - StackActionHelpers, + type EventArg, + type ParamListBase, + type StackActionHelpers, StackActions, - StackNavigationState, + type StackNavigationState, StackRouter, - StackRouterOptions, + type StackRouterOptions, useNavigationBuilder, } from '@react-navigation/native' -import type { - NativeStackNavigationEventMap, - NativeStackNavigationOptions, +import { + type NativeStackNavigationEventMap, + type NativeStackNavigationOptions, } from '@react-navigation/native-stack' import {NativeStackView} from '@react-navigation/native-stack' -import type {NativeStackNavigatorProps} from '@react-navigation/native-stack/src/types' +import {type NativeStackNavigatorProps} from '@react-navigation/native-stack/src/types' import {PWI_ENABLED} from '#/lib/build-flags' import {useWebMediaQueries} from '#/lib/hooks/useWebMediaQueries' @@ -35,7 +35,7 @@ import {Deactivated} from '#/screens/Deactivated' import {Onboarding} from '#/screens/Onboarding' import {SignupQueued} from '#/screens/SignupQueued' import {Takendown} from '#/screens/Takendown' -import {atoms as a} from '#/alf' +import {atoms as a, useLayoutBreakpoints} from '#/alf' import {BottomBarWeb} from './bottom-bar/BottomBarWeb' import {DesktopLeftNav} from './desktop/LeftNav' import {DesktopRightNav} from './desktop/RightNav' @@ -101,7 +101,8 @@ function NativeStackNavigator({ const onboardingState = useOnboardingState() const {showLoggedOut} = useLoggedOutView() const {setShowLoggedOut} = useLoggedOutViewControls() - const {isMobile, isTabletOrMobile} = useWebMediaQueries() + const {isMobile} = useWebMediaQueries() + const {leftNavMinimal} = useLayoutBreakpoints() if (!hasSession && (!PWI_ENABLED || activeRouteRequiresAuth || isNative)) { return <LoggedOut /> } @@ -138,7 +139,7 @@ function NativeStackNavigator({ // Show the bottom bar if we have a session only on mobile web. If we don't have a session, we want to show it // on both tablet and mobile web so that we see the create account CTA. - const showBottomBar = hasSession ? isMobile : isTabletOrMobile + const showBottomBar = hasSession ? isMobile : leftNavMinimal return ( <NavigationContent> diff --git a/src/view/shell/desktop/LeftNav.tsx b/src/view/shell/desktop/LeftNav.tsx index 5cef18ebf..7d7c0ac8d 100644 --- a/src/view/shell/desktop/LeftNav.tsx +++ b/src/view/shell/desktop/LeftNav.tsx @@ -571,7 +571,7 @@ export function DesktopLeftNav() { ]}> {hasSession ? ( <ProfileCard /> - ) : isDesktop ? ( + ) : !leftNavMinimal ? ( <View style={[a.pt_xl]}> <NavSignupCard /> </View> diff --git a/src/view/shell/index.tsx b/src/view/shell/index.tsx index 3d3a5520c..1e34f6da5 100644 --- a/src/view/shell/index.tsx +++ b/src/view/shell/index.tsx @@ -25,6 +25,7 @@ import {ModalsContainer} from '#/view/com/modals/Modal' import {ErrorBoundary} from '#/view/com/util/ErrorBoundary' import {atoms as a, select, useTheme} from '#/alf' import {setSystemUITheme} from '#/alf/util/systemUI' +import {InAppBrowserConsentDialog} from '#/components/dialogs/InAppBrowserConsent' import {MutedWordsDialog} from '#/components/dialogs/MutedWords' import {SigninDialog} from '#/components/dialogs/Signin' import {Outlet as PortalOutlet} from '#/components/Portal' @@ -151,6 +152,7 @@ function ShellInner() { <ModalsContainer /> <MutedWordsDialog /> <SigninDialog /> + <InAppBrowserConsentDialog /> <Lightbox /> <PortalOutlet /> <BottomSheetOutlet /> diff --git a/yarn.lock b/yarn.lock index 57c647d92..46eaf0844 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5312,15 +5312,54 @@ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== +"@radix-ui/number@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/number/-/number-1.1.1.tgz#7b2c9225fbf1b126539551f5985769d0048d9090" + integrity sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g== + "@radix-ui/primitive@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.1.0.tgz#42ef83b3b56dccad5d703ae8c42919a68798bbe2" integrity sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA== -"@radix-ui/primitive@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.1.1.tgz#fc169732d755c7fbad33ba8d0cd7fd10c90dc8e3" - integrity sha512-SJ31y+Q/zAyShtXJc8x83i9TYdbAfHZ++tUZnvjJJqFjzsdUnKsxPL6IEtBlxKkU7yzer//GQtZSV4GbldL3YA== +"@radix-ui/primitive@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@radix-ui/primitive/-/primitive-1.1.2.tgz#83f415c4425f21e3d27914c12b3272a32e3dae65" + integrity sha512-XnbHrrprsNqZKQhStrSwgRUQzoCI1glLzdw79xiZPoofhGICeZRSQ3dIxAKH1gb3OHfNf4d6f+vAv3kil2eggA== + +"@radix-ui/react-accessible-icon@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-accessible-icon/-/react-accessible-icon-1.1.3.tgz#d31766a08fa506770fe2b11ef16c276398bc5a55" + integrity sha512-givBUIlhucV212j05wJCzXtcUtQnAwoUF9eAyUyOB2YwKHnWyme817trCtAzLjo0OndPr09kbkFe2onKRxLWdg== + dependencies: + "@radix-ui/react-visually-hidden" "1.1.3" + +"@radix-ui/react-accordion@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-accordion/-/react-accordion-1.2.4.tgz#7ccfceb959bbb3bac2f92e5e75b2654a488a2ff0" + integrity sha512-SGCxlSBaMvEzDROzyZjsVNzu9XY5E28B3k8jOENyrz6csOv/pG1eHyYfLJai1n9tRjwG61coXDhfpgtxKxUv5g== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-collapsible" "1.1.4" + "@radix-ui/react-collection" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-use-controllable-state" "1.1.1" + +"@radix-ui/react-alert-dialog@1.1.7": + version "1.1.7" + resolved "https://registry.yarnpkg.com/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.1.7.tgz#d4e07dcf9a3c67c45225c20c2800577773469454" + integrity sha512-7Gx1gcoltd0VxKoR8mc+TAVbzvChJyZryZsTam0UhoL92z0L+W8ovxvcgvd+nkz24y7Qc51JQKBAGe4+825tYw== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-dialog" "1.1.7" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-slot" "1.2.0" "@radix-ui/react-arrow@1.1.0": version "1.1.0" @@ -5329,12 +5368,57 @@ dependencies: "@radix-ui/react-primitive" "2.0.0" -"@radix-ui/react-arrow@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-arrow/-/react-arrow-1.1.2.tgz#30c0d574d7bb10eed55cd7007b92d38b03c6b2ab" - integrity sha512-G+KcpzXHq24iH0uGG/pF8LyzpFJYGD4RfLjCIBfGdSLXvjLHST31RUiRVrupIBMvIppMgSzQ6l66iAxl03tdlg== +"@radix-ui/react-arrow@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-arrow/-/react-arrow-1.1.3.tgz#8926eb1d87f73c2e047eac96703949f168c85861" + integrity sha512-2dvVU4jva0qkNZH6HHWuSz5FN5GeU5tymvCgutF8WaXz9WnD1NgUhy73cqzkjkN4Zkn8lfTPv5JIfrC221W+Nw== + dependencies: + "@radix-ui/react-primitive" "2.0.3" + +"@radix-ui/react-aspect-ratio@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.1.3.tgz#8a1fa699e2eb3dfea614383b0f4b2cef2fa2bb43" + integrity sha512-yIrYZUc2e/JtRkDpuJCmaR6kj/jzekDfQLcPFdEWzSOygCPy8poR4YcszaHP5A7mh25ncofHEpeTwfhxEuBv8Q== + dependencies: + "@radix-ui/react-primitive" "2.0.3" + +"@radix-ui/react-avatar@1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-avatar/-/react-avatar-1.1.4.tgz#55dd879cd57b08265cf313b92ba1021f7f4d5abe" + integrity sha512-+kBesLBzwqyDiYCtYFK+6Ktf+N7+Y6QOTUueLGLIbLZ/YeyFW6bsBGDsN+5HxHpM55C90u5fxsg0ErxzXTcwKA== dependencies: - "@radix-ui/react-primitive" "2.0.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-checkbox@1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@radix-ui/react-checkbox/-/react-checkbox-1.1.5.tgz#b27080678d751e33ac66066269453be9bdaa429b" + integrity sha512-B0gYIVxl77KYDR25AY9EGe/G//ef85RVBIxQvK+m5pxAC7XihAc/8leMHhDvjvhDu02SBSb6BuytlWr/G7F3+g== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-presence" "1.1.3" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-use-controllable-state" "1.1.1" + "@radix-ui/react-use-previous" "1.1.1" + "@radix-ui/react-use-size" "1.1.1" + +"@radix-ui/react-collapsible@1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-collapsible/-/react-collapsible-1.1.4.tgz#59729939c0c5db978934c688aa5f8229876d8f3f" + integrity sha512-u7LCw1EYInQtBNLGjm9nZ89S/4GcvX1UR5XbekEgnQae2Hkpq39ycJ1OhdeN1/JDfVNG91kWaWoest127TaEKQ== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-presence" "1.1.3" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-use-controllable-state" "1.1.1" + "@radix-ui/react-use-layout-effect" "1.1.1" "@radix-ui/react-collection@1.1.0": version "1.1.0" @@ -5346,25 +5430,37 @@ "@radix-ui/react-primitive" "2.0.0" "@radix-ui/react-slot" "1.1.0" -"@radix-ui/react-collection@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.1.2.tgz#b45eccca1cb902fd078b237316bd9fa81e621e15" - integrity sha512-9z54IEKRxIa9VityapoEYMuByaG42iSy1ZXlY2KcuLSEtq8x4987/N6m15ppoMffgZX72gER2uHe1D9Y6Unlcw== +"@radix-ui/react-collection@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-collection/-/react-collection-1.1.3.tgz#cfd46dcea5a8ab064d91798feeb46faba4032930" + integrity sha512-mM2pxoQw5HJ49rkzwOs7Y6J4oYH22wS8BfK2/bBxROlI4xuR0c4jEenQP63LlTlDkO6Buj2Vt+QYAYcOgqtrXA== dependencies: - "@radix-ui/react-compose-refs" "1.1.1" - "@radix-ui/react-context" "1.1.1" - "@radix-ui/react-primitive" "2.0.2" - "@radix-ui/react-slot" "1.1.2" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-slot" "1.2.0" "@radix-ui/react-compose-refs@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz#656432461fc8283d7b591dcf0d79152fae9ecc74" integrity sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw== -"@radix-ui/react-compose-refs@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.1.tgz#6f766faa975f8738269ebb8a23bad4f5a8d2faec" - integrity sha512-Y9VzoRDSJtgFMUCoiZBDVo084VQ5hfpXxVE+NgkdNsjiDBByiImMZKKhxMwCbdHvhlENG6a833CbFkOQvTricw== +"@radix-ui/react-compose-refs@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz#a2c4c47af6337048ee78ff6dc0d090b390d2bb30" + integrity sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg== + +"@radix-ui/react-context-menu@2.2.7": + version "2.2.7" + resolved "https://registry.yarnpkg.com/@radix-ui/react-context-menu/-/react-context-menu-2.2.7.tgz#6d05eb191f3b45a040b1892fb91eaed1504b25f8" + integrity sha512-EwO3tyyqwGaLPg0P64jmIKJnBywD0yjiL1eRuMPyhUXPkWWpa5JPDS+oyeIWHy2JbhF+NUlfUPVq6vE7OqgZww== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-menu" "2.1.7" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-controllable-state" "1.1.1" "@radix-ui/react-context-menu@^2.0.1": version "2.2.2" @@ -5388,11 +5484,41 @@ resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.1.tgz#82074aa83a472353bb22e86f11bcbd1c61c4c71a" integrity sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q== +"@radix-ui/react-context@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@radix-ui/react-context/-/react-context-1.1.2.tgz#61628ef269a433382c364f6f1e3788a6dc213a36" + integrity sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA== + +"@radix-ui/react-dialog@1.1.7": + version "1.1.7" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dialog/-/react-dialog-1.1.7.tgz#c826d997d9e512bd2a2adb3245bb9dffe56e02aa" + integrity sha512-EIdma8C0C/I6kL6sO02avaCRqi3fmWJpxH6mqbVScorW6nNktzKJT/le7VPho3o/7wCsyRg3z0+Q+Obr0Gy/VQ== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-dismissable-layer" "1.1.6" + "@radix-ui/react-focus-guards" "1.1.2" + "@radix-ui/react-focus-scope" "1.1.3" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-portal" "1.1.5" + "@radix-ui/react-presence" "1.1.3" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-slot" "1.2.0" + "@radix-ui/react-use-controllable-state" "1.1.1" + aria-hidden "^1.2.4" + react-remove-scroll "^2.6.3" + "@radix-ui/react-direction@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.1.0.tgz#a7d39855f4d077adc2a1922f9c353c5977a09cdc" integrity sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg== +"@radix-ui/react-direction@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-direction/-/react-direction-1.1.1.tgz#39e5a5769e676c753204b792fbe6cf508e550a14" + integrity sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw== + "@radix-ui/react-dismissable-layer@1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.1.tgz#cbdcb739c5403382bdde5f9243042ba643883396" @@ -5404,29 +5530,29 @@ "@radix-ui/react-use-callback-ref" "1.1.0" "@radix-ui/react-use-escape-keydown" "1.1.0" -"@radix-ui/react-dismissable-layer@1.1.5", "@radix-ui/react-dismissable-layer@^1.1.5": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.5.tgz#96dde2be078c694a621e55e047406c58cd5fe774" - integrity sha512-E4TywXY6UsXNRhFrECa5HAvE5/4BFcGyfTyK36gP+pAW1ed7UTK4vKwdr53gAJYwqbfCWC6ATvJa3J3R/9+Qrg== - dependencies: - "@radix-ui/primitive" "1.1.1" - "@radix-ui/react-compose-refs" "1.1.1" - "@radix-ui/react-primitive" "2.0.2" - "@radix-ui/react-use-callback-ref" "1.1.0" - "@radix-ui/react-use-escape-keydown" "1.1.0" - -"@radix-ui/react-dropdown-menu@2.1.6": - version "2.1.6" - resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.6.tgz#b66b62648b378370aa3c38e5727fd3bc5b8792a3" - integrity sha512-no3X7V5fD487wab/ZYSHXq3H37u4NVeLDKI/Ks724X/eEFSSEFYZxWgsIlr1UBeEyDaM29HM5x9p1Nv8DuTYPA== - dependencies: - "@radix-ui/primitive" "1.1.1" - "@radix-ui/react-compose-refs" "1.1.1" - "@radix-ui/react-context" "1.1.1" - "@radix-ui/react-id" "1.1.0" - "@radix-ui/react-menu" "2.1.6" - "@radix-ui/react-primitive" "2.0.2" - "@radix-ui/react-use-controllable-state" "1.1.0" +"@radix-ui/react-dismissable-layer@1.1.6": + version "1.1.6" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.6.tgz#e72c156cac7b07614fe8e3a039ab7081ce413686" + integrity sha512-7gpgMT2gyKym9Jz2ZhlRXSg2y6cNQIK8d/cqBZ0RBCaps8pFryCWXiUKI+uHGFrhMrbGUP7U6PWgiXzIxoyF3Q== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-escape-keydown" "1.1.1" + +"@radix-ui/react-dropdown-menu@2.1.7": + version "2.1.7" + resolved "https://registry.yarnpkg.com/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.1.7.tgz#a18860ff69bdf061b7f8ace51db01db2eb225161" + integrity sha512-7/1LiuNZuCQE3IzdicGoHdQOHkS2Q08+7p8w6TXZ6ZjgAULaCI85ZY15yPl4o4FVgoKLRT43/rsfNVN8osClQQ== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-menu" "2.1.7" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-use-controllable-state" "1.1.1" "@radix-ui/react-dropdown-menu@^2.0.1": version "2.1.2" @@ -5441,11 +5567,16 @@ "@radix-ui/react-primitive" "2.0.0" "@radix-ui/react-use-controllable-state" "1.1.0" -"@radix-ui/react-focus-guards@1.1.1", "@radix-ui/react-focus-guards@^1.1.1": +"@radix-ui/react-focus-guards@1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.1.tgz#8635edd346304f8b42cae86b05912b61aef27afe" integrity sha512-pSIwfrT1a6sIoDASCSpFwOasEwKTZWDw/iBdtnqKO7v6FeOzYJ7U53cPzYFVR3geGGXgVHaH+CdngrrAzqUGxg== +"@radix-ui/react-focus-guards@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.2.tgz#4ec9a7e50925f7fb661394460045b46212a33bed" + integrity sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA== + "@radix-ui/react-focus-scope@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.0.tgz#ebe2891a298e0a33ad34daab2aad8dea31caf0b2" @@ -5455,14 +5586,41 @@ "@radix-ui/react-primitive" "2.0.0" "@radix-ui/react-use-callback-ref" "1.1.0" -"@radix-ui/react-focus-scope@1.1.2", "@radix-ui/react-focus-scope@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.2.tgz#c0a4519cd95c772606a82fc5b96226cd7fdd2602" - integrity sha512-zxwE80FCU7lcXUGWkdt6XpTTCKPitG1XKOwViTxHVKIJhZl9MvIl2dVHeZENCWD9+EdWv05wlaEkRXUykU27RA== +"@radix-ui/react-focus-scope@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.3.tgz#eac83a3aac700db17650b41b30724deffac5b28a" + integrity sha512-4XaDlq0bPt7oJwR+0k0clCiCO/7lO7NKZTAaJBYxDNQT/vj4ig0/UvctrRscZaFREpRvUTkpKR96ov1e6jptQg== dependencies: - "@radix-ui/react-compose-refs" "1.1.1" - "@radix-ui/react-primitive" "2.0.2" - "@radix-ui/react-use-callback-ref" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + +"@radix-ui/react-form@0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-form/-/react-form-0.1.3.tgz#f3dd9a985eade574d043dabb50960946ee8dee5b" + integrity sha512-fVxaewKm9+oKL5q+E1+tIKNEkAeh8waJ+MsFNhLFAmpF8VG6nrNXYd2FFU8J7P3gIGNr023Sp+dD0xflqI84mA== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-label" "2.1.3" + "@radix-ui/react-primitive" "2.0.3" + +"@radix-ui/react-hover-card@1.1.7": + version "1.1.7" + resolved "https://registry.yarnpkg.com/@radix-ui/react-hover-card/-/react-hover-card-1.1.7.tgz#01b2f956daeb8a1193ccdb36c9c00943120bf2d4" + integrity sha512-HwM03kP8psrv21J1+9T/hhxi0f5rARVbqIZl9+IAq13l4j4fX+oGIuxisukZZmebO7J35w9gpoILvtG8bbph0w== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-dismissable-layer" "1.1.6" + "@radix-ui/react-popper" "1.2.3" + "@radix-ui/react-portal" "1.1.5" + "@radix-ui/react-presence" "1.1.3" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-use-controllable-state" "1.1.1" "@radix-ui/react-id@1.1.0": version "1.1.0" @@ -5471,6 +5629,20 @@ dependencies: "@radix-ui/react-use-layout-effect" "1.1.0" +"@radix-ui/react-id@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-id/-/react-id-1.1.1.tgz#1404002e79a03fe062b7e3864aa01e24bd1471f7" + integrity sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg== + dependencies: + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-label@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-label/-/react-label-2.1.3.tgz#de83641c90c57e58f0d1e1943d450dbc3936a23f" + integrity sha512-zwSQ1NzSKG95yA0tvBMgv6XPHoqapJCcg9nsUBaQQ66iRBhZNhlpaQG2ERYYX4O4stkYFK5rxj5NsWfO9CS+Hg== + dependencies: + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-menu@2.1.2": version "2.1.2" resolved "https://registry.yarnpkg.com/@radix-ui/react-menu/-/react-menu-2.1.2.tgz#91f6815845a4298dde775563ed2d80b7ad667899" @@ -5495,27 +5667,84 @@ aria-hidden "^1.1.1" react-remove-scroll "2.6.0" -"@radix-ui/react-menu@2.1.6": - version "2.1.6" - resolved "https://registry.yarnpkg.com/@radix-ui/react-menu/-/react-menu-2.1.6.tgz#05fb1ef3fd7545c8abe61178372902970cdec3ce" - integrity sha512-tBBb5CXDJW3t2mo9WlO7r6GTmWV0F0uzHZVFmlRmYpiSK1CDU5IKojP1pm7oknpBOrFZx/YgBRW9oorPO2S/Lg== - dependencies: - "@radix-ui/primitive" "1.1.1" - "@radix-ui/react-collection" "1.1.2" - "@radix-ui/react-compose-refs" "1.1.1" - "@radix-ui/react-context" "1.1.1" - "@radix-ui/react-direction" "1.1.0" - "@radix-ui/react-dismissable-layer" "1.1.5" - "@radix-ui/react-focus-guards" "1.1.1" - "@radix-ui/react-focus-scope" "1.1.2" - "@radix-ui/react-id" "1.1.0" - "@radix-ui/react-popper" "1.2.2" - "@radix-ui/react-portal" "1.1.4" - "@radix-ui/react-presence" "1.1.2" - "@radix-ui/react-primitive" "2.0.2" - "@radix-ui/react-roving-focus" "1.1.2" - "@radix-ui/react-slot" "1.1.2" - "@radix-ui/react-use-callback-ref" "1.1.0" +"@radix-ui/react-menu@2.1.7": + version "2.1.7" + resolved "https://registry.yarnpkg.com/@radix-ui/react-menu/-/react-menu-2.1.7.tgz#e85f47e3762245d88d7a3bad3f2268c21f835111" + integrity sha512-tBODsrk68rOi1/iQzbM54toFF+gSw/y+eQgttFflqlGekuSebNqvFNHjJgjqPhiMb4Fw9A0zNFly1QT6ZFdQ+Q== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-collection" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-dismissable-layer" "1.1.6" + "@radix-ui/react-focus-guards" "1.1.2" + "@radix-ui/react-focus-scope" "1.1.3" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-popper" "1.2.3" + "@radix-ui/react-portal" "1.1.5" + "@radix-ui/react-presence" "1.1.3" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-roving-focus" "1.1.3" + "@radix-ui/react-slot" "1.2.0" + "@radix-ui/react-use-callback-ref" "1.1.1" + aria-hidden "^1.2.4" + react-remove-scroll "^2.6.3" + +"@radix-ui/react-menubar@1.1.7": + version "1.1.7" + resolved "https://registry.yarnpkg.com/@radix-ui/react-menubar/-/react-menubar-1.1.7.tgz#d6980295858134729d22fd3b6f9ca63fbebd5574" + integrity sha512-YB2zFhGdZ5SWEgRS+PgrF7EkwpsjEHntIFB/LRbT49LJdnIeK/xQQyuwLiRcOCgTDN+ALlPXQ08f0P0+TfR41g== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-collection" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-menu" "2.1.7" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-roving-focus" "1.1.3" + "@radix-ui/react-use-controllable-state" "1.1.1" + +"@radix-ui/react-navigation-menu@1.2.6": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.2.6.tgz#4a333d4a7800fa1111343609460c713eb68d6bb5" + integrity sha512-HJqyzqG74Lj7KV58rk73i/B1nnopVyCfUmKgeGWWrZZiCuMNcY0KKugTrmqMbIeMliUnkBUDKCy9J6Mzl6xeWw== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-collection" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-dismissable-layer" "1.1.6" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-presence" "1.1.3" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-controllable-state" "1.1.1" + "@radix-ui/react-use-layout-effect" "1.1.1" + "@radix-ui/react-use-previous" "1.1.1" + "@radix-ui/react-visually-hidden" "1.1.3" + +"@radix-ui/react-popover@1.1.7": + version "1.1.7" + resolved "https://registry.yarnpkg.com/@radix-ui/react-popover/-/react-popover-1.1.7.tgz#4397a5c1a4b2c03efe350cf467a8ddd720115c39" + integrity sha512-I38OYWDmJF2kbO74LX8UsFydSHWOJuQ7LxPnTefjxxvdvPLempvAnmsyX9UsBlywcbSGpRH7oMLfkUf+ij4nrw== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-dismissable-layer" "1.1.6" + "@radix-ui/react-focus-guards" "1.1.2" + "@radix-ui/react-focus-scope" "1.1.3" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-popper" "1.2.3" + "@radix-ui/react-portal" "1.1.5" + "@radix-ui/react-presence" "1.1.3" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-slot" "1.2.0" + "@radix-ui/react-use-controllable-state" "1.1.1" aria-hidden "^1.2.4" react-remove-scroll "^2.6.3" @@ -5535,21 +5764,21 @@ "@radix-ui/react-use-size" "1.1.0" "@radix-ui/rect" "1.1.0" -"@radix-ui/react-popper@1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.2.2.tgz#d2e1ee5a9b24419c5936a1b7f6f472b7b412b029" - integrity sha512-Rvqc3nOpwseCyj/rgjlJDYAgyfw7OC1tTkKn2ivhaMGcYt8FSBlahHOZak2i3QwkRXUXgGgzeEe2RuqeEHuHgA== +"@radix-ui/react-popper@1.2.3": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-popper/-/react-popper-1.2.3.tgz#3b6ef3388fd209bb46341e1e40125b75f07f1304" + integrity sha512-iNb9LYUMkne9zIahukgQmHlSBp9XWGeQQ7FvUGNk45ywzOb6kQa+Ca38OphXlWDiKvyneo9S+KSJsLfLt8812A== dependencies: "@floating-ui/react-dom" "^2.0.0" - "@radix-ui/react-arrow" "1.1.2" - "@radix-ui/react-compose-refs" "1.1.1" - "@radix-ui/react-context" "1.1.1" - "@radix-ui/react-primitive" "2.0.2" - "@radix-ui/react-use-callback-ref" "1.1.0" - "@radix-ui/react-use-layout-effect" "1.1.0" - "@radix-ui/react-use-rect" "1.1.0" - "@radix-ui/react-use-size" "1.1.0" - "@radix-ui/rect" "1.1.0" + "@radix-ui/react-arrow" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-layout-effect" "1.1.1" + "@radix-ui/react-use-rect" "1.1.1" + "@radix-ui/react-use-size" "1.1.1" + "@radix-ui/rect" "1.1.1" "@radix-ui/react-portal@1.1.2": version "1.1.2" @@ -5559,13 +5788,13 @@ "@radix-ui/react-primitive" "2.0.0" "@radix-ui/react-use-layout-effect" "1.1.0" -"@radix-ui/react-portal@1.1.4": - version "1.1.4" - resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.1.4.tgz#ff5401ff63c8a825c46eea96d3aef66074b8c0c8" - integrity sha512-sn2O9k1rPFYVyKd5LAJfo96JlSGVFpa1fS6UuBJfrZadudiw5tAmru+n1x7aMRQ84qDM71Zh1+SzK5QwU0tJfA== +"@radix-ui/react-portal@1.1.5": + version "1.1.5" + resolved "https://registry.yarnpkg.com/@radix-ui/react-portal/-/react-portal-1.1.5.tgz#50ed6bee2d895c9a9dfc28625f24b8483b74d431" + integrity sha512-ps/67ZqsFm+Mb6lSPJpfhRLrVL2i2fntgCmGMqqth4eaGUf+knAuuRtWVJrNjUhExgmdRqftSgzpf0DF0n6yXA== dependencies: - "@radix-ui/react-primitive" "2.0.2" - "@radix-ui/react-use-layout-effect" "1.1.0" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-use-layout-effect" "1.1.1" "@radix-ui/react-presence@1.1.1": version "1.1.1" @@ -5575,13 +5804,13 @@ "@radix-ui/react-compose-refs" "1.1.0" "@radix-ui/react-use-layout-effect" "1.1.0" -"@radix-ui/react-presence@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.1.2.tgz#bb764ed8a9118b7ec4512da5ece306ded8703cdc" - integrity sha512-18TFr80t5EVgL9x1SwF/YGtfG+l0BS0PRAlCWBDoBEiDQjeKgnNZRVJp/oVBl24sr3Gbfwc/Qpj4OcWTQMsAEg== +"@radix-ui/react-presence@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-presence/-/react-presence-1.1.3.tgz#ce3400caec9892ceb862f96ddaa2add080c09b90" + integrity sha512-IrVLIhskYhH3nLvtcBLQFZr61tBG7wx7O3kEmdzcYwRGAEBmBicGGL7ATzNgruYJ3xBTbuzEEq9OXJM3PAX3tA== dependencies: - "@radix-ui/react-compose-refs" "1.1.1" - "@radix-ui/react-use-layout-effect" "1.1.0" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-use-layout-effect" "1.1.1" "@radix-ui/react-primitive@2.0.0": version "2.0.0" @@ -5590,12 +5819,36 @@ dependencies: "@radix-ui/react-slot" "1.1.0" -"@radix-ui/react-primitive@2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-2.0.2.tgz#ac8b7854d87b0d7af388d058268d9a7eb64ca8ef" - integrity sha512-Ec/0d38EIuvDF+GZjcMU/Ze6MxntVJYO/fRlCPhCaVUyPY9WTalHJw54tp9sXeJo3tlShWpy41vQRgLRGOuz+w== +"@radix-ui/react-primitive@2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-primitive/-/react-primitive-2.0.3.tgz#13c654dc4754558870a9c769f6febe5980a1bad8" + integrity sha512-Pf/t/GkndH7CQ8wE2hbkXA+WyZ83fhQQn5DDmwDiDo6AwN/fhaH8oqZ0jRjMrO2iaMhDi6P1HRx6AZwyMinY1g== dependencies: - "@radix-ui/react-slot" "1.1.2" + "@radix-ui/react-slot" "1.2.0" + +"@radix-ui/react-progress@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-progress/-/react-progress-1.1.3.tgz#78df084607432792368070ca4b060597ebc9190a" + integrity sha512-F56aZPGTPb4qJQ/vDjnAq63oTu/DRoIG/Asb5XKOWj8rpefNLtUllR969j5QDN2sRrTk9VXIqQDRj5VvAuquaw== + dependencies: + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-primitive" "2.0.3" + +"@radix-ui/react-radio-group@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-radio-group/-/react-radio-group-1.2.4.tgz#f170fc55bd02298e5782c96c69136a78d5bb91c2" + integrity sha512-oLz7ATfKgVTUbpr5OBu6Q7hQcnV22uPT306bmG0QwgnKqBStR98RfWfJGCfW/MmhL4ISmrmmBPBW+c77SDwV9g== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-presence" "1.1.3" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-roving-focus" "1.1.3" + "@radix-ui/react-use-controllable-state" "1.1.1" + "@radix-ui/react-use-previous" "1.1.1" + "@radix-ui/react-use-size" "1.1.1" "@radix-ui/react-roving-focus@1.1.0": version "1.1.0" @@ -5612,20 +5865,86 @@ "@radix-ui/react-use-callback-ref" "1.1.0" "@radix-ui/react-use-controllable-state" "1.1.0" -"@radix-ui/react-roving-focus@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.2.tgz#815d051a54299114a68db6eb8d34c41a3c0a646f" - integrity sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw== +"@radix-ui/react-roving-focus@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.3.tgz#c992b9d30c795f5f5a668853db8f4a6e07b7284d" + integrity sha512-ufbpLUjZiOg4iYgb2hQrWXEPYX6jOLBbR27bDyAff5GYMRrCzcze8lukjuXVUQvJ6HZe8+oL+hhswDcjmcgVyg== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-collection" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-controllable-state" "1.1.1" + +"@radix-ui/react-scroll-area@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-scroll-area/-/react-scroll-area-1.2.4.tgz#4b6fd6fccaae26dbe73700fe8c5be5313984d8f4" + integrity sha512-G9rdWTQjOR4sk76HwSdROhPU0jZWpfozn9skU1v4N0/g9k7TmswrJn8W8WMU+aYktnLLpk5LX6fofj2bGe5NFQ== + dependencies: + "@radix-ui/number" "1.1.1" + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-presence" "1.1.3" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-select@2.1.7": + version "2.1.7" + resolved "https://registry.yarnpkg.com/@radix-ui/react-select/-/react-select-2.1.7.tgz#68561488ca54cad07352b3f2c2d29e0da28bbaa0" + integrity sha512-exzGIRtc7S8EIM2KjFg+7lJZsH7O7tpaBaJbBNVDnOZNhtoQ2iV+iSNfi2Wth0m6h3trJkMVvzAehB3c6xj/3Q== + dependencies: + "@radix-ui/number" "1.1.1" + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-collection" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-dismissable-layer" "1.1.6" + "@radix-ui/react-focus-guards" "1.1.2" + "@radix-ui/react-focus-scope" "1.1.3" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-popper" "1.2.3" + "@radix-ui/react-portal" "1.1.5" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-slot" "1.2.0" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-controllable-state" "1.1.1" + "@radix-ui/react-use-layout-effect" "1.1.1" + "@radix-ui/react-use-previous" "1.1.1" + "@radix-ui/react-visually-hidden" "1.1.3" + aria-hidden "^1.2.4" + react-remove-scroll "^2.6.3" + +"@radix-ui/react-separator@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-separator/-/react-separator-1.1.3.tgz#767ea659592efaafda3c738833ff325e54d83de5" + integrity sha512-2omrWKJvxR0U/tkIXezcc1nFMwtLU0+b/rDK40gnzJqTLWQ/TD/D5IYVefp9sC3QWfeQbpSbEA6op9MQKyaALQ== dependencies: - "@radix-ui/primitive" "1.1.1" - "@radix-ui/react-collection" "1.1.2" - "@radix-ui/react-compose-refs" "1.1.1" - "@radix-ui/react-context" "1.1.1" - "@radix-ui/react-direction" "1.1.0" - "@radix-ui/react-id" "1.1.0" - "@radix-ui/react-primitive" "2.0.2" - "@radix-ui/react-use-callback-ref" "1.1.0" - "@radix-ui/react-use-controllable-state" "1.1.0" + "@radix-ui/react-primitive" "2.0.3" + +"@radix-ui/react-slider@1.2.4": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-slider/-/react-slider-1.2.4.tgz#29cd5e53806d828f81f32af8ff88489a25c1072d" + integrity sha512-Vr/OgNejNJPAghIhjS7Mf/2F/EXGDT0qgtiHf2BHz71+KqgN+jndFLKq5xAB9JOGejGzejfJLIvT04Do+yzhcg== + dependencies: + "@radix-ui/number" "1.1.1" + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-collection" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-use-controllable-state" "1.1.1" + "@radix-ui/react-use-layout-effect" "1.1.1" + "@radix-ui/react-use-previous" "1.1.1" + "@radix-ui/react-use-size" "1.1.1" "@radix-ui/react-slot@1.1.0": version "1.1.0" @@ -5634,18 +5953,121 @@ dependencies: "@radix-ui/react-compose-refs" "1.1.0" -"@radix-ui/react-slot@1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.1.2.tgz#daffff7b2bfe99ade63b5168407680b93c00e1c6" - integrity sha512-YAKxaiGsSQJ38VzKH86/BPRC4rh+b1Jpa+JneA5LRE7skmLPNAyeG8kPJj/oo4STLvlrs8vkf/iYyc3A5stYCQ== +"@radix-ui/react-slot@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-slot/-/react-slot-1.2.0.tgz#57727fc186ddb40724ccfbe294e1a351d92462ba" + integrity sha512-ujc+V6r0HNDviYqIK3rW4ffgYiZ8g5DEHrGJVk4x7kTlLXRDILnKX9vAUYeIsLOoDpDJ0ujpqMkjH4w2ofuo6w== + dependencies: + "@radix-ui/react-compose-refs" "1.1.2" + +"@radix-ui/react-switch@1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-switch/-/react-switch-1.1.4.tgz#a0672f67974ad11cd8e2304b04aad8ce684eb037" + integrity sha512-zGP6W8plLeogoeGMiTHJ/uvf+TE1C2chVsEwfP8YlvpQKJHktG+iCkUtCLGPAuDV8/qDSmIRPm4NggaTxFMVBQ== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-use-controllable-state" "1.1.1" + "@radix-ui/react-use-previous" "1.1.1" + "@radix-ui/react-use-size" "1.1.1" + +"@radix-ui/react-tabs@1.1.4": + version "1.1.4" + resolved "https://registry.yarnpkg.com/@radix-ui/react-tabs/-/react-tabs-1.1.4.tgz#2e43f3ef3450143281e7c1491da1e5d7941b9826" + integrity sha512-fuHMHWSf5SRhXke+DbHXj2wVMo+ghVH30vhX3XVacdXqDl+J4XWafMIGOOER861QpBx1jxgwKXL2dQnfrsd8MQ== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-presence" "1.1.3" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-roving-focus" "1.1.3" + "@radix-ui/react-use-controllable-state" "1.1.1" + +"@radix-ui/react-toast@1.2.7": + version "1.2.7" + resolved "https://registry.yarnpkg.com/@radix-ui/react-toast/-/react-toast-1.2.7.tgz#57954e88061c20f12a9c6ac7cbd532d2c3ca1186" + integrity sha512-0IWTbAUKvzdpOaWDMZisXZvScXzF0phaQjWspK8RUMEUxjLbli+886mB/kXTIC3F+t5vQ0n0vYn+dsX8s+WdfA== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-collection" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-dismissable-layer" "1.1.6" + "@radix-ui/react-portal" "1.1.5" + "@radix-ui/react-presence" "1.1.3" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-controllable-state" "1.1.1" + "@radix-ui/react-use-layout-effect" "1.1.1" + "@radix-ui/react-visually-hidden" "1.1.3" + +"@radix-ui/react-toggle-group@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.3.tgz#39ec34b5c67416bf285eac19ef6898532a0c56c6" + integrity sha512-khTzdGIxy8WurYUEUrapvj5aOev/tUA8TDEFi1D0Dn3yX+KR5AqjX0b7E5sL9ngRRpxDN2RRJdn5siasu5jtcg== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-roving-focus" "1.1.3" + "@radix-ui/react-toggle" "1.1.3" + "@radix-ui/react-use-controllable-state" "1.1.1" + +"@radix-ui/react-toggle@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-toggle/-/react-toggle-1.1.3.tgz#5e0275c3788a38f77521a47c1446d2efa840641d" + integrity sha512-Za5HHd9nvsiZ2t3EI/dVd4Bm/JydK+D22uHKk46fPtvuPxVCJBUo5mQybN+g5sZe35y7I6GDTTfdkVv5SnxlFg== dependencies: - "@radix-ui/react-compose-refs" "1.1.1" + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-use-controllable-state" "1.1.1" + +"@radix-ui/react-toolbar@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-toolbar/-/react-toolbar-1.1.3.tgz#7937b5a6890b35bda23cbf3b2de279779dd5162e" + integrity sha512-yTZ8ooxlBqljSiruO6y6azKXSXYBpnzd23yohjyFesun4nm8yh+D91J1yCqhtnRtSjRWuAmr9vFgGxmGwLjTfg== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-roving-focus" "1.1.3" + "@radix-ui/react-separator" "1.1.3" + "@radix-ui/react-toggle-group" "1.1.3" + +"@radix-ui/react-tooltip@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@radix-ui/react-tooltip/-/react-tooltip-1.2.0.tgz#aee9fed9db53e4c84f525aada3436b651464a532" + integrity sha512-b1Sdc75s7zN9B8ONQTGBSHL3XS8+IcjcOIY51fhM4R1Hx8s0YbgqgyNZiri4qcYMVZK8hfCZVBiyCm7N9rs0rw== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-dismissable-layer" "1.1.6" + "@radix-ui/react-id" "1.1.1" + "@radix-ui/react-popper" "1.2.3" + "@radix-ui/react-portal" "1.1.5" + "@radix-ui/react-presence" "1.1.3" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-slot" "1.2.0" + "@radix-ui/react-use-controllable-state" "1.1.1" + "@radix-ui/react-visually-hidden" "1.1.3" "@radix-ui/react-use-callback-ref@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz#bce938ca413675bc937944b0d01ef6f4a6dc5bf1" integrity sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw== +"@radix-ui/react-use-callback-ref@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz#62a4dba8b3255fdc5cc7787faeac1c6e4cc58d40" + integrity sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg== + "@radix-ui/react-use-controllable-state@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz#1321446857bb786917df54c0d4d084877aab04b0" @@ -5653,6 +6075,13 @@ dependencies: "@radix-ui/react-use-callback-ref" "1.1.0" +"@radix-ui/react-use-controllable-state@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.1.tgz#ec9c572072a6f269df7435c1652fbeebabe0f0c1" + integrity sha512-YnEXIy8/ga01Y1PN0VfaNH//MhA91JlEGVBDxDzROqwrAtG5Yr2QGEPz8A/rJA3C7ZAHryOYGaUv8fLSW2H/mg== + dependencies: + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-escape-keydown@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz#31a5b87c3b726504b74e05dac1edce7437b98754" @@ -5660,11 +6089,28 @@ dependencies: "@radix-ui/react-use-callback-ref" "1.1.0" +"@radix-ui/react-use-escape-keydown@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz#b3fed9bbea366a118f40427ac40500aa1423cc29" + integrity sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g== + dependencies: + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-layout-effect@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz#3c2c8ce04827b26a39e442ff4888d9212268bd27" integrity sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w== +"@radix-ui/react-use-layout-effect@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz#0c4230a9eed49d4589c967e2d9c0d9d60a23971e" + integrity sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ== + +"@radix-ui/react-use-previous@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz#1a1ad5568973d24051ed0af687766f6c7cb9b5b5" + integrity sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ== + "@radix-ui/react-use-rect@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz#13b25b913bd3e3987cc9b073a1a164bb1cf47b88" @@ -5672,6 +6118,13 @@ dependencies: "@radix-ui/rect" "1.1.0" +"@radix-ui/react-use-rect@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz#01443ca8ed071d33023c1113e5173b5ed8769152" + integrity sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w== + dependencies: + "@radix-ui/rect" "1.1.1" + "@radix-ui/react-use-size@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz#b4dba7fbd3882ee09e8d2a44a3eed3a7e555246b" @@ -5679,11 +6132,30 @@ dependencies: "@radix-ui/react-use-layout-effect" "1.1.0" +"@radix-ui/react-use-size@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz#6de276ffbc389a537ffe4316f5b0f24129405b37" + integrity sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ== + dependencies: + "@radix-ui/react-use-layout-effect" "1.1.1" + +"@radix-ui/react-visually-hidden@1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.3.tgz#f704c49121859941a8bb50ff1e4f156058cacd0b" + integrity sha512-oXSF3ZQRd5fvomd9hmUCb2EHSZbPp3ZSHAHJJU/DlF9XoFkJBBW8RHU/E8WEH+RbSfJd/QFA0sl8ClJXknBwHQ== + dependencies: + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/rect@1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-1.1.0.tgz#f817d1d3265ac5415dadc67edab30ae196696438" integrity sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg== +"@radix-ui/rect@1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@radix-ui/rect/-/rect-1.1.1.tgz#78244efe12930c56fd255d7923865857c41ac8cb" + integrity sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw== + "@react-native-async-storage/async-storage@1.23.1": version "1.23.1" resolved "https://registry.yarnpkg.com/@react-native-async-storage/async-storage/-/async-storage-1.23.1.tgz#cad3cd4fab7dacfe9838dce6ecb352f79150c883" @@ -16624,6 +17096,62 @@ quick-format-unescaped@^4.0.3: resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== +radix-ui@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/radix-ui/-/radix-ui-1.2.0.tgz#076f3a01d1463e048b27c8c3b53f42625f342e3e" + integrity sha512-05auM88p3yNwAarx3JQGnRHbtzDNATbMx6/Qkr2gXg5QNLPUjdeduJvlhhVzlGxfUMBnwzYmydUIzAdrOz3J5w== + dependencies: + "@radix-ui/primitive" "1.1.2" + "@radix-ui/react-accessible-icon" "1.1.3" + "@radix-ui/react-accordion" "1.2.4" + "@radix-ui/react-alert-dialog" "1.1.7" + "@radix-ui/react-aspect-ratio" "1.1.3" + "@radix-ui/react-avatar" "1.1.4" + "@radix-ui/react-checkbox" "1.1.5" + "@radix-ui/react-collapsible" "1.1.4" + "@radix-ui/react-collection" "1.1.3" + "@radix-ui/react-compose-refs" "1.1.2" + "@radix-ui/react-context" "1.1.2" + "@radix-ui/react-context-menu" "2.2.7" + "@radix-ui/react-dialog" "1.1.7" + "@radix-ui/react-direction" "1.1.1" + "@radix-ui/react-dismissable-layer" "1.1.6" + "@radix-ui/react-dropdown-menu" "2.1.7" + "@radix-ui/react-focus-guards" "1.1.2" + "@radix-ui/react-focus-scope" "1.1.3" + "@radix-ui/react-form" "0.1.3" + "@radix-ui/react-hover-card" "1.1.7" + "@radix-ui/react-label" "2.1.3" + "@radix-ui/react-menu" "2.1.7" + "@radix-ui/react-menubar" "1.1.7" + "@radix-ui/react-navigation-menu" "1.2.6" + "@radix-ui/react-popover" "1.1.7" + "@radix-ui/react-popper" "1.2.3" + "@radix-ui/react-portal" "1.1.5" + "@radix-ui/react-presence" "1.1.3" + "@radix-ui/react-primitive" "2.0.3" + "@radix-ui/react-progress" "1.1.3" + "@radix-ui/react-radio-group" "1.2.4" + "@radix-ui/react-roving-focus" "1.1.3" + "@radix-ui/react-scroll-area" "1.2.4" + "@radix-ui/react-select" "2.1.7" + "@radix-ui/react-separator" "1.1.3" + "@radix-ui/react-slider" "1.2.4" + "@radix-ui/react-slot" "1.2.0" + "@radix-ui/react-switch" "1.1.4" + "@radix-ui/react-tabs" "1.1.4" + "@radix-ui/react-toast" "1.2.7" + "@radix-ui/react-toggle" "1.1.3" + "@radix-ui/react-toggle-group" "1.1.3" + "@radix-ui/react-toolbar" "1.1.3" + "@radix-ui/react-tooltip" "1.2.0" + "@radix-ui/react-use-callback-ref" "1.1.1" + "@radix-ui/react-use-controllable-state" "1.1.1" + "@radix-ui/react-use-escape-keydown" "1.1.1" + "@radix-ui/react-use-layout-effect" "1.1.1" + "@radix-ui/react-use-size" "1.1.1" + "@radix-ui/react-visually-hidden" "1.1.3" + ramda@^0.27.1: version "0.27.2" resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.27.2.tgz#84463226f7f36dc33592f6f4ed6374c48306c3f1" |