From 35cb2bcf94e90b85f0333db8a4381043e6a52bb0 Mon Sep 17 00:00:00 2001 From: DS Boyce <260543580+ds-boyce@users.noreply.github.com> Date: Thu, 12 Mar 2026 11:35:58 -0700 Subject: [PATCH] Create codemod for updating Toast calls to v2 (#10045) --- .jscodeshift/toast-v2.js | 106 ++++++++++++++++++ src/App.native.tsx | 9 +- src/App.web.tsx | 9 +- src/components/FeedCard.tsx | 6 +- .../PostControls/PostMenu/PostMenuItems.tsx | 26 +++-- .../PostControls/ShareMenu/ShareMenuItems.tsx | 6 +- src/components/PostControls/index.tsx | 14 ++- src/components/ProfileCard.tsx | 10 +- .../SubscribeProfileDialog.tsx | 14 ++- .../ageAssurance/AgeAssuranceAppealDialog.tsx | 6 +- .../dialogs/PostInteractionSettingsDialog.tsx | 6 +- .../dialogs/lists/CreateOrEditListDialog.tsx | 2 +- .../lists/ListAddRemoveUsersDialog.tsx | 12 +- src/components/dms/ActionsWrapper.web.tsx | 12 +- src/components/dms/AfterReportDialog.tsx | 10 +- src/components/dms/ConvoMenu.tsx | 6 +- src/components/dms/LeaveConvoPrompt.tsx | 6 +- src/components/dms/MessageContextMenu.tsx | 16 +-- src/components/dms/MessageProfileButton.tsx | 2 +- src/components/dms/dialogs/NewChatDialog.tsx | 6 +- .../dms/dialogs/ShareViaChatDialog.tsx | 9 +- src/components/hooks/useFollowMethods.ts | 10 +- .../moderation/LabelsOnMeDialog.tsx | 2 +- .../verification/VerificationCreatePrompt.tsx | 2 +- .../verification/VerificationRemovePrompt.tsx | 6 +- src/features/liveNow/index.tsx | 2 +- src/lib/hooks/useAccountSwitcher.ts | 16 ++- src/lib/media/picker.shared.ts | 6 +- src/lib/sharing.ts | 10 +- src/screens/List/ListHiddenScreen.tsx | 2 +- src/screens/Login/ChooseAccountForm.tsx | 2 +- src/screens/Messages/Inbox.tsx | 18 ++- src/screens/Messages/Settings.tsx | 6 +- .../Messages/components/ChatDisabled.tsx | 6 +- .../Messages/components/MessageInput.tsx | 6 +- .../Messages/components/MessageInput.web.tsx | 6 +- .../Messages/components/RequestButtons.tsx | 26 +++-- .../ModerationInteractionSettings/index.tsx | 2 +- .../ThreadItemAnchorFollowButton.tsx | 10 +- .../Profile/Header/EditProfileDialog.tsx | 2 +- .../Profile/components/ProfileFeedHeader.tsx | 14 ++- src/screens/SavedFeeds.tsx | 10 +- src/screens/Settings/AboutSettings.tsx | 2 +- src/screens/Settings/AppPasswords.tsx | 2 +- src/screens/Settings/InterestsSettings.tsx | 6 +- src/screens/Settings/Settings.tsx | 7 +- .../components/DisableEmail2FADialog.tsx | 2 +- src/screens/Settings/components/OTAInfo.tsx | 6 +- src/screens/StarterPack/StarterPackScreen.tsx | 14 ++- src/screens/StarterPack/Wizard/State.tsx | 10 +- src/screens/StarterPack/Wizard/index.tsx | 10 +- src/state/queries/activity-subscriptions.ts | 2 +- src/state/queries/notifications/settings.ts | 6 +- src/state/queries/pinned-post.ts | 2 +- src/state/shell/composer/index.tsx | 9 +- .../composer/videos/SubtitleFilePicker.tsx | 2 +- .../com/composer/videos/VideoPreview.web.tsx | 6 +- .../notifications/NotificationFeedItem.tsx | 10 +- src/view/com/posts/FeedShutdownMsg.tsx | 10 +- src/view/com/profile/ProfileMenu.tsx | 26 +++-- src/view/screens/Debug.tsx | 2 +- src/view/screens/Storybook/Settings.tsx | 2 +- 62 files changed, 422 insertions(+), 171 deletions(-) create mode 100644 .jscodeshift/toast-v2.js diff --git a/.jscodeshift/toast-v2.js b/.jscodeshift/toast-v2.js new file mode 100644 index 0000000000..a60f2da4ab --- /dev/null +++ b/.jscodeshift/toast-v2.js @@ -0,0 +1,106 @@ +/** + * Codemod to replace namespaced React calls with named imports + * + * Before: + * import * as Toast from '#/view/com/util/Toast' + * Toast.show(message, 'xmark') + * + * After: + * import * as Toast from '#/components/Toast' + * Toast.show(message, {type: 'error'}) + * + * Usage: jscodeshift -t .jscodeshift/toast-v2.js + * Example: jscodeshift -t .jscodeshift/toast-v2.js src/App.native.tsx + */ + +/* eslint-disable */ + +export const parser = 'tsx' + +const OLD_IMPORT = '#/view/com/util/Toast' +const NEW_IMPORT = '#/components/Toast' + +const convertLegacyToastType = type => { + switch (type) { + // these ones are fine + case 'default': + case 'success': + case 'error': + case 'warning': + case 'info': + return type + // legacy ones need conversion + case 'xmark': + return 'error' + case 'exclamation-circle': + return 'warning' + case 'check': + return 'success' + case 'clipboard-check': + return 'success' + case 'circle-exclamation': + case 'exclamation-circle': + return 'warning' + default: + return 'default' + } +} + +export default function transformer(file, api) { + const j = api.jscodeshift + const root = j(file.source) + + // Find Toast import declarations using the old path + const toastImports = root + .find(j.ImportDeclaration) + .filter(path => path.value.source.value === OLD_IMPORT) + + if (toastImports.length === 0) { + return file.source + } + + // Update import path + toastImports.forEach(path => { + path.value.source.value = NEW_IMPORT + }) + + // Collect all local names the Toast namespace is bound to + const toastLocalNames = new Set() + toastImports.forEach(path => { + path.value.specifiers.forEach(spec => { + if (spec.type === 'ImportNamespaceSpecifier') { + toastLocalNames.add(spec.local.name) + } + }) + }) + + // Transform Toast.show(message, type) calls + root.find(j.CallExpression).forEach(path => { + const {callee, arguments: args} = path.value + + // Match .show(...) + if ( + callee.type !== 'MemberExpression' || + callee.object.type !== 'Identifier' || + !toastLocalNames.has(callee.object.name) || + callee.property.name !== 'show' + ) { + return + } + + // Only transform 2-arg calls where the second arg is a string literal + if (args.length !== 2) return + const typeArg = args[1] + if (typeArg.type !== 'StringLiteral' && typeArg.type !== 'Literal') return + + const legacyType = typeArg.value + const newType = convertLegacyToastType(legacyType) + + // Replace the second argument with an options object: {type: 'newType'} + args[1] = j.objectExpression([ + j.property('init', j.identifier('type'), j.stringLiteral(newType)), + ]) + }) + + return root.toSource() +} diff --git a/src/App.native.tsx b/src/App.native.tsx index 3699cb173d..6f6a2220c9 100644 --- a/src/App.native.tsx +++ b/src/App.native.tsx @@ -58,7 +58,6 @@ import {Provider as SelectedFeedProvider} from '#/state/shell/selected-feed' import {Provider as StarterPackProvider} from '#/state/shell/starter-pack' import {Provider as HiddenRepliesProvider} from '#/state/threadgate-hidden-replies' import {TestCtrls} from '#/view/com/testing/TestCtrls' -import * as Toast from '#/view/com/util/Toast' import {Shell} from '#/view/shell' import {ThemeProvider as Alf} from '#/alf' import {useColorModeTheme} from '#/alf/util/useColorModeTheme' @@ -68,6 +67,7 @@ import {Provider as IntentDialogProvider} from '#/components/intents/IntentDialo import {Provider as PolicyUpdateOverlayProvider} from '#/components/PolicyUpdateOverlay' import {Provider as PortalProvider} from '#/components/Portal' import {Provider as VideoVolumeProvider} from '#/components/Post/Embed/VideoEmbed/VideoVolumeContext' +import * as Toast from '#/components/Toast' import {ToastOutlet} from '#/components/Toast' import { prefetchAgeAssuranceConfig, @@ -139,10 +139,9 @@ function InnerApp() { useEffect(() => { return listenSessionDropped(() => { - Toast.show( - _(msg`Sorry! Your session expired. Please sign in again.`), - 'info', - ) + Toast.show(_(msg`Sorry! Your session expired. Please sign in again.`), { + type: 'info', + }) }) }, [_]) diff --git a/src/App.web.tsx b/src/App.web.tsx index 34225bab62..8b6abdc3f3 100644 --- a/src/App.web.tsx +++ b/src/App.web.tsx @@ -47,7 +47,6 @@ import {Provider as ProgressGuideProvider} from '#/state/shell/progress-guide' import {Provider as SelectedFeedProvider} from '#/state/shell/selected-feed' import {Provider as StarterPackProvider} from '#/state/shell/starter-pack' import {Provider as HiddenRepliesProvider} from '#/state/threadgate-hidden-replies' -import * as Toast from '#/view/com/util/Toast' import {Shell} from '#/view/shell/index' import {ThemeProvider as Alf} from '#/alf' import {useColorModeTheme} from '#/alf/util/useColorModeTheme' @@ -58,6 +57,7 @@ import {Provider as PolicyUpdateOverlayProvider} from '#/components/PolicyUpdate import {Provider as PortalProvider} from '#/components/Portal' import {Provider as ActiveVideoProvider} from '#/components/Post/Embed/VideoEmbed/ActiveVideoWebContext' import {Provider as VideoVolumeProvider} from '#/components/Post/Embed/VideoEmbed/VideoVolumeContext' +import * as Toast from '#/components/Toast' import {ToastOutlet} from '#/components/Toast' import { prefetchAgeAssuranceConfig, @@ -115,10 +115,9 @@ function InnerApp() { useEffect(() => { return listenSessionDropped(() => { - Toast.show( - _(msg`Sorry! Your session expired. Please sign in again.`), - 'info', - ) + Toast.show(_(msg`Sorry! Your session expired. Please sign in again.`), { + type: 'info', + }) }) }, [_]) diff --git a/src/components/FeedCard.tsx b/src/components/FeedCard.tsx index 8c087d17e7..efd14be4ba 100644 --- a/src/components/FeedCard.tsx +++ b/src/components/FeedCard.tsx @@ -18,7 +18,6 @@ import { useRemoveFeedMutation, } from '#/state/queries/preferences' import {useSession} from '#/state/session' -import * as Toast from '#/view/com/util/Toast' import {UserAvatar} from '#/view/com/util/UserAvatar' import {atoms as a, select, useTheme} from '#/alf' import { @@ -33,6 +32,7 @@ import {Link as InternalLink, type LinkProps} from '#/components/Link' import {Loader} from '#/components/Loader' import * as Prompt from '#/components/Prompt' import {RichText, type RichTextProps} from '#/components/RichText' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {useActiveLiveEventFeedUris} from '#/features/liveEvents/context' import type * as bsky from '#/types/bsky' @@ -313,7 +313,9 @@ function SaveButtonInner({ Toast.show(l({message: 'Feeds updated!', context: 'toast'})) } catch (err: any) { logger.error(err, {message: `FeedCard: failed to update feeds`, pin}) - Toast.show(l`Failed to update feeds`, 'xmark') + Toast.show(l`Failed to update feeds`, { + type: 'error', + }) } }, [l, pin, saveFeeds, removeFeed, uri, savedFeedConfig, type], diff --git a/src/components/PostControls/PostMenu/PostMenuItems.tsx b/src/components/PostControls/PostMenu/PostMenuItems.tsx index d2d0d9ad5e..6fe8692d20 100644 --- a/src/components/PostControls/PostMenu/PostMenuItems.tsx +++ b/src/components/PostControls/PostMenu/PostMenuItems.tsx @@ -56,7 +56,6 @@ import { } from '#/state/queries/threadgate' import {useRequireAuth, useSession} from '#/state/session' import {useMergedThreadgateHiddenReplies} from '#/state/threadgate-hidden-replies' -import * as Toast from '#/view/com/util/Toast' import {useDialogControl} from '#/components/Dialog' import {useGlobalDialogsControlContext} from '#/components/dialogs/Context' import { @@ -93,6 +92,7 @@ import { useReportDialogControl, } from '#/components/moderation/ReportDialog' import * as Prompt from '#/components/Prompt' +import * as Toast from '#/components/Toast' import {useAnalytics} from '#/analytics' import {IS_INTERNAL} from '#/env' import * as bsky from '#/types/bsky' @@ -216,7 +216,9 @@ let PostMenuItems = ({ }, e => { logger.error('Failed to delete post', {message: e}) - Toast.show(l`Failed to delete post, please try again`, 'xmark') + Toast.show(l`Failed to delete post, please try again`, { + type: 'error', + }) }, ) } @@ -246,7 +248,9 @@ let PostMenuItems = ({ const e = err as Error if (e?.name !== 'AbortError') { logger.error('Failed to toggle thread mute', {message: e}) - Toast.show(l`Failed to toggle thread mute, please try again`, 'xmark') + Toast.show(l`Failed to toggle thread mute, please try again`, { + type: 'error', + }) } } } @@ -265,7 +269,9 @@ let PostMenuItems = ({ const str = richTextToString(richText, true) void Clipboard.setStringAsync(str) - Toast.show(l`Copied to clipboard`, 'clipboard-check') + Toast.show(l`Copied to clipboard`, { + type: 'success', + }) } const onPressTranslate = () => { @@ -434,7 +440,9 @@ let PostMenuItems = ({ const e = err as Error if (e?.name !== 'AbortError') { logger.error('Failed to block account', {message: e}) - Toast.show(l`There was an issue! ${e.toString()}`, 'xmark') + Toast.show(l`There was an issue! ${e.toString()}`, { + type: 'error', + }) } } finally { ax.metric('postMenu:blockAccount', { @@ -455,7 +463,9 @@ let PostMenuItems = ({ const e = err as Error if (e?.name !== 'AbortError') { logger.error('Failed to unmute account', {message: e}) - Toast.show(l`There was an issue! ${e.toString()}`, 'xmark') + Toast.show(l`There was an issue! ${e.toString()}`, { + type: 'error', + }) } } finally { ax.metric('postMenu:unmuteAccount', { @@ -473,7 +483,9 @@ let PostMenuItems = ({ const e = err as Error if (e?.name !== 'AbortError') { logger.error('Failed to mute account', {message: e}) - Toast.show(l`There was an issue! ${e.toString()}`, 'xmark') + Toast.show(l`There was an issue! ${e.toString()}`, { + type: 'error', + }) } } finally { ax.metric('postMenu:muteAccount', { diff --git a/src/components/PostControls/ShareMenu/ShareMenuItems.tsx b/src/components/PostControls/ShareMenu/ShareMenuItems.tsx index f4ea3b0cd7..8cdfe1a93d 100644 --- a/src/components/PostControls/ShareMenu/ShareMenuItems.tsx +++ b/src/components/PostControls/ShareMenu/ShareMenuItems.tsx @@ -12,7 +12,6 @@ import {shareText, shareUrl} from '#/lib/sharing' import {toShareUrl} from '#/lib/strings/url-helpers' import {useProfileShadow} from '#/state/cache/profile-shadow' import {useSession} from '#/state/session' -import * as Toast from '#/view/com/util/Toast' import {atoms as a} from '#/alf' import {Admonition} from '#/components/Admonition' import {useDialogControl} from '#/components/Dialog' @@ -22,6 +21,7 @@ import {ChainLink_Stroke2_Corner0_Rounded as ChainLinkIcon} from '#/components/i import {Clipboard_Stroke2_Corner2_Rounded as ClipboardIcon} from '#/components/icons/Clipboard' import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlaneIcon} from '#/components/icons/PaperPlane' import * as Menu from '#/components/Menu' +import * as Toast from '#/components/Toast' import {useAgeAssurance} from '#/ageAssurance' import {useAnalytics} from '#/analytics' import {IS_IOS} from '#/env' @@ -71,7 +71,9 @@ let ShareMenuItems = ({ } else { await ExpoClipboard.setStringAsync(url) } - Toast.show(_(msg`Copied to clipboard`), 'clipboard-check') + Toast.show(_(msg`Copied to clipboard`), { + type: 'success', + }) onShareProp() } diff --git a/src/components/PostControls/index.tsx b/src/components/PostControls/index.tsx index 43f99b5979..8da129e08b 100644 --- a/src/components/PostControls/index.tsx +++ b/src/components/PostControls/index.tsx @@ -24,11 +24,11 @@ import { ProgressGuideAction, useProgressGuideControls, } from '#/state/shell/progress-guide' -import * as Toast from '#/view/com/util/Toast' import {atoms as a, useBreakpoints} from '#/alf' import {Reply as Bubble} from '#/components/icons/Reply' import {useFormatPostStatCount} from '#/components/PostControls/util' import * as Skele from '#/components/Skeleton' +import * as Toast from '#/components/Toast' import {useAnalytics} from '#/analytics' import {BookmarkButton} from './BookmarkButton' import { @@ -106,7 +106,9 @@ let PostControls = ({ const onPressToggleLike = async () => { if (isBlocked) { - Toast.show(l`Cannot interact with a blocked user`, 'exclamation-circle') + Toast.show(l`Cannot interact with a blocked user`, { + type: 'warning', + }) return } @@ -135,7 +137,9 @@ let PostControls = ({ const onRepost = async () => { if (isBlocked) { - Toast.show(l`Cannot interact with a blocked user`, 'exclamation-circle') + Toast.show(l`Cannot interact with a blocked user`, { + type: 'warning', + }) return } @@ -161,7 +165,9 @@ let PostControls = ({ const onQuote = () => { if (isBlocked) { - Toast.show(l`Cannot interact with a blocked user`, 'exclamation-circle') + Toast.show(l`Cannot interact with a blocked user`, { + type: 'warning', + }) return } diff --git a/src/components/ProfileCard.tsx b/src/components/ProfileCard.tsx index ee9e657028..15f288089f 100644 --- a/src/components/ProfileCard.tsx +++ b/src/components/ProfileCard.tsx @@ -22,7 +22,6 @@ import {sanitizeHandle} from '#/lib/strings/handles' import {useProfileShadow} from '#/state/cache/profile-shadow' import {useProfileFollowMutationQueue} from '#/state/queries/profile' import {useSession} from '#/state/session' -import * as Toast from '#/view/com/util/Toast' import {PreviewableUserAvatar, UserAvatar} from '#/view/com/util/UserAvatar' import { atoms as a, @@ -43,6 +42,7 @@ import {Link as InternalLink, type LinkProps} from '#/components/Link' import * as Pills from '#/components/Pills' import {ProfileBadges} from '#/components/ProfileBadges' import {RichText} from '#/components/RichText' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {type Metrics} from '#/analytics' import {useActorStatus} from '#/features/liveNow' @@ -504,7 +504,9 @@ export function FollowButtonInner({ } catch (e) { const err = e as Error if (err?.name !== 'AbortError') { - Toast.show(l`An issue occurred, please try again.`, 'xmark') + Toast.show(l`An issue occurred, please try again.`, { + type: 'error', + }) } } } @@ -524,7 +526,9 @@ export function FollowButtonInner({ } catch (e) { const err = e as Error if (err?.name !== 'AbortError') { - Toast.show(l`An issue occurred, please try again.`, 'xmark') + Toast.show(l`An issue occurred, please try again.`, { + type: 'error', + }) } } } diff --git a/src/components/activity-notifications/SubscribeProfileDialog.tsx b/src/components/activity-notifications/SubscribeProfileDialog.tsx index 6e878353ac..8a6b8314cd 100644 --- a/src/components/activity-notifications/SubscribeProfileDialog.tsx +++ b/src/components/activity-notifications/SubscribeProfileDialog.tsx @@ -21,7 +21,6 @@ import {sanitizeHandle} from '#/lib/strings/handles' import {updateProfileShadow} from '#/state/cache/profile-shadow' import {RQKEY_getActivitySubscriptions} from '#/state/queries/activity-subscriptions' import {useAgent} from '#/state/session' -import * as Toast from '#/view/com/util/Toast' import {atoms as a, platform, useTheme, web} from '#/alf' import {Admonition} from '#/components/Admonition' import { @@ -34,6 +33,7 @@ import * as Dialog from '#/components/Dialog' import * as Toggle from '#/components/forms/Toggle' import {Loader} from '#/components/Loader' import * as ProfileCard from '#/components/ProfileCard' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' import {IS_WEB} from '#/env' @@ -139,7 +139,9 @@ function DialogInner({ _( msg`You will no longer receive notifications for ${sanitizeHandle(profile.handle, '@')}`, ), - 'check', + { + type: 'success', + }, ) // filter out the subscription @@ -169,10 +171,14 @@ function DialogInner({ _( msg`You'll start receiving notifications for ${sanitizeHandle(profile.handle, '@')}!`, ), - 'check', + { + type: 'success', + }, ) } else { - Toast.show(_(msg`Changes saved`), 'check') + Toast.show(_(msg`Changes saved`), { + type: 'success', + }) } } }) diff --git a/src/components/ageAssurance/AgeAssuranceAppealDialog.tsx b/src/components/ageAssurance/AgeAssuranceAppealDialog.tsx index abbb626236..1ee126eb28 100644 --- a/src/components/ageAssurance/AgeAssuranceAppealDialog.tsx +++ b/src/components/ageAssurance/AgeAssuranceAppealDialog.tsx @@ -8,12 +8,12 @@ import {useMutation} from '@tanstack/react-query' import {BLUESKY_MOD_SERVICE_HEADERS} from '#/lib/constants' import {useAgent, useSession} from '#/state/session' -import * as Toast from '#/view/com/util/Toast' import {atoms as a, useBreakpoints, web} from '#/alf' import {AgeAssuranceBadge} from '#/components/ageAssurance/AgeAssuranceBadge' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' import {Loader} from '#/components/Loader' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {logger} from '#/ageAssurance' import {useAnalytics} from '#/analytics' @@ -70,7 +70,9 @@ function Inner({control}: {control: Dialog.DialogControlProps}) { logger.error('AgeAssuranceAppealDialog failed', {safeMessage: err}) Toast.show( _(msg`Age assurance inquiry failed to send, please try again.`), - 'xmark', + { + type: 'error', + }, ) }, onSuccess: () => { diff --git a/src/components/dialogs/PostInteractionSettingsDialog.tsx b/src/components/dialogs/PostInteractionSettingsDialog.tsx index a49ccc7316..8a5c7101cc 100644 --- a/src/components/dialogs/PostInteractionSettingsDialog.tsx +++ b/src/components/dialogs/PostInteractionSettingsDialog.tsx @@ -37,7 +37,6 @@ import { usePostThreadContext, } from '#/state/queries/usePostThread' import {useAgent, useSession} from '#/state/session' -import * as Toast from '#/view/com/util/Toast' import {UserAvatar} from '#/view/com/util/UserAvatar' import {atoms as a, useTheme, web} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' @@ -50,6 +49,7 @@ import { import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo' import {CloseQuote_Stroke2_Corner1_Rounded as QuoteIcon} from '#/components/icons/Quote' import {Loader} from '#/components/Loader' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' import {IS_IOS} from '#/env' @@ -240,7 +240,9 @@ export function PostInteractionSettingsDialogControlledInner( _( msg`There was an issue. Please check your internet connection and try again.`, ), - 'xmark', + { + type: 'error', + }, ) } finally { setIsSaving(false) diff --git a/src/components/dialogs/lists/CreateOrEditListDialog.tsx b/src/components/dialogs/lists/CreateOrEditListDialog.tsx index 213426eaaf..7164c3ebeb 100644 --- a/src/components/dialogs/lists/CreateOrEditListDialog.tsx +++ b/src/components/dialogs/lists/CreateOrEditListDialog.tsx @@ -17,7 +17,6 @@ import { } from '#/state/queries/list' import {useAgent} from '#/state/session' import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' -import * as Toast from '#/view/com/util/Toast' import {EditableUserAvatar} from '#/view/com/util/UserAvatar' import {atoms as a, useTheme, web} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' @@ -25,6 +24,7 @@ import * as Dialog from '#/components/Dialog' import * as TextField from '#/components/forms/TextField' import {Loader} from '#/components/Loader' import * as Prompt from '#/components/Prompt' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {IS_WEB} from '#/env' diff --git a/src/components/dialogs/lists/ListAddRemoveUsersDialog.tsx b/src/components/dialogs/lists/ListAddRemoveUsersDialog.tsx index ae82c4259a..da96565655 100644 --- a/src/components/dialogs/lists/ListAddRemoveUsersDialog.tsx +++ b/src/components/dialogs/lists/ListAddRemoveUsersDialog.tsx @@ -14,7 +14,6 @@ import { useListMembershipAddMutation, useListMembershipRemoveMutation, } from '#/state/queries/list-memberships' -import * as Toast from '#/view/com/util/Toast' import {atoms as a} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' @@ -24,6 +23,7 @@ import { } from '#/components/dialogs/SearchablePeopleList' import {Loader} from '#/components/Loader' import * as ProfileCard from '#/components/ProfileCard' +import * as Toast from '#/components/Toast' import type * as bsky from '#/types/bsky' export function ListAddRemoveUsersDialog({ @@ -113,7 +113,10 @@ function UserResult({ Toast.show(_(msg`Added to list`)) onChange?.('add', profile) }, - onError: e => Toast.show(cleanError(e), 'xmark'), + onError: e => + Toast.show(cleanError(e), { + type: 'error', + }), }) const {mutate: listMembershipRemove, isPending: isRemovingPending} = useListMembershipRemoveMutation({ @@ -121,7 +124,10 @@ function UserResult({ Toast.show(_(msg`Removed from list`)) onChange?.('remove', profile) }, - onError: e => Toast.show(cleanError(e), 'xmark'), + onError: e => + Toast.show(cleanError(e), { + type: 'error', + }), }) const isMutating = isAddingPending || isRemovingPending diff --git a/src/components/dms/ActionsWrapper.web.tsx b/src/components/dms/ActionsWrapper.web.tsx index 6b95e7fbaa..beb6577e0f 100644 --- a/src/components/dms/ActionsWrapper.web.tsx +++ b/src/components/dms/ActionsWrapper.web.tsx @@ -6,11 +6,11 @@ import {useLingui} from '@lingui/react' import {useConvoActive} from '#/state/messages/convo' import {useSession} from '#/state/session' -import * as Toast from '#/view/com/util/Toast' import {atoms as a, useTheme} from '#/alf' import {MessageContextMenu} from '#/components/dms/MessageContextMenu' import {DotGrid3x1_Stroke2_Corner0_Rounded as DotsHorizontalIcon} from '#/components/icons/DotGrid' import {EmojiSmile_Stroke2_Corner0_Rounded as EmojiSmileIcon} from '#/components/icons/Emoji' +import * as Toast from '#/components/Toast' import {EmojiReactionPicker} from './EmojiReactionPicker' import {hasReachedReactionLimit} from './util' @@ -60,11 +60,11 @@ export function ActionsWrapper({ .catch(() => Toast.show(_(msg`Failed to remove emoji reaction`))) } else { if (hasReachedReactionLimit(message, currentAccount?.did)) return - convo - .addReaction(message.id, emoji) - .catch(() => - Toast.show(_(msg`Failed to add emoji reaction`), 'xmark'), - ) + convo.addReaction(message.id, emoji).catch(() => + Toast.show(_(msg`Failed to add emoji reaction`), { + type: 'error', + }), + ) } }, [_, convo, message, currentAccount?.did], diff --git a/src/components/dms/AfterReportDialog.tsx b/src/components/dms/AfterReportDialog.tsx index b58013ee5a..d851037e45 100644 --- a/src/components/dms/AfterReportDialog.tsx +++ b/src/components/dms/AfterReportDialog.tsx @@ -13,12 +13,12 @@ import { useProfileBlockMutationQueue, useProfileQuery, } from '#/state/queries/profile' -import * as Toast from '#/view/com/util/Toast' import {atoms as a, platform, useBreakpoints, useTheme, web} from '#/alf' import {Button, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' import * as Toggle from '#/components/forms/Toggle' import {Loader} from '#/components/Loader' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {IS_NATIVE} from '#/env' @@ -135,7 +135,9 @@ function DoneStep({ } }, onError: () => { - Toast.show(_(msg`Could not leave chat`), 'xmark') + Toast.show(_(msg`Could not leave chat`), { + type: 'error', + }) }, }) @@ -161,7 +163,9 @@ function DoneStep({ leaveConvo() } if (toastMsg) { - Toast.show(toastMsg, 'check') + Toast.show(toastMsg, { + type: 'success', + }) } }) } diff --git a/src/components/dms/ConvoMenu.tsx b/src/components/dms/ConvoMenu.tsx index 5332021c00..ae9a4a3c4a 100644 --- a/src/components/dms/ConvoMenu.tsx +++ b/src/components/dms/ConvoMenu.tsx @@ -18,7 +18,6 @@ import { unstableCacheProfileView, useProfileBlockMutationQueue, } from '#/state/queries/profile' -import * as Toast from '#/view/com/util/Toast' import {type ViewStyleProp} from '#/alf' import {atoms as a} from '#/alf' import {Button, ButtonIcon} from '#/components/Button' @@ -40,6 +39,7 @@ import {SpeakerVolumeFull_Stroke2_Corner0_Rounded as Unmute} from '#/components/ import * as Menu from '#/components/Menu' import {ReportDialog} from '#/components/moderation/ReportDialog' import * as Prompt from '#/components/Prompt' +import * as Toast from '#/components/Toast' import type * as bsky from '#/types/bsky' let ConvoMenu = ({ @@ -205,7 +205,9 @@ function MenuContent({ } }, onError: () => { - Toast.show(_(msg`Could not mute chat`), 'xmark') + Toast.show(_(msg`Could not mute chat`), { + type: 'error', + }) }, }) diff --git a/src/components/dms/LeaveConvoPrompt.tsx b/src/components/dms/LeaveConvoPrompt.tsx index 44fb6d6572..b000040455 100644 --- a/src/components/dms/LeaveConvoPrompt.tsx +++ b/src/components/dms/LeaveConvoPrompt.tsx @@ -4,9 +4,9 @@ import {StackActions, useNavigation} from '@react-navigation/native' import {type NavigationProp} from '#/lib/routes/types' import {useLeaveConvo} from '#/state/queries/messages/leave-conversation' -import * as Toast from '#/view/com/util/Toast' import {type DialogOuterProps} from '#/components/Dialog' import * as Prompt from '#/components/Prompt' +import * as Toast from '#/components/Toast' import {IS_NATIVE} from '#/env' export function LeaveConvoPrompt({ @@ -32,7 +32,9 @@ export function LeaveConvoPrompt({ } }, onError: () => { - Toast.show(_(msg`Could not leave chat`), 'xmark') + Toast.show(_(msg`Could not leave chat`), { + type: 'error', + }) }, }) diff --git a/src/components/dms/MessageContextMenu.tsx b/src/components/dms/MessageContextMenu.tsx index ea5b4a48b3..dd48eda127 100644 --- a/src/components/dms/MessageContextMenu.tsx +++ b/src/components/dms/MessageContextMenu.tsx @@ -12,7 +12,6 @@ import {useConvoActive} from '#/state/messages/convo' import {useLanguagePrefs} from '#/state/preferences' import {unstableCacheProfileView} from '#/state/queries/unstable-profile-cache' import {useSession} from '#/state/session' -import * as Toast from '#/view/com/util/Toast' import * as ContextMenu from '#/components/ContextMenu' import {type TriggerProps} from '#/components/ContextMenu/types' import {AfterReportDialog} from '#/components/dms/AfterReportDialog' @@ -23,6 +22,7 @@ import {Warning_Stroke2_Corner0_Rounded as Warning} from '#/components/icons/War import {ReportDialog} from '#/components/moderation/ReportDialog' import * as Prompt from '#/components/Prompt' import {usePromptControl} from '#/components/Prompt' +import * as Toast from '#/components/Toast' import {useAnalytics} from '#/analytics' import {IS_NATIVE} from '#/env' import {EmojiReactionPicker} from './EmojiReactionPicker' @@ -58,7 +58,9 @@ export let MessageContextMenu = ({ ) void Clipboard.setStringAsync(str) - Toast.show(_(msg`Copied to clipboard`), 'clipboard-check') + Toast.show(_(msg`Copied to clipboard`), { + type: 'success', + }) }, [_, message.text, message.facets]) const onPressTranslateMessage = useCallback(() => { @@ -95,11 +97,11 @@ export let MessageContextMenu = ({ .catch(() => Toast.show(_(msg`Failed to remove emoji reaction`))) } else { if (hasReachedReactionLimit(message, currentAccount?.did)) return - convo - .addReaction(message.id, emoji) - .catch(() => - Toast.show(_(msg`Failed to add emoji reaction`), 'xmark'), - ) + convo.addReaction(message.id, emoji).catch(() => + Toast.show(_(msg`Failed to add emoji reaction`), { + type: 'error', + }), + ) } }, [_, convo, message, currentAccount?.did], diff --git a/src/components/dms/MessageProfileButton.tsx b/src/components/dms/MessageProfileButton.tsx index 9a0d93b38a..ede352218b 100644 --- a/src/components/dms/MessageProfileButton.tsx +++ b/src/components/dms/MessageProfileButton.tsx @@ -10,11 +10,11 @@ import {useRequireEmailVerification} from '#/lib/hooks/useRequireEmailVerificati import {type NavigationProp} from '#/lib/routes/types' import {useGetConvoAvailabilityQuery} from '#/state/queries/messages/get-convo-availability' import {useGetConvoForMembers} from '#/state/queries/messages/get-convo-for-members' -import * as Toast from '#/view/com/util/Toast' import {atoms as a, useTheme} from '#/alf' import {Button, ButtonIcon} from '#/components/Button' import {canBeMessaged} from '#/components/dms/util' import {Message_Stroke2_Corner0_Rounded as Message} from '#/components/icons/Message' +import * as Toast from '#/components/Toast' import {useAnalytics} from '#/analytics' export function MessageProfileButton({ diff --git a/src/components/dms/dialogs/NewChatDialog.tsx b/src/components/dms/dialogs/NewChatDialog.tsx index 9c349d0a0d..e934027046 100644 --- a/src/components/dms/dialogs/NewChatDialog.tsx +++ b/src/components/dms/dialogs/NewChatDialog.tsx @@ -7,11 +7,11 @@ import {useRequireEmailVerification} from '#/lib/hooks/useRequireEmailVerificati import {logger} from '#/logger' import {useGetConvoForMembers} from '#/state/queries/messages/get-convo-for-members' import {FAB} from '#/view/com/util/fab/FAB' -import * as Toast from '#/view/com/util/Toast' import {useTheme} from '#/alf' import * as Dialog from '#/components/Dialog' import {SearchablePeopleList} from '#/components/dialogs/SearchablePeopleList' import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus' +import * as Toast from '#/components/Toast' import {useAnalytics} from '#/analytics' export function NewChat({ @@ -37,7 +37,9 @@ export function NewChat({ }, onError: error => { logger.error('Failed to create chat', {safeMessage: error}) - Toast.show(_(msg`An issue occurred starting the chat`), 'xmark') + Toast.show(_(msg`An issue occurred starting the chat`), { + type: 'error', + }) }, }) diff --git a/src/components/dms/dialogs/ShareViaChatDialog.tsx b/src/components/dms/dialogs/ShareViaChatDialog.tsx index f738d049ae..faf3545519 100644 --- a/src/components/dms/dialogs/ShareViaChatDialog.tsx +++ b/src/components/dms/dialogs/ShareViaChatDialog.tsx @@ -4,9 +4,9 @@ import {useLingui} from '@lingui/react' import {logger} from '#/logger' import {useGetConvoForMembers} from '#/state/queries/messages/get-convo-for-members' -import * as Toast from '#/view/com/util/Toast' import * as Dialog from '#/components/Dialog' import {SearchablePeopleList} from '#/components/dialogs/SearchablePeopleList' +import * as Toast from '#/components/Toast' import {useAnalytics} from '#/analytics' export function SendViaChatDialog({ @@ -47,10 +47,9 @@ function SendViaChatDialogInner({ }, onError: error => { logger.error('Failed to share post to chat', {message: error}) - Toast.show( - _(msg`An issue occurred while trying to open the chat`), - 'xmark', - ) + Toast.show(_(msg`An issue occurred while trying to open the chat`), { + type: 'error', + }) }, }) diff --git a/src/components/hooks/useFollowMethods.ts b/src/components/hooks/useFollowMethods.ts index 4617ff83a2..cb9cdaa245 100644 --- a/src/components/hooks/useFollowMethods.ts +++ b/src/components/hooks/useFollowMethods.ts @@ -6,7 +6,7 @@ import {logger} from '#/logger' import {type Shadow} from '#/state/cache/types' import {useProfileFollowMutationQueue} from '#/state/queries/profile' import {useRequireAuth} from '#/state/session' -import * as Toast from '#/view/com/util/Toast' +import * as Toast from '#/components/Toast' import {type Metrics} from '#/analytics/metrics' import type * as bsky from '#/types/bsky' @@ -32,7 +32,9 @@ export function useFollowMethods({ } catch (e: any) { logger.error(`useFollowMethods: failed to follow`, {message: String(e)}) if (e?.name !== 'AbortError') { - Toast.show(_(msg`An issue occurred, please try again.`), 'xmark') + Toast.show(_(msg`An issue occurred, please try again.`), { + type: 'error', + }) } } }) @@ -47,7 +49,9 @@ export function useFollowMethods({ message: String(e), }) if (e?.name !== 'AbortError') { - Toast.show(_(msg`An issue occurred, please try again.`), 'xmark') + Toast.show(_(msg`An issue occurred, please try again.`), { + type: 'error', + }) } } }) diff --git a/src/components/moderation/LabelsOnMeDialog.tsx b/src/components/moderation/LabelsOnMeDialog.tsx index 7583905d87..c750079d1e 100644 --- a/src/components/moderation/LabelsOnMeDialog.tsx +++ b/src/components/moderation/LabelsOnMeDialog.tsx @@ -14,11 +14,11 @@ import {makeProfileLink} from '#/lib/routes/links' import {sanitizeHandle} from '#/lib/strings/handles' import {logger} from '#/logger' import {useAgent, useSession} from '#/state/session' -import * as Toast from '#/view/com/util/Toast' import {atoms as a, useBreakpoints, useTheme} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' import {InlineLinkText} from '#/components/Link' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {IS_ANDROID} from '#/env' import {Admonition} from '../Admonition' diff --git a/src/components/verification/VerificationCreatePrompt.tsx b/src/components/verification/VerificationCreatePrompt.tsx index 11dcf0c530..b0a87f476e 100644 --- a/src/components/verification/VerificationCreatePrompt.tsx +++ b/src/components/verification/VerificationCreatePrompt.tsx @@ -7,7 +7,6 @@ import {Trans} from '@lingui/react/macro' 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, useBreakpoints} from '#/alf' import {Admonition} from '#/components/Admonition' import {Button, ButtonIcon, ButtonText} from '#/components/Button' @@ -17,6 +16,7 @@ import {VerifiedCheck} from '#/components/icons/VerifiedCheck' import {Loader} from '#/components/Loader' import * as ProfileCard from '#/components/ProfileCard' import * as Prompt from '#/components/Prompt' +import * as Toast from '#/components/Toast' import type * as bsky from '#/types/bsky' export function VerificationCreatePrompt({ diff --git a/src/components/verification/VerificationRemovePrompt.tsx b/src/components/verification/VerificationRemovePrompt.tsx index becee16ebf..96b119ceb1 100644 --- a/src/components/verification/VerificationRemovePrompt.tsx +++ b/src/components/verification/VerificationRemovePrompt.tsx @@ -5,9 +5,9 @@ import {useLingui} from '@lingui/react' import {logger} from '#/logger' import {useVerificationsRemoveMutation} from '#/state/queries/verification/useVerificationsRemoveMutation' -import * as Toast from '#/view/com/util/Toast' import {type DialogControlProps} from '#/components/Dialog' import * as Prompt from '#/components/Prompt' +import * as Toast from '#/components/Toast' import type * as bsky from '#/types/bsky' export {useDialogControl as usePromptControl} from '#/components/Dialog' @@ -31,7 +31,9 @@ export function VerificationRemovePrompt({ await remove({profile, verifications}) Toast.show(_(msg`Removed verification`)) } catch (e) { - Toast.show(_(msg`Failed to remove verification`), 'xmark') + Toast.show(_(msg`Failed to remove verification`), { + type: 'error', + }) logger.error('Failed to remove verification', { safeMessage: e, }) diff --git a/src/features/liveNow/index.tsx b/src/features/liveNow/index.tsx index 2c8f27eb61..a7c9192789 100644 --- a/src/features/liveNow/index.tsx +++ b/src/features/liveNow/index.tsx @@ -23,8 +23,8 @@ import { } from '#/state/cache/profile-shadow' import {useAgent, useSession} from '#/state/session' import {useTickEveryMinute} from '#/state/shell' -import * as Toast from '#/view/com/util/Toast' import {useDialogContext} from '#/components/Dialog' +import * as Toast from '#/components/Toast' import {useAnalytics} from '#/analytics' import {getLiveNowHost, getLiveServiceNames} from '#/features/liveNow/utils' import type * as bsky from '#/types/bsky' diff --git a/src/lib/hooks/useAccountSwitcher.ts b/src/lib/hooks/useAccountSwitcher.ts index 4793eeb4e8..106e92d37a 100644 --- a/src/lib/hooks/useAccountSwitcher.ts +++ b/src/lib/hooks/useAccountSwitcher.ts @@ -5,7 +5,7 @@ import {useLingui} from '@lingui/react' import {logger} from '#/logger' import {type SessionAccount, useSessionApi} from '#/state/session' import {useLoggedOutViewControls} from '#/state/shell/logged-out' -import * as Toast from '#/view/com/util/Toast' +import * as Toast from '#/components/Toast' import {useAnalytics} from '#/analytics' import {type Metrics} from '#/analytics/metrics' import {IS_WEB} from '#/env' @@ -42,20 +42,18 @@ export function useAccountSwitcher() { Toast.show(_(msg`Signed in as @${account.handle}`)) } else { requestSwitchToAccount({requestedAccount: account.did}) - Toast.show( - _(msg`Please sign in as @${account.handle}`), - 'circle-exclamation', - ) + Toast.show(_(msg`Please sign in as @${account.handle}`), { + type: 'warning', + }) } } catch (e: any) { logger.error(`switch account: selectAccount failed`, { message: e.message, }) requestSwitchToAccount({requestedAccount: account.did}) - Toast.show( - _(msg`Please sign in as @${account.handle}`), - 'circle-exclamation', - ) + Toast.show(_(msg`Please sign in as @${account.handle}`), { + type: 'warning', + }) } finally { setPendingDid(null) } diff --git a/src/lib/media/picker.shared.ts b/src/lib/media/picker.shared.ts index 079626ed28..270910e851 100644 --- a/src/lib/media/picker.shared.ts +++ b/src/lib/media/picker.shared.ts @@ -6,7 +6,7 @@ import { import {t} from '@lingui/core/macro' import {type ImageMeta} from '#/state/gallery' -import * as Toast from '#/view/com/util/Toast' +import * as Toast from '#/components/Toast' import {IS_IOS, IS_WEB} from '#/env' import {VIDEO_MAX_DURATION_MS} from '../constants' import {getDataUriSize} from './util' @@ -30,7 +30,9 @@ export async function openPicker(opts?: ImagePickerOptions) { return (response.assets ?? []) .filter(asset => { if (asset.mimeType?.startsWith('image/')) return true - Toast.show(t`Only image files are supported`, 'exclamation-circle') + Toast.show(t`Only image files are supported`, { + type: 'warning', + }) return false }) .map(image => ({ diff --git a/src/lib/sharing.ts b/src/lib/sharing.ts index fe086c7d2a..0efde62d3c 100644 --- a/src/lib/sharing.ts +++ b/src/lib/sharing.ts @@ -3,7 +3,7 @@ import {Share} from 'react-native' import {setStringAsync} from 'expo-clipboard' import {t} from '@lingui/core/macro' -import * as Toast from '#/view/com/util/Toast' +import * as Toast from '#/components/Toast' import {IS_ANDROID, IS_IOS} from '#/env' /** @@ -21,7 +21,9 @@ export async function shareUrl(url: string) { // React Native Share is not supported by web. Web Share API // has increasing but not full support, so default to clipboard setStringAsync(url) - Toast.show(t`Copied to clipboard`, 'clipboard-check') + Toast.show(t`Copied to clipboard`, { + type: 'success', + }) } } @@ -37,6 +39,8 @@ export async function shareText(text: string) { await Share.share({message: text}) } else { await setStringAsync(text) - Toast.show(t`Copied to clipboard`, 'clipboard-check') + Toast.show(t`Copied to clipboard`, { + type: 'success', + }) } } diff --git a/src/screens/List/ListHiddenScreen.tsx b/src/screens/List/ListHiddenScreen.tsx index e313268b31..aea2465d7f 100644 --- a/src/screens/List/ListHiddenScreen.tsx +++ b/src/screens/List/ListHiddenScreen.tsx @@ -19,13 +19,13 @@ import { useRemoveFeedMutation, } from '#/state/queries/preferences' import {useSession} from '#/state/session' -import * as Toast from '#/view/com/util/Toast' import {CenteredView} from '#/view/com/util/Views' import {atoms as a, useBreakpoints, useTheme} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlash} from '#/components/icons/EyeSlash' import {Loader} from '#/components/Loader' import {useHider} from '#/components/moderation/Hider' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' export function ListHiddenScreen({ diff --git a/src/screens/Login/ChooseAccountForm.tsx b/src/screens/Login/ChooseAccountForm.tsx index 86485d814c..041e2e3b22 100644 --- a/src/screens/Login/ChooseAccountForm.tsx +++ b/src/screens/Login/ChooseAccountForm.tsx @@ -7,11 +7,11 @@ import {Trans} from '@lingui/react/macro' import {logger} from '#/logger' import {type SessionAccount, useSession, useSessionApi} from '#/state/session' import {useLoggedOutViewControls} from '#/state/shell/logged-out' -import * as Toast from '#/view/com/util/Toast' import {atoms as a, web} from '#/alf' import {AccountList} from '#/components/AccountList' import {Button, ButtonText} from '#/components/Button' import * as TextField from '#/components/forms/TextField' +import * as Toast from '#/components/Toast' import {useAnalytics} from '#/analytics' import {IS_WEB} from '#/env' import {FormContainer} from './FormContainer' diff --git a/src/screens/Messages/Inbox.tsx b/src/screens/Messages/Inbox.tsx index 9dc9754376..d439f0b1d0 100644 --- a/src/screens/Messages/Inbox.tsx +++ b/src/screens/Messages/Inbox.tsx @@ -30,7 +30,6 @@ import {useUpdateAllRead} from '#/state/queries/messages/update-all-read' import {FAB} from '#/view/com/util/fab/FAB' import {List} from '#/view/com/util/List' import {ChatListLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder' -import * as Toast from '#/view/com/util/Toast' import {atoms as a, useBreakpoints, useTheme} from '#/alf' import {AgeRestrictedScreen} from '#/components/ageAssurance/AgeRestrictedScreen' import {useAgeAssuranceCopy} from '#/components/ageAssurance/useAgeAssuranceCopy' @@ -43,6 +42,7 @@ import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfoIcon} from '#/components import {Message_Stroke2_Corner0_Rounded as MessageIcon} from '#/components/icons/Message' import * as Layout from '#/components/Layout' import {ListFooter} from '#/components/Lists' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {IS_NATIVE} from '#/env' import {RequestListItem} from './components/RequestListItem' @@ -313,10 +313,14 @@ function MarkAllReadFAB() { const t = useTheme() const {mutate: markAllRead} = useUpdateAllRead('request', { onMutate: () => { - Toast.show(_(msg`Marked all as read`), 'check') + Toast.show(_(msg`Marked all as read`), { + type: 'success', + }) }, onError: () => { - Toast.show(_(msg`Failed to mark all requests as read`), 'xmark') + Toast.show(_(msg`Failed to mark all requests as read`), { + type: 'error', + }) }, }) @@ -336,10 +340,14 @@ function MarkAsReadHeaderButton() { const {_} = useLingui() const {mutate: markAllRead} = useUpdateAllRead('request', { onMutate: () => { - Toast.show(_(msg`Marked all as read`), 'check') + Toast.show(_(msg`Marked all as read`), { + type: 'success', + }) }, onError: () => { - Toast.show(_(msg`Failed to mark all requests as read`), 'xmark') + Toast.show(_(msg`Failed to mark all requests as read`), { + type: 'error', + }) }, }) diff --git a/src/screens/Messages/Settings.tsx b/src/screens/Messages/Settings.tsx index 83c68ab10e..12e2fd5c2c 100644 --- a/src/screens/Messages/Settings.tsx +++ b/src/screens/Messages/Settings.tsx @@ -9,12 +9,12 @@ import {type CommonNavigatorParams} from '#/lib/routes/types' import {useUpdateActorDeclaration} from '#/state/queries/messages/actor-declaration' import {useProfileQuery} from '#/state/queries/profile' import {useSession} from '#/state/session' -import * as Toast from '#/view/com/util/Toast' import {atoms as a} from '#/alf' import {Admonition} from '#/components/Admonition' import {Divider} from '#/components/Divider' import * as Toggle from '#/components/forms/Toggle' import * as Layout from '#/components/Layout' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {IS_NATIVE} from '#/env' import {useBackgroundNotificationPreferences} from '../../../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider' @@ -37,7 +37,9 @@ export function MessagesSettingsScreenInner({}: Props) { const {mutate: updateDeclaration} = useUpdateActorDeclaration({ onError: () => { - Toast.show(_(msg`Failed to update settings`), 'xmark') + Toast.show(_(msg`Failed to update settings`), { + type: 'error', + }) }, }) diff --git a/src/screens/Messages/components/ChatDisabled.tsx b/src/screens/Messages/components/ChatDisabled.tsx index f8773c9ac8..51cac2b773 100644 --- a/src/screens/Messages/components/ChatDisabled.tsx +++ b/src/screens/Messages/components/ChatDisabled.tsx @@ -9,11 +9,11 @@ import {useMutation} from '@tanstack/react-query' import {BLUESKY_MOD_SERVICE_HEADERS} from '#/lib/constants' import {logger} from '#/logger' import {useAgent, useSession} from '#/state/session' -import * as Toast from '#/view/com/util/Toast' import {atoms as a, useBreakpoints, useTheme} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' import {Loader} from '#/components/Loader' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' export function ChatDisabled() { @@ -97,7 +97,9 @@ function DialogInner() { }, onError: err => { logger.error('Failed to submit chat appeal', {message: err}) - Toast.show(_(msg`Failed to submit appeal, please try again.`), 'xmark') + Toast.show(_(msg`Failed to submit appeal, please try again.`), { + type: 'error', + }) }, onSuccess: () => { control.close() diff --git a/src/screens/Messages/components/MessageInput.tsx b/src/screens/Messages/components/MessageInput.tsx index c82e7e6d50..f39205bd3b 100644 --- a/src/screens/Messages/components/MessageInput.tsx +++ b/src/screens/Messages/components/MessageInput.tsx @@ -24,10 +24,10 @@ import { useSaveMessageDraft, } from '#/state/messages/message-drafts' 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' import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlane} from '#/components/icons/PaperPlane' +import * as Toast from '#/components/Toast' import {IS_IOS, IS_WEB} from '#/env' import {useExtractEmbedFromFacets} from './MessageInputEmbed' @@ -76,7 +76,9 @@ export function MessageInput({ return } if (countGraphemes(message) > MAX_DM_GRAPHEME_LENGTH) { - Toast.show(_(msg`Message is too long`), 'xmark') + Toast.show(_(msg`Message is too long`), { + type: 'error', + }) return } clearDraft() diff --git a/src/screens/Messages/components/MessageInput.web.tsx b/src/screens/Messages/components/MessageInput.web.tsx index dc20b0ad30..5113027f06 100644 --- a/src/screens/Messages/components/MessageInput.web.tsx +++ b/src/screens/Messages/components/MessageInput.web.tsx @@ -17,12 +17,12 @@ import { type Emoji, type EmojiPickerPosition, } from '#/view/com/composer/text-input/web/EmojiPicker' -import * as Toast from '#/view/com/util/Toast' import {atoms as a, flatten, useTheme} from '#/alf' import {Button} from '#/components/Button' import {useSharedInputStyles} from '#/components/forms/TextField' import {EmojiArc_Stroke2_Corner0_Rounded as EmojiSmile} from '#/components/icons/Emoji' import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlane} from '#/components/icons/PaperPlane' +import * as Toast from '#/components/Toast' import {IS_WEB_SAFARI, IS_WEB_TOUCH_DEVICE} from '#/env' import {useExtractEmbedFromFacets} from './MessageInputEmbed' @@ -57,7 +57,9 @@ export function MessageInput({ return } if (countGraphemes(message) > MAX_DM_GRAPHEME_LENGTH) { - Toast.show(_(msg`Message is too long`), 'xmark') + Toast.show(_(msg`Message is too long`), { + type: 'error', + }) return } clearDraft() diff --git a/src/screens/Messages/components/RequestButtons.tsx b/src/screens/Messages/components/RequestButtons.tsx index 82b5b553f7..5a3b92dbe9 100644 --- a/src/screens/Messages/components/RequestButtons.tsx +++ b/src/screens/Messages/components/RequestButtons.tsx @@ -16,7 +16,6 @@ import { unstableCacheProfileView, useProfileBlockMutationQueue, } from '#/state/queries/profile' -import * as Toast from '#/view/com/util/Toast' import {atoms as a} from '#/alf' import { Button, @@ -36,6 +35,7 @@ import {PersonX_Stroke2_Corner0_Rounded as PersonXIcon} from '#/components/icons import {Loader} from '#/components/Loader' import * as Menu from '#/components/Menu' import {ReportDialog} from '#/components/moderation/ReportDialog' +import * as Toast from '#/components/Toast' export function RejectMenu({ convo, @@ -72,7 +72,9 @@ export function RejectMenu({ message: 'Failed to delete chat', }), ), - 'xmark', + { + type: 'error', + }, ) }, }) @@ -86,7 +88,9 @@ export function RejectMenu({ message: 'Chat deleted', }), ), - 'check', + { + type: 'success', + }, ) leaveConvo() }, [leaveConvo, _]) @@ -99,7 +103,9 @@ export function RejectMenu({ message: 'Account blocked', }), ), - 'check', + { + type: 'success', + }, ) // block and also delete convo queueBlock() @@ -245,7 +251,9 @@ export function AcceptChatButton({ message: 'Failed to accept chat', }), ), - 'xmark', + { + type: 'error', + }, ) }, }) @@ -314,7 +322,9 @@ export function DeleteChatButton({ message: 'Failed to delete chat', }), ), - 'xmark', + { + type: 'error', + }, ) }, }) @@ -327,7 +337,9 @@ export function DeleteChatButton({ message: 'Chat deleted', }), ), - 'check', + { + type: 'success', + }, ) leaveConvo() }, [leaveConvo, _]) diff --git a/src/screens/ModerationInteractionSettings/index.tsx b/src/screens/ModerationInteractionSettings/index.tsx index 5a984bed4a..261e6b55ae 100644 --- a/src/screens/ModerationInteractionSettings/index.tsx +++ b/src/screens/ModerationInteractionSettings/index.tsx @@ -16,12 +16,12 @@ import { threadgateAllowUISettingToAllowRecordValue, threadgateRecordToAllowUISetting, } from '#/state/queries/threadgate' -import * as Toast from '#/view/com/util/Toast' import {atoms as a, useGutters} from '#/alf' import {Admonition} from '#/components/Admonition' import {PostInteractionSettingsForm} from '#/components/dialogs/PostInteractionSettingsDialog' import * as Layout from '#/components/Layout' import {Loader} from '#/components/Loader' +import * as Toast from '#/components/Toast' export function Screen() { const gutters = useGutters(['base']) diff --git a/src/screens/PostThread/components/ThreadItemAnchorFollowButton.tsx b/src/screens/PostThread/components/ThreadItemAnchorFollowButton.tsx index 1651757426..f7ea1c53fb 100644 --- a/src/screens/PostThread/components/ThreadItemAnchorFollowButton.tsx +++ b/src/screens/PostThread/components/ThreadItemAnchorFollowButton.tsx @@ -12,11 +12,11 @@ import { useProfileQuery, } from '#/state/queries/profile' import {useRequireAuth} from '#/state/session' -import * as Toast from '#/view/com/util/Toast' import {atoms as a, useBreakpoints} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {Check_Stroke2_Corner0_Rounded as CheckIcon} from '#/components/icons/Check' import {PlusLarge_Stroke2_Corner0_Rounded as PlusIcon} from '#/components/icons/Plus' +import * as Toast from '#/components/Toast' import {IS_IOS} from '#/env' import {GrowthHack} from './GrowthHack' @@ -114,7 +114,9 @@ function PostThreadFollowBtnLoaded({ } catch (e: any) { if (e?.name !== 'AbortError') { logger.error('Failed to follow', {message: String(e)}) - Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark') + Toast.show(_(msg`There was an issue! ${e.toString()}`), { + type: 'error', + }) } } }) @@ -125,7 +127,9 @@ function PostThreadFollowBtnLoaded({ } catch (e: any) { if (e?.name !== 'AbortError') { logger.error('Failed to unfollow', {message: String(e)}) - Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark') + Toast.show(_(msg`There was an issue! ${e.toString()}`), { + type: 'error', + }) } } }) diff --git a/src/screens/Profile/Header/EditProfileDialog.tsx b/src/screens/Profile/Header/EditProfileDialog.tsx index 2d0d0d34d3..3b948f2375 100644 --- a/src/screens/Profile/Header/EditProfileDialog.tsx +++ b/src/screens/Profile/Header/EditProfileDialog.tsx @@ -12,7 +12,6 @@ import {logger} from '#/logger' import {type ImageMeta} from '#/state/gallery' import {useProfileUpdateMutation} from '#/state/queries/profile' import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' -import * as Toast from '#/view/com/util/Toast' import {EditableUserAvatar} from '#/view/com/util/UserAvatar' import {UserBanner} from '#/view/com/util/UserBanner' import {atoms as a, useTheme} from '#/alf' @@ -23,6 +22,7 @@ import * as TextField from '#/components/forms/TextField' import {InlineLinkText} from '#/components/Link' import {Loader} from '#/components/Loader' import * as Prompt from '#/components/Prompt' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {useSimpleVerificationState} from '#/components/verification' diff --git a/src/screens/Profile/components/ProfileFeedHeader.tsx b/src/screens/Profile/components/ProfileFeedHeader.tsx index 9f78167a64..6966fa6fe2 100644 --- a/src/screens/Profile/components/ProfileFeedHeader.tsx +++ b/src/screens/Profile/components/ProfileFeedHeader.tsx @@ -21,7 +21,6 @@ import { } from '#/state/queries/preferences' import {useSession} from '#/state/session' import {formatCount} from '#/view/com/util/numeric/format' -import * as Toast from '#/view/com/util/Toast' import {UserAvatar} from '#/view/com/util/UserAvatar' import {atoms as a, useBreakpoints, useTheme, web} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' @@ -50,6 +49,7 @@ import { useReportDialogControl, } from '#/components/moderation/ReportDialog' import {RichText} from '#/components/RichText' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' import {IS_WEB} from '#/env' @@ -139,7 +139,9 @@ export function ProfileFeedHeader({info}: {info: FeedSourceFeedInfo}) { _( msg`There was an issue updating your feeds, please check your internet connection and try again.`, ), - 'xmark', + { + type: 'error', + }, ) logger.error('Failed to update feeds', {message: err}) } @@ -177,7 +179,9 @@ export function ProfileFeedHeader({info}: {info: FeedSourceFeedInfo}) { ax.metric('feed:pin', {feedUrl: info.uri}) } } catch (e) { - Toast.show(_(msg`There was an issue contacting the server`), 'xmark') + Toast.show(_(msg`There was an issue contacting the server`), { + type: 'error', + }) logger.error('Failed to toggle pinned feed', {message: e}) } } @@ -421,7 +425,9 @@ function DialogInner({ _( msg`There was an issue contacting the server, please check your internet connection and try again.`, ), - 'xmark', + { + type: 'error', + }, ) logger.error('Failed to toggle like', {message: err}) } diff --git a/src/screens/SavedFeeds.tsx b/src/screens/SavedFeeds.tsx index 4b8fcaddbc..e2629651ec 100644 --- a/src/screens/SavedFeeds.tsx +++ b/src/screens/SavedFeeds.tsx @@ -25,7 +25,6 @@ import { import {type UsePreferencesQueryResponse} from '#/state/queries/preferences/types' import {useSetMinimalShellMode} from '#/state/shell' import {FeedSourceCard} from '#/view/com/feeds/FeedSourceCard' -import * as Toast from '#/view/com/util/Toast' import {NoFollowingFeed} from '#/screens/Feeds/NoFollowingFeed' import {NoSavedFeedsOfAnyType} from '#/screens/Feeds/NoSavedFeedsOfAnyType' import {atoms as a, useBreakpoints, useTheme} from '#/alf' @@ -43,6 +42,7 @@ import {Trash_Stroke2_Corner0_Rounded as TrashIcon} from '#/components/icons/Tra import * as Layout from '#/components/Layout' import {InlineLinkText} from '#/components/Link' import {Loader} from '#/components/Loader' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' type Props = NativeStackScreenProps @@ -104,7 +104,9 @@ function SavedFeedsInner({ navigation.navigate('Feeds') } } catch (e) { - Toast.show(_(msg`There was an issue contacting the server`), 'xmark') + Toast.show(_(msg`There was an issue contacting the server`), { + type: 'error', + }) logger.error('Failed to toggle pinned feed', {message: e}) } } @@ -288,7 +290,9 @@ function SavedFeedsA11y({ navigation.navigate('Feeds') } } catch (e) { - Toast.show(_(msg`There was an issue contacting the server`), 'xmark') + Toast.show(_(msg`There was an issue contacting the server`), { + type: 'error', + }) logger.error('Failed to toggle pinned feed', {message: e}) } } diff --git a/src/screens/Settings/AboutSettings.tsx b/src/screens/Settings/AboutSettings.tsx index 9e287ade71..5acb50c4f5 100644 --- a/src/screens/Settings/AboutSettings.tsx +++ b/src/screens/Settings/AboutSettings.tsx @@ -10,7 +10,6 @@ import {useMutation} from '@tanstack/react-query' import {STATUS_PAGE_URL} from '#/lib/constants' import {type CommonNavigatorParams} from '#/lib/routes/types' -import * as Toast from '#/view/com/util/Toast' import * as SettingsList from '#/screens/Settings/components/SettingsList' import {Atom_Stroke2_Corner0_Rounded as AtomIcon} from '#/components/icons/Atom' import {BroomSparkle_Stroke2_Corner2_Rounded as BroomSparkleIcon} from '#/components/icons/BroomSparkle' @@ -20,6 +19,7 @@ import {Newspaper_Stroke2_Corner2_Rounded as NewspaperIcon} from '#/components/i import {Wrench_Stroke2_Corner2_Rounded as WrenchIcon} from '#/components/icons/Wrench' import * as Layout from '#/components/Layout' import {Loader} from '#/components/Loader' +import * as Toast from '#/components/Toast' import {getDeviceId} from '#/analytics/identifiers' import {IS_ANDROID, IS_IOS, IS_NATIVE} from '#/env' import * as env from '#/env' diff --git a/src/screens/Settings/AppPasswords.tsx b/src/screens/Settings/AppPasswords.tsx index 0cc3792bf8..65ebdf3d4f 100644 --- a/src/screens/Settings/AppPasswords.tsx +++ b/src/screens/Settings/AppPasswords.tsx @@ -20,7 +20,6 @@ import { } from '#/state/queries/app-passwords' import {EmptyState} from '#/view/com/util/EmptyState' import {ErrorScreen} from '#/view/com/util/error/ErrorScreen' -import * as Toast from '#/view/com/util/Toast' import {atoms as a, useTheme} from '#/alf' import {Admonition} from '#/components/Admonition' import {Button, ButtonIcon, ButtonText} from '#/components/Button' @@ -32,6 +31,7 @@ import {Warning_Stroke2_Corner0_Rounded as WarningIcon} from '#/components/icons import * as Layout from '#/components/Layout' import {Loader} from '#/components/Loader' import * as Prompt from '#/components/Prompt' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {AddAppPasswordDialog} from './components/AddAppPasswordDialog' import * as SettingsList from './components/SettingsList' diff --git a/src/screens/Settings/InterestsSettings.tsx b/src/screens/Settings/InterestsSettings.tsx index 53684722aa..8224bb133e 100644 --- a/src/screens/Settings/InterestsSettings.tsx +++ b/src/screens/Settings/InterestsSettings.tsx @@ -22,13 +22,13 @@ import {createGetSuggestedFeedsQueryKey} from '#/state/queries/trending/useGetSu import {createGetSuggestedUsersQueryKey} from '#/state/queries/trending/useGetSuggestedUsersQuery' import {createSuggestedStarterPacksQueryKey} from '#/state/queries/useSuggestedStarterPacksQuery' import {useAgent} from '#/state/session' -import * as Toast from '#/view/com/util/Toast' import {atoms as a, useGutters, useTheme} from '#/alf' import {Admonition} from '#/components/Admonition' import {Divider} from '#/components/Divider' import * as Toggle from '#/components/forms/Toggle' import * as Layout from '#/components/Layout' import {Loader} from '#/components/Loader' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' type Props = NativeStackScreenProps @@ -139,7 +139,9 @@ function Inner({ context: 'toast', }), ), - 'xmark', + { + type: 'error', + }, ) } finally { setIsSaving(false) diff --git a/src/screens/Settings/Settings.tsx b/src/screens/Settings/Settings.tsx index c77c77a209..6e02297fc2 100644 --- a/src/screens/Settings/Settings.tsx +++ b/src/screens/Settings/Settings.tsx @@ -28,7 +28,6 @@ import {type SessionAccount, useSession, useSessionApi} from '#/state/session' import {useOnboardingDispatch} from '#/state/shell' import {useLoggedOutViewControls} from '#/state/shell/logged-out' import {useCloseAllActiveElements} from '#/state/util' -import * as Toast from '#/view/com/util/Toast' import {UserAvatar} from '#/view/com/util/UserAvatar' import * as SettingsList from '#/screens/Settings/components/SettingsList' import {atoms as a, platform, tokens, useBreakpoints, useTheme} from '#/alf' @@ -63,6 +62,7 @@ import * as Menu from '#/components/Menu' import {ID as PolicyUpdate202508} from '#/components/PolicyUpdateOverlay/updates/202508/config' import {ProfileBadges} from '#/components/ProfileBadges' import * as Prompt from '#/components/Prompt' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' import {IS_INTERNAL, IS_IOS, IS_NATIVE} from '#/env' @@ -520,7 +520,6 @@ function DevOptions() { ) : null} - @@ -545,7 +544,9 @@ function DevOptions() { onPress={() => { device.set([PolicyUpdate202508], false) agent.bskyAppRemoveNuxs([PolicyUpdate202508]) - Toast.show(`Done`, 'info') + Toast.show(`Done`, { + type: 'info', + }) }} label="Reset policy update nux" color="secondary" diff --git a/src/screens/Settings/components/DisableEmail2FADialog.tsx b/src/screens/Settings/components/DisableEmail2FADialog.tsx index 45b414116b..8b774b54f7 100644 --- a/src/screens/Settings/components/DisableEmail2FADialog.tsx +++ b/src/screens/Settings/components/DisableEmail2FADialog.tsx @@ -7,13 +7,13 @@ import {Trans} from '@lingui/react/macro' import {cleanError} from '#/lib/strings/errors' import {useAgent, useSession} from '#/state/session' import {ErrorMessage} from '#/view/com/util/error/ErrorMessage' -import * as Toast from '#/view/com/util/Toast' import {atoms as a, useBreakpoints, useTheme} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import * as Dialog from '#/components/Dialog' import * as TextField from '#/components/forms/TextField' import {Lock_Stroke2_Corner0_Rounded as Lock} from '#/components/icons/Lock' import {Loader} from '#/components/Loader' +import * as Toast from '#/components/Toast' import {P, Text} from '#/components/Typography' import {IS_NATIVE} from '#/env' diff --git a/src/screens/Settings/components/OTAInfo.tsx b/src/screens/Settings/components/OTAInfo.tsx index b64fbc1b20..9ab1962b97 100644 --- a/src/screens/Settings/components/OTAInfo.tsx +++ b/src/screens/Settings/components/OTAInfo.tsx @@ -4,11 +4,11 @@ import {useLingui} from '@lingui/react' import {Trans} from '@lingui/react/macro' import {useMutation, useQuery} from '@tanstack/react-query' -import * as Toast from '#/view/com/util/Toast' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as RetryIcon} from '#/components/icons/ArrowRotate' import {Shapes_Stroke2_Corner0_Rounded as ShapesIcon} from '#/components/icons/Shapes' import {Loader} from '#/components/Loader' +import * as Toast from '#/components/Toast' import * as SettingsList from '../components/SettingsList' export function OTAInfo() { @@ -34,7 +34,9 @@ export function OTAInfo() { await Updates.reloadAsync() }, onError: error => - Toast.show(`Failed to update: ${error.message}`, 'xmark'), + Toast.show(`Failed to update: ${error.message}`, { + type: 'error', + }), }) if (!Updates.isEnabled || __DEV__) { diff --git a/src/screens/StarterPack/StarterPackScreen.tsx b/src/screens/StarterPack/StarterPackScreen.tsx index 49d826a428..ef812b6cee 100644 --- a/src/screens/StarterPack/StarterPackScreen.tsx +++ b/src/screens/StarterPack/StarterPackScreen.tsx @@ -46,7 +46,6 @@ import { import {useSetActiveStarterPack} from '#/state/shell/starter-pack' import {PagerWithHeader} from '#/view/com/pager/PagerWithHeader' import {ProfileSubpageHeader} from '#/view/com/profile/ProfileSubpageHeader' -import * as Toast from '#/view/com/util/Toast' import {bulkWriteFollows} from '#/screens/Onboarding/util' import {atoms as a, useBreakpoints, useTheme} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' @@ -74,6 +73,7 @@ import {PostsList} from '#/components/StarterPack/Main/PostsList' import {ProfilesList} from '#/components/StarterPack/Main/ProfilesList' import {QrCodeDialog} from '#/components/StarterPack/QrCodeDialog' import {ShareDialog} from '#/components/StarterPack/ShareDialog' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' import {IS_WEB} from '#/env' @@ -356,7 +356,9 @@ function Header({ listItems = await getAllListMembers(agent, starterPack.list.uri) } catch (e) { setIsProcessing(false) - Toast.show(_(msg`An error occurred while trying to follow all`), 'xmark') + Toast.show(_(msg`An error occurred while trying to follow all`), { + type: 'error', + }) logger.error('Failed to get list members for starter pack', { safeMessage: e, }) @@ -381,7 +383,9 @@ function Header({ }) } catch (e) { setIsProcessing(false) - Toast.show(_(msg`An error occurred while trying to follow all`), 'xmark') + Toast.show(_(msg`An error occurred while trying to follow all`), { + type: 'error', + }) logger.error('Failed to follow all accounts', {safeMessage: e}) } @@ -749,7 +753,9 @@ function InvalidStarterPack({rkey}: {rkey: string}) { onError: e => { setIsProcessing(false) logger.error('Failed to delete invalid starter pack', {safeMessage: e}) - Toast.show(_(msg`Failed to delete starter pack`), 'xmark') + Toast.show(_(msg`Failed to delete starter pack`), { + type: 'error', + }) }, }) diff --git a/src/screens/StarterPack/Wizard/State.tsx b/src/screens/StarterPack/Wizard/State.tsx index a148d6a653..0ec8700057 100644 --- a/src/screens/StarterPack/Wizard/State.tsx +++ b/src/screens/StarterPack/Wizard/State.tsx @@ -7,7 +7,7 @@ import { import {msg, plural} from '@lingui/core/macro' import {STARTER_PACK_MAX_SIZE} from '#/lib/constants' -import * as Toast from '#/view/com/util/Toast' +import * as Toast from '#/components/Toast' import * as bsky from '#/types/bsky' const steps = ['Details', 'Profiles', 'Feeds'] as const @@ -80,7 +80,9 @@ function reducer(state: State, action: Action): State { msg`You may only add up to ${plural(STARTER_PACK_MAX_SIZE, { other: `${STARTER_PACK_MAX_SIZE} profiles`, })}`.message ?? '', - 'info', + { + type: 'info', + }, ) } else { updatedState = {...state, profiles: [...state.profiles, action.profile]} @@ -96,7 +98,9 @@ function reducer(state: State, action: Action): State { break case 'AddFeed': if (state.feeds.length >= 3) { - Toast.show(msg`You may only add up to 3 feeds`.message ?? '', 'info') + Toast.show(msg`You may only add up to 3 feeds`.message ?? '', { + type: 'info', + }) } else { updatedState = {...state, feeds: [...state.feeds, action.feed]} } diff --git a/src/screens/StarterPack/Wizard/index.tsx b/src/screens/StarterPack/Wizard/index.tsx index f64f7d163d..adddd6417b 100644 --- a/src/screens/StarterPack/Wizard/index.tsx +++ b/src/screens/StarterPack/Wizard/index.tsx @@ -40,7 +40,6 @@ import { } from '#/state/queries/starter-packs' import {useSession} from '#/state/session' import {useSetMinimalShellMode} from '#/state/shell' -import * as Toast from '#/view/com/util/Toast' import {UserAvatar} from '#/view/com/util/UserAvatar' import { useWizardState, @@ -56,6 +55,7 @@ import * as Layout from '#/components/Layout' import {ListMaybePlaceholder} from '#/components/Lists' import {Loader} from '#/components/Loader' import {WizardEditListDialog} from '#/components/StarterPack/Wizard/WizardEditListDialog' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import {useAnalytics} from '#/analytics' import {IS_NATIVE} from '#/env' @@ -258,7 +258,9 @@ function WizardInner({ onError: e => { logger.error('Failed to create starter pack', {safeMessage: e}) dispatch({type: 'SetProcessing', processing: false}) - Toast.show(_(msg`Failed to create starter pack`), 'xmark') + Toast.show(_(msg`Failed to create starter pack`), { + type: 'error', + }) }, }) const {mutate: editStarterPack} = useEditStarterPackMutation({ @@ -266,7 +268,9 @@ function WizardInner({ onError: e => { logger.error('Failed to edit starter pack', {safeMessage: e}) dispatch({type: 'SetProcessing', processing: false}) - Toast.show(_(msg`Failed to create starter pack`), 'xmark') + Toast.show(_(msg`Failed to create starter pack`), { + type: 'error', + }) }, }) diff --git a/src/state/queries/activity-subscriptions.ts b/src/state/queries/activity-subscriptions.ts index 5ad218fe94..30964fe7d6 100644 --- a/src/state/queries/activity-subscriptions.ts +++ b/src/state/queries/activity-subscriptions.ts @@ -14,7 +14,7 @@ import { } from '@tanstack/react-query' import {useAgent, useSession} from '#/state/session' -import * as Toast from '#/view/com/util/Toast' +import * as Toast from '#/components/Toast' export const RQKEY_getActivitySubscriptions = ['activity-subscriptions'] export const RQKEY_getNotificationDeclaration = ['notification-declaration'] diff --git a/src/state/queries/notifications/settings.ts b/src/state/queries/notifications/settings.ts index 274b17f5ae..d00a4ae5ed 100644 --- a/src/state/queries/notifications/settings.ts +++ b/src/state/queries/notifications/settings.ts @@ -9,7 +9,7 @@ import { import {logger} from '#/logger' import {useAgent} from '#/state/session' -import * as Toast from '#/view/com/util/Toast' +import * as Toast from '#/components/Toast' const RQKEY_ROOT = 'notification-settings' const RQKEY = [RQKEY_ROOT] @@ -46,7 +46,9 @@ export function useNotificationSettingsUpdateMutation() { onError: e => { logger.error('Could not update notification settings', {message: e}) queryClient.invalidateQueries({queryKey: RQKEY}) - Toast.show(t`Could not update notification settings`, 'xmark') + Toast.show(t`Could not update notification settings`, { + type: 'error', + }) }, }) } diff --git a/src/state/queries/pinned-post.ts b/src/state/queries/pinned-post.ts index 440a3e51fd..09a0b4c9b9 100644 --- a/src/state/queries/pinned-post.ts +++ b/src/state/queries/pinned-post.ts @@ -4,7 +4,7 @@ import {useMutation, useQueryClient} from '@tanstack/react-query' import {logger} from '#/logger' import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed' -import * as Toast from '#/view/com/util/Toast' +import * as Toast from '#/components/Toast' import {updatePostShadow} from '../cache/post-shadow' import {useAgent, useSession} from '../session' import {useProfileUpdateMutation} from './profile' diff --git a/src/state/shell/composer/index.tsx b/src/state/shell/composer/index.tsx index e8d694fddf..eda5235523 100644 --- a/src/state/shell/composer/index.tsx +++ b/src/state/shell/composer/index.tsx @@ -18,7 +18,7 @@ import { RQKEY_LINK_ROOT, } from '#/state/queries/resolve-link' import {type EmojiPickerPosition} from '#/view/com/composer/text-input/web/EmojiPicker' -import * as Toast from '#/view/com/util/Toast' +import * as Toast from '#/components/Toast' export interface ComposerOptsPostRef { uri: string @@ -104,10 +104,9 @@ export function Provider({children}: React.PropsWithChildren<{}>) { author.viewer?.blockingByList), ) if (isBlocked) { - Toast.show( - _(msg`Cannot interact with a blocked user`), - 'exclamation-circle', - ) + Toast.show(_(msg`Cannot interact with a blocked user`), { + type: 'warning', + }) } else { setState(prevOpts => { if (prevOpts) { diff --git a/src/view/com/composer/videos/SubtitleFilePicker.tsx b/src/view/com/composer/videos/SubtitleFilePicker.tsx index aed396c2e9..44fa582ddf 100644 --- a/src/view/com/composer/videos/SubtitleFilePicker.tsx +++ b/src/view/com/composer/videos/SubtitleFilePicker.tsx @@ -5,10 +5,10 @@ import {useLingui} from '@lingui/react' import {Trans} from '@lingui/react/macro' import {logger} from '#/logger' -import * as Toast from '#/view/com/util/Toast' import {atoms as a} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {CC_Stroke2_Corner0_Rounded as CCIcon} from '#/components/icons/CC' +import * as Toast from '#/components/Toast' export function SubtitleFilePicker({ onSelectFile, diff --git a/src/view/com/composer/videos/VideoPreview.web.tsx b/src/view/com/composer/videos/VideoPreview.web.tsx index 574cc1cf4d..e23733e0c6 100644 --- a/src/view/com/composer/videos/VideoPreview.web.tsx +++ b/src/view/com/composer/videos/VideoPreview.web.tsx @@ -7,8 +7,8 @@ import {type CompressedVideo} from '#/lib/media/video/types' import {clamp} from '#/lib/numbers' import {useAutoplayDisabled} from '#/state/preferences' import {ExternalEmbedRemoveBtn} from '#/view/com/composer/ExternalEmbedRemoveBtn' -import * as Toast from '#/view/com/util/Toast' import {atoms as a} from '#/alf' +import * as Toast from '#/components/Toast' import {PlayButtonIcon} from '#/components/video/PlayButtonIcon' export function VideoPreview({ @@ -63,7 +63,9 @@ export function VideoPreview({ playsInline onError={err => { console.error('Error loading video', err) - Toast.show(_(msg`Could not process your video`), 'xmark') + Toast.show(_(msg`Could not process your video`), { + type: 'error', + }) clear() }} /> diff --git a/src/view/com/notifications/NotificationFeedItem.tsx b/src/view/com/notifications/NotificationFeedItem.tsx index e769affdfa..d8f0abf8a5 100644 --- a/src/view/com/notifications/NotificationFeedItem.tsx +++ b/src/view/com/notifications/NotificationFeedItem.tsx @@ -44,7 +44,6 @@ import {FeedSourceCard} from '#/view/com/feeds/FeedSourceCard' import {Post} from '#/view/com/post/Post' import {formatCount} from '#/view/com/util/numeric/format' import {TimeElapsed} from '#/view/com/util/TimeElapsed' -import * as Toast from '#/view/com/util/Toast' import {PreviewableUserAvatar, UserAvatar} from '#/view/com/util/UserAvatar' import {atoms as a, platform, useTheme} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' @@ -67,6 +66,7 @@ import {ProfileBadges} from '#/components/ProfileBadges' import {ProfileHoverCard} from '#/components/ProfileHoverCard' import {Notification as StarterPackCard} from '#/components/StarterPack/StarterPackCard' import {SubtleHover} from '#/components/SubtleHover' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' import * as bsky from '#/types/bsky' @@ -769,7 +769,9 @@ function FollowBackButton({profile}: {profile: AppBskyActorDefs.ProfileView}) { ) } catch (err: any) { if (err?.name !== 'AbortError') { - Toast.show(_(msg`An issue occurred, please try again.`), 'xmark') + Toast.show(_(msg`An issue occurred, please try again.`), { + type: 'error', + }) } } } @@ -789,7 +791,9 @@ function FollowBackButton({profile}: {profile: AppBskyActorDefs.ProfileView}) { ) } catch (err: any) { if (err?.name !== 'AbortError') { - Toast.show(_(msg`An issue occurred, please try again.`), 'xmark') + Toast.show(_(msg`An issue occurred, please try again.`), { + type: 'error', + }) } } } diff --git a/src/view/com/posts/FeedShutdownMsg.tsx b/src/view/com/posts/FeedShutdownMsg.tsx index 8e426de6c2..459cb5870e 100644 --- a/src/view/com/posts/FeedShutdownMsg.tsx +++ b/src/view/com/posts/FeedShutdownMsg.tsx @@ -12,11 +12,11 @@ import { useReplaceForYouWithDiscoverFeedMutation, } from '#/state/queries/preferences' import {useSetSelectedFeed} from '#/state/shell/selected-feed' -import * as Toast from '#/view/com/util/Toast' import {atoms as a, useTheme} from '#/alf' import {Button, ButtonIcon, ButtonText} from '#/components/Button' import {InlineLinkText} from '#/components/Link' import {Loader} from '#/components/Loader' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' export function FeedShutdownMsg({feedUri}: {feedUri: string}) { @@ -52,7 +52,9 @@ export function FeedShutdownMsg({feedUri}: {feedUri: string}) { _( msg`There was an issue updating your feeds, please check your internet connection and try again.`, ), - 'exclamation-circle', + { + type: 'warning', + }, ) logger.error('Failed to update feeds', {message: err}) } @@ -71,7 +73,9 @@ export function FeedShutdownMsg({feedUri}: {feedUri: string}) { _( msg`There was an issue updating your feeds, please check your internet connection and try again.`, ), - 'exclamation-circle', + { + type: 'warning', + }, ) logger.error('Failed to update feeds', {message: err}) } diff --git a/src/view/com/profile/ProfileMenu.tsx b/src/view/com/profile/ProfileMenu.tsx index e036871215..c89b2c3bf9 100644 --- a/src/view/com/profile/ProfileMenu.tsx +++ b/src/view/com/profile/ProfileMenu.tsx @@ -22,7 +22,6 @@ import { } from '#/state/queries/profile' import {useSession} from '#/state/session' import {EventStopper} from '#/view/com/util/EventStopper' -import * as Toast from '#/view/com/util/Toast' import {atoms as a, useTheme} from '#/alf' import {Button, ButtonIcon} from '#/components/Button' import {useDialogControl} from '#/components/Dialog' @@ -52,6 +51,7 @@ import { useReportDialogControl, } from '#/components/moderation/ReportDialog' import * as Prompt from '#/components/Prompt' +import * as Toast from '#/components/Toast' import {useFullVerificationState} from '#/components/verification' import {VerificationCreatePrompt} from '#/components/verification/VerificationCreatePrompt' import {VerificationRemovePrompt} from '#/components/verification/VerificationRemovePrompt' @@ -149,7 +149,9 @@ let ProfileMenu = ({ } catch (e: any) { if (e?.name !== 'AbortError') { ax.logger.error('Failed to unmute account', {message: e}) - Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark') + Toast.show(_(msg`There was an issue! ${e.toString()}`), { + type: 'error', + }) } } } else { @@ -159,7 +161,9 @@ let ProfileMenu = ({ } catch (e: any) { if (e?.name !== 'AbortError') { ax.logger.error('Failed to mute account', {message: e}) - Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark') + Toast.show(_(msg`There was an issue! ${e.toString()}`), { + type: 'error', + }) } } } @@ -173,7 +177,9 @@ let ProfileMenu = ({ } catch (e: any) { if (e?.name !== 'AbortError') { ax.logger.error('Failed to unblock account', {message: e}) - Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark') + Toast.show(_(msg`There was an issue! ${e.toString()}`), { + type: 'error', + }) } } } else { @@ -183,7 +189,9 @@ let ProfileMenu = ({ } catch (e: any) { if (e?.name !== 'AbortError') { ax.logger.error('Failed to block account', {message: e}) - Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark') + Toast.show(_(msg`There was an issue! ${e.toString()}`), { + type: 'error', + }) } } } @@ -196,7 +204,9 @@ let ProfileMenu = ({ } catch (e: any) { if (e?.name !== 'AbortError') { ax.logger.error('Failed to follow account', {message: e}) - Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark') + Toast.show(_(msg`There was an issue! ${e.toString()}`), { + type: 'error', + }) } } }, [_, ax, queueFollow]) @@ -208,7 +218,9 @@ let ProfileMenu = ({ } catch (e: any) { if (e?.name !== 'AbortError') { ax.logger.error('Failed to unfollow account', {message: e}) - Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark') + Toast.show(_(msg`There was an issue! ${e.toString()}`), { + type: 'error', + }) } } }, [_, ax, queueUnfollow]) diff --git a/src/view/screens/Debug.tsx b/src/view/screens/Debug.tsx index 3c6b9e9266..7e79b26ccd 100644 --- a/src/view/screens/Debug.tsx +++ b/src/view/screens/Debug.tsx @@ -16,11 +16,11 @@ import {ErrorScreen} from '#/view/com/util/error/ErrorScreen' import {Button} from '#/view/com/util/forms/Button' import * as LoadingPlaceholder from '#/view/com/util/LoadingPlaceholder' import {Text} from '#/view/com/util/text/Text' -import * as Toast from '#/view/com/util/Toast' import {ViewHeader} from '#/view/com/util/ViewHeader' import {ViewSelector} from '#/view/com/util/ViewSelector' import {HashtagWide_Stroke1_Corner0_Rounded as HashtagWideIcon} from '#/components/icons/Hashtag' import * as Layout from '#/components/Layout' +import * as Toast from '#/components/Toast' const MAIN_VIEWS = ['Base', 'Controls', 'Error', 'Notifs'] diff --git a/src/view/screens/Storybook/Settings.tsx b/src/view/screens/Storybook/Settings.tsx index 196dfac060..af3a7b4634 100644 --- a/src/view/screens/Storybook/Settings.tsx +++ b/src/view/screens/Storybook/Settings.tsx @@ -1,6 +1,5 @@ import {View} from 'react-native' -import * as Toast from '#/view/com/util/Toast' import * as SettingsList from '#/screens/Settings/components/SettingsList' import {atoms as a, useTheme} from '#/alf' import {Alien_Stroke2_Corner0_Rounded as AlienIcon} from '#/components/icons/Alien' @@ -16,6 +15,7 @@ import {Pizza_Stroke2_Corner0_Rounded as PizzaIcon} from '#/components/icons/Piz import {RaisingHand4Finger_Stroke2_Corner2_Rounded as HandIcon} from '#/components/icons/RaisingHand' import {ShieldCheck_Stroke2_Corner0_Rounded as ShieldIcon} from '#/components/icons/Shield' import {Window_Stroke2_Corner2_Rounded as WindowIcon} from '#/components/icons/Window' +import * as Toast from '#/components/Toast' import {Text} from '#/components/Typography' export function Settings() {