···11+/**
22+ * Codemod to replace namespaced React calls with named imports
33+ *
44+ * Before:
55+ * import * as Toast from '#/view/com/util/Toast'
66+ * Toast.show(message, 'xmark')
77+ *
88+ * After:
99+ * import * as Toast from '#/components/Toast'
1010+ * Toast.show(message, {type: 'error'})
1111+ *
1212+ * Usage: jscodeshift -t .jscodeshift/toast-v2.js <file-path>
1313+ * Example: jscodeshift -t .jscodeshift/toast-v2.js src/App.native.tsx
1414+ */
1515+1616+/* eslint-disable */
1717+1818+export const parser = 'tsx'
1919+2020+const OLD_IMPORT = '#/view/com/util/Toast'
2121+const NEW_IMPORT = '#/components/Toast'
2222+2323+const convertLegacyToastType = type => {
2424+ switch (type) {
2525+ // these ones are fine
2626+ case 'default':
2727+ case 'success':
2828+ case 'error':
2929+ case 'warning':
3030+ case 'info':
3131+ return type
3232+ // legacy ones need conversion
3333+ case 'xmark':
3434+ return 'error'
3535+ case 'exclamation-circle':
3636+ return 'warning'
3737+ case 'check':
3838+ return 'success'
3939+ case 'clipboard-check':
4040+ return 'success'
4141+ case 'circle-exclamation':
4242+ case 'exclamation-circle':
4343+ return 'warning'
4444+ default:
4545+ return 'default'
4646+ }
4747+}
4848+4949+export default function transformer(file, api) {
5050+ const j = api.jscodeshift
5151+ const root = j(file.source)
5252+5353+ // Find Toast import declarations using the old path
5454+ const toastImports = root
5555+ .find(j.ImportDeclaration)
5656+ .filter(path => path.value.source.value === OLD_IMPORT)
5757+5858+ if (toastImports.length === 0) {
5959+ return file.source
6060+ }
6161+6262+ // Update import path
6363+ toastImports.forEach(path => {
6464+ path.value.source.value = NEW_IMPORT
6565+ })
6666+6767+ // Collect all local names the Toast namespace is bound to
6868+ const toastLocalNames = new Set()
6969+ toastImports.forEach(path => {
7070+ path.value.specifiers.forEach(spec => {
7171+ if (spec.type === 'ImportNamespaceSpecifier') {
7272+ toastLocalNames.add(spec.local.name)
7373+ }
7474+ })
7575+ })
7676+7777+ // Transform Toast.show(message, type) calls
7878+ root.find(j.CallExpression).forEach(path => {
7979+ const {callee, arguments: args} = path.value
8080+8181+ // Match <ToastName>.show(...)
8282+ if (
8383+ callee.type !== 'MemberExpression' ||
8484+ callee.object.type !== 'Identifier' ||
8585+ !toastLocalNames.has(callee.object.name) ||
8686+ callee.property.name !== 'show'
8787+ ) {
8888+ return
8989+ }
9090+9191+ // Only transform 2-arg calls where the second arg is a string literal
9292+ if (args.length !== 2) return
9393+ const typeArg = args[1]
9494+ if (typeArg.type !== 'StringLiteral' && typeArg.type !== 'Literal') return
9595+9696+ const legacyType = typeArg.value
9797+ const newType = convertLegacyToastType(legacyType)
9898+9999+ // Replace the second argument with an options object: {type: 'newType'}
100100+ args[1] = j.objectExpression([
101101+ j.property('init', j.identifier('type'), j.stringLiteral(newType)),
102102+ ])
103103+ })
104104+105105+ return root.toSource()
106106+}
+4-5
src/App.native.tsx
···5858import {Provider as StarterPackProvider} from '#/state/shell/starter-pack'
5959import {Provider as HiddenRepliesProvider} from '#/state/threadgate-hidden-replies'
6060import {TestCtrls} from '#/view/com/testing/TestCtrls'
6161-import * as Toast from '#/view/com/util/Toast'
6261import {Shell} from '#/view/shell'
6362import {ThemeProvider as Alf} from '#/alf'
6463import {useColorModeTheme} from '#/alf/util/useColorModeTheme'
···6867import {Provider as PolicyUpdateOverlayProvider} from '#/components/PolicyUpdateOverlay'
6968import {Provider as PortalProvider} from '#/components/Portal'
7069import {Provider as VideoVolumeProvider} from '#/components/Post/Embed/VideoEmbed/VideoVolumeContext'
7070+import * as Toast from '#/components/Toast'
7171import {ToastOutlet} from '#/components/Toast'
7272import {
7373 prefetchAgeAssuranceConfig,
···139139140140 useEffect(() => {
141141 return listenSessionDropped(() => {
142142- Toast.show(
143143- _(msg`Sorry! Your session expired. Please sign in again.`),
144144- 'info',
145145- )
142142+ Toast.show(_(msg`Sorry! Your session expired. Please sign in again.`), {
143143+ type: 'info',
144144+ })
146145 })
147146 }, [_])
148147
+4-5
src/App.web.tsx
···4747import {Provider as SelectedFeedProvider} from '#/state/shell/selected-feed'
4848import {Provider as StarterPackProvider} from '#/state/shell/starter-pack'
4949import {Provider as HiddenRepliesProvider} from '#/state/threadgate-hidden-replies'
5050-import * as Toast from '#/view/com/util/Toast'
5150import {Shell} from '#/view/shell/index'
5251import {ThemeProvider as Alf} from '#/alf'
5352import {useColorModeTheme} from '#/alf/util/useColorModeTheme'
···5857import {Provider as PortalProvider} from '#/components/Portal'
5958import {Provider as ActiveVideoProvider} from '#/components/Post/Embed/VideoEmbed/ActiveVideoWebContext'
6059import {Provider as VideoVolumeProvider} from '#/components/Post/Embed/VideoEmbed/VideoVolumeContext'
6060+import * as Toast from '#/components/Toast'
6161import {ToastOutlet} from '#/components/Toast'
6262import {
6363 prefetchAgeAssuranceConfig,
···115115116116 useEffect(() => {
117117 return listenSessionDropped(() => {
118118- Toast.show(
119119- _(msg`Sorry! Your session expired. Please sign in again.`),
120120- 'info',
121121- )
118118+ Toast.show(_(msg`Sorry! Your session expired. Please sign in again.`), {
119119+ type: 'info',
120120+ })
122121 })
123122 }, [_])
124123
+4-2
src/components/FeedCard.tsx
···1818 useRemoveFeedMutation,
1919} from '#/state/queries/preferences'
2020import {useSession} from '#/state/session'
2121-import * as Toast from '#/view/com/util/Toast'
2221import {UserAvatar} from '#/view/com/util/UserAvatar'
2322import {atoms as a, select, useTheme} from '#/alf'
2423import {
···3332import {Loader} from '#/components/Loader'
3433import * as Prompt from '#/components/Prompt'
3534import {RichText, type RichTextProps} from '#/components/RichText'
3535+import * as Toast from '#/components/Toast'
3636import {Text} from '#/components/Typography'
3737import {useActiveLiveEventFeedUris} from '#/features/liveEvents/context'
3838import type * as bsky from '#/types/bsky'
···313313 Toast.show(l({message: 'Feeds updated!', context: 'toast'}))
314314 } catch (err: any) {
315315 logger.error(err, {message: `FeedCard: failed to update feeds`, pin})
316316- Toast.show(l`Failed to update feeds`, 'xmark')
316316+ Toast.show(l`Failed to update feeds`, {
317317+ type: 'error',
318318+ })
317319 }
318320 },
319321 [l, pin, saveFeeds, removeFeed, uri, savedFeedConfig, type],
···1212import {toShareUrl} from '#/lib/strings/url-helpers'
1313import {useProfileShadow} from '#/state/cache/profile-shadow'
1414import {useSession} from '#/state/session'
1515-import * as Toast from '#/view/com/util/Toast'
1615import {atoms as a} from '#/alf'
1716import {Admonition} from '#/components/Admonition'
1817import {useDialogControl} from '#/components/Dialog'
···2221import {Clipboard_Stroke2_Corner2_Rounded as ClipboardIcon} from '#/components/icons/Clipboard'
2322import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlaneIcon} from '#/components/icons/PaperPlane'
2423import * as Menu from '#/components/Menu'
2424+import * as Toast from '#/components/Toast'
2525import {useAgeAssurance} from '#/ageAssurance'
2626import {useAnalytics} from '#/analytics'
2727import {IS_IOS} from '#/env'
···7171 } else {
7272 await ExpoClipboard.setStringAsync(url)
7373 }
7474- Toast.show(_(msg`Copied to clipboard`), 'clipboard-check')
7474+ Toast.show(_(msg`Copied to clipboard`), {
7575+ type: 'success',
7676+ })
7577 onShareProp()
7678 }
7779
+10-4
src/components/PostControls/index.tsx
···2424 ProgressGuideAction,
2525 useProgressGuideControls,
2626} from '#/state/shell/progress-guide'
2727-import * as Toast from '#/view/com/util/Toast'
2827import {atoms as a, useBreakpoints} from '#/alf'
2928import {Reply as Bubble} from '#/components/icons/Reply'
3029import {useFormatPostStatCount} from '#/components/PostControls/util'
3130import * as Skele from '#/components/Skeleton'
3131+import * as Toast from '#/components/Toast'
3232import {useAnalytics} from '#/analytics'
3333import {BookmarkButton} from './BookmarkButton'
3434import {
···106106107107 const onPressToggleLike = async () => {
108108 if (isBlocked) {
109109- Toast.show(l`Cannot interact with a blocked user`, 'exclamation-circle')
109109+ Toast.show(l`Cannot interact with a blocked user`, {
110110+ type: 'warning',
111111+ })
110112 return
111113 }
112114···135137136138 const onRepost = async () => {
137139 if (isBlocked) {
138138- Toast.show(l`Cannot interact with a blocked user`, 'exclamation-circle')
140140+ Toast.show(l`Cannot interact with a blocked user`, {
141141+ type: 'warning',
142142+ })
139143 return
140144 }
141145···161165162166 const onQuote = () => {
163167 if (isBlocked) {
164164- Toast.show(l`Cannot interact with a blocked user`, 'exclamation-circle')
168168+ Toast.show(l`Cannot interact with a blocked user`, {
169169+ type: 'warning',
170170+ })
165171 return
166172 }
167173
+7-3
src/components/ProfileCard.tsx
···2222import {useProfileShadow} from '#/state/cache/profile-shadow'
2323import {useProfileFollowMutationQueue} from '#/state/queries/profile'
2424import {useSession} from '#/state/session'
2525-import * as Toast from '#/view/com/util/Toast'
2625import {PreviewableUserAvatar, UserAvatar} from '#/view/com/util/UserAvatar'
2726import {
2827 atoms as a,
···4342import * as Pills from '#/components/Pills'
4443import {ProfileBadges} from '#/components/ProfileBadges'
4544import {RichText} from '#/components/RichText'
4545+import * as Toast from '#/components/Toast'
4646import {Text} from '#/components/Typography'
4747import {type Metrics} from '#/analytics'
4848import {useActorStatus} from '#/features/liveNow'
···504504 } catch (e) {
505505 const err = e as Error
506506 if (err?.name !== 'AbortError') {
507507- Toast.show(l`An issue occurred, please try again.`, 'xmark')
507507+ Toast.show(l`An issue occurred, please try again.`, {
508508+ type: 'error',
509509+ })
508510 }
509511 }
510512 }
···524526 } catch (e) {
525527 const err = e as Error
526528 if (err?.name !== 'AbortError') {
527527- Toast.show(l`An issue occurred, please try again.`, 'xmark')
529529+ Toast.show(l`An issue occurred, please try again.`, {
530530+ type: 'error',
531531+ })
528532 }
529533 }
530534 }
···3737 usePostThreadContext,
3838} from '#/state/queries/usePostThread'
3939import {useAgent, useSession} from '#/state/session'
4040-import * as Toast from '#/view/com/util/Toast'
4140import {UserAvatar} from '#/view/com/util/UserAvatar'
4241import {atoms as a, useTheme, web} from '#/alf'
4342import {Button, ButtonIcon, ButtonText} from '#/components/Button'
···5049import {CircleInfo_Stroke2_Corner0_Rounded as CircleInfo} from '#/components/icons/CircleInfo'
5150import {CloseQuote_Stroke2_Corner1_Rounded as QuoteIcon} from '#/components/icons/Quote'
5251import {Loader} from '#/components/Loader'
5252+import * as Toast from '#/components/Toast'
5353import {Text} from '#/components/Typography'
5454import {useAnalytics} from '#/analytics'
5555import {IS_IOS} from '#/env'
···240240 _(
241241 msg`There was an issue. Please check your internet connection and try again.`,
242242 ),
243243- 'xmark',
243243+ {
244244+ type: 'error',
245245+ },
244246 )
245247 } finally {
246248 setIsSaving(false)
···1717} from '#/state/queries/list'
1818import {useAgent} from '#/state/session'
1919import {ErrorMessage} from '#/view/com/util/error/ErrorMessage'
2020-import * as Toast from '#/view/com/util/Toast'
2120import {EditableUserAvatar} from '#/view/com/util/UserAvatar'
2221import {atoms as a, useTheme, web} from '#/alf'
2322import {Button, ButtonIcon, ButtonText} from '#/components/Button'
···2524import * as TextField from '#/components/forms/TextField'
2625import {Loader} from '#/components/Loader'
2726import * as Prompt from '#/components/Prompt'
2727+import * as Toast from '#/components/Toast'
2828import {Text} from '#/components/Typography'
2929import {IS_WEB} from '#/env'
3030
···1414 useListMembershipAddMutation,
1515 useListMembershipRemoveMutation,
1616} from '#/state/queries/list-memberships'
1717-import * as Toast from '#/view/com/util/Toast'
1817import {atoms as a} from '#/alf'
1918import {Button, ButtonIcon, ButtonText} from '#/components/Button'
2019import * as Dialog from '#/components/Dialog'
···2423} from '#/components/dialogs/SearchablePeopleList'
2524import {Loader} from '#/components/Loader'
2625import * as ProfileCard from '#/components/ProfileCard'
2626+import * as Toast from '#/components/Toast'
2727import type * as bsky from '#/types/bsky'
28282929export function ListAddRemoveUsersDialog({
···113113 Toast.show(_(msg`Added to list`))
114114 onChange?.('add', profile)
115115 },
116116- onError: e => Toast.show(cleanError(e), 'xmark'),
116116+ onError: e =>
117117+ Toast.show(cleanError(e), {
118118+ type: 'error',
119119+ }),
117120 })
118121 const {mutate: listMembershipRemove, isPending: isRemovingPending} =
119122 useListMembershipRemoveMutation({
···121124 Toast.show(_(msg`Removed from list`))
122125 onChange?.('remove', profile)
123126 },
124124- onError: e => Toast.show(cleanError(e), 'xmark'),
127127+ onError: e =>
128128+ Toast.show(cleanError(e), {
129129+ type: 'error',
130130+ }),
125131 })
126132 const isMutating = isAddingPending || isRemovingPending
127133
+6-6
src/components/dms/ActionsWrapper.web.tsx
···6677import {useConvoActive} from '#/state/messages/convo'
88import {useSession} from '#/state/session'
99-import * as Toast from '#/view/com/util/Toast'
109import {atoms as a, useTheme} from '#/alf'
1110import {MessageContextMenu} from '#/components/dms/MessageContextMenu'
1211import {DotGrid3x1_Stroke2_Corner0_Rounded as DotsHorizontalIcon} from '#/components/icons/DotGrid'
1312import {EmojiSmile_Stroke2_Corner0_Rounded as EmojiSmileIcon} from '#/components/icons/Emoji'
1313+import * as Toast from '#/components/Toast'
1414import {EmojiReactionPicker} from './EmojiReactionPicker'
1515import {hasReachedReactionLimit} from './util'
1616···6060 .catch(() => Toast.show(_(msg`Failed to remove emoji reaction`)))
6161 } else {
6262 if (hasReachedReactionLimit(message, currentAccount?.did)) return
6363- convo
6464- .addReaction(message.id, emoji)
6565- .catch(() =>
6666- Toast.show(_(msg`Failed to add emoji reaction`), 'xmark'),
6767- )
6363+ convo.addReaction(message.id, emoji).catch(() =>
6464+ Toast.show(_(msg`Failed to add emoji reaction`), {
6565+ type: 'error',
6666+ }),
6767+ )
6868 }
6969 },
7070 [_, convo, message, currentAccount?.did],
+7-3
src/components/dms/AfterReportDialog.tsx
···1313 useProfileBlockMutationQueue,
1414 useProfileQuery,
1515} from '#/state/queries/profile'
1616-import * as Toast from '#/view/com/util/Toast'
1716import {atoms as a, platform, useBreakpoints, useTheme, web} from '#/alf'
1817import {Button, ButtonText} from '#/components/Button'
1918import * as Dialog from '#/components/Dialog'
2019import * as Toggle from '#/components/forms/Toggle'
2120import {Loader} from '#/components/Loader'
2121+import * as Toast from '#/components/Toast'
2222import {Text} from '#/components/Typography'
2323import {IS_NATIVE} from '#/env'
2424···135135 }
136136 },
137137 onError: () => {
138138- Toast.show(_(msg`Could not leave chat`), 'xmark')
138138+ Toast.show(_(msg`Could not leave chat`), {
139139+ type: 'error',
140140+ })
139141 },
140142 })
141143···161163 leaveConvo()
162164 }
163165 if (toastMsg) {
164164- Toast.show(toastMsg, 'check')
166166+ Toast.show(toastMsg, {
167167+ type: 'success',
168168+ })
165169 }
166170 })
167171 }
+4-2
src/components/dms/ConvoMenu.tsx
···1818 unstableCacheProfileView,
1919 useProfileBlockMutationQueue,
2020} from '#/state/queries/profile'
2121-import * as Toast from '#/view/com/util/Toast'
2221import {type ViewStyleProp} from '#/alf'
2322import {atoms as a} from '#/alf'
2423import {Button, ButtonIcon} from '#/components/Button'
···4039import * as Menu from '#/components/Menu'
4140import {ReportDialog} from '#/components/moderation/ReportDialog'
4241import * as Prompt from '#/components/Prompt'
4242+import * as Toast from '#/components/Toast'
4343import type * as bsky from '#/types/bsky'
44444545let ConvoMenu = ({
···205205 }
206206 },
207207 onError: () => {
208208- Toast.show(_(msg`Could not mute chat`), 'xmark')
208208+ Toast.show(_(msg`Could not mute chat`), {
209209+ type: 'error',
210210+ })
209211 },
210212 })
211213
+4-2
src/components/dms/LeaveConvoPrompt.tsx
···4455import {type NavigationProp} from '#/lib/routes/types'
66import {useLeaveConvo} from '#/state/queries/messages/leave-conversation'
77-import * as Toast from '#/view/com/util/Toast'
87import {type DialogOuterProps} from '#/components/Dialog'
98import * as Prompt from '#/components/Prompt'
99+import * as Toast from '#/components/Toast'
1010import {IS_NATIVE} from '#/env'
11111212export function LeaveConvoPrompt({
···3232 }
3333 },
3434 onError: () => {
3535- Toast.show(_(msg`Could not leave chat`), 'xmark')
3535+ Toast.show(_(msg`Could not leave chat`), {
3636+ type: 'error',
3737+ })
3638 },
3739 })
3840
+9-7
src/components/dms/MessageContextMenu.tsx
···1212import {useLanguagePrefs} from '#/state/preferences'
1313import {unstableCacheProfileView} from '#/state/queries/unstable-profile-cache'
1414import {useSession} from '#/state/session'
1515-import * as Toast from '#/view/com/util/Toast'
1615import * as ContextMenu from '#/components/ContextMenu'
1716import {type TriggerProps} from '#/components/ContextMenu/types'
1817import {AfterReportDialog} from '#/components/dms/AfterReportDialog'
···2322import {ReportDialog} from '#/components/moderation/ReportDialog'
2423import * as Prompt from '#/components/Prompt'
2524import {usePromptControl} from '#/components/Prompt'
2525+import * as Toast from '#/components/Toast'
2626import {useAnalytics} from '#/analytics'
2727import {IS_NATIVE} from '#/env'
2828import {EmojiReactionPicker} from './EmojiReactionPicker'
···5858 )
59596060 void Clipboard.setStringAsync(str)
6161- Toast.show(_(msg`Copied to clipboard`), 'clipboard-check')
6161+ Toast.show(_(msg`Copied to clipboard`), {
6262+ type: 'success',
6363+ })
6264 }, [_, message.text, message.facets])
63656466 const onPressTranslateMessage = useCallback(() => {
···9597 .catch(() => Toast.show(_(msg`Failed to remove emoji reaction`)))
9698 } else {
9799 if (hasReachedReactionLimit(message, currentAccount?.did)) return
9898- convo
9999- .addReaction(message.id, emoji)
100100- .catch(() =>
101101- Toast.show(_(msg`Failed to add emoji reaction`), 'xmark'),
102102- )
100100+ convo.addReaction(message.id, emoji).catch(() =>
101101+ Toast.show(_(msg`Failed to add emoji reaction`), {
102102+ type: 'error',
103103+ }),
104104+ )
103105 }
104106 },
105107 [_, convo, message, currentAccount?.did],
+1-1
src/components/dms/MessageProfileButton.tsx
···1010import {type NavigationProp} from '#/lib/routes/types'
1111import {useGetConvoAvailabilityQuery} from '#/state/queries/messages/get-convo-availability'
1212import {useGetConvoForMembers} from '#/state/queries/messages/get-convo-for-members'
1313-import * as Toast from '#/view/com/util/Toast'
1413import {atoms as a, useTheme} from '#/alf'
1514import {Button, ButtonIcon} from '#/components/Button'
1615import {canBeMessaged} from '#/components/dms/util'
1716import {Message_Stroke2_Corner0_Rounded as Message} from '#/components/icons/Message'
1717+import * as Toast from '#/components/Toast'
1818import {useAnalytics} from '#/analytics'
19192020export function MessageProfileButton({
+4-2
src/components/dms/dialogs/NewChatDialog.tsx
···77import {logger} from '#/logger'
88import {useGetConvoForMembers} from '#/state/queries/messages/get-convo-for-members'
99import {FAB} from '#/view/com/util/fab/FAB'
1010-import * as Toast from '#/view/com/util/Toast'
1110import {useTheme} from '#/alf'
1211import * as Dialog from '#/components/Dialog'
1312import {SearchablePeopleList} from '#/components/dialogs/SearchablePeopleList'
1413import {PlusLarge_Stroke2_Corner0_Rounded as Plus} from '#/components/icons/Plus'
1414+import * as Toast from '#/components/Toast'
1515import {useAnalytics} from '#/analytics'
16161717export function NewChat({
···3737 },
3838 onError: error => {
3939 logger.error('Failed to create chat', {safeMessage: error})
4040- Toast.show(_(msg`An issue occurred starting the chat`), 'xmark')
4040+ Toast.show(_(msg`An issue occurred starting the chat`), {
4141+ type: 'error',
4242+ })
4143 },
4244 })
4345
+4-5
src/components/dms/dialogs/ShareViaChatDialog.tsx
···4455import {logger} from '#/logger'
66import {useGetConvoForMembers} from '#/state/queries/messages/get-convo-for-members'
77-import * as Toast from '#/view/com/util/Toast'
87import * as Dialog from '#/components/Dialog'
98import {SearchablePeopleList} from '#/components/dialogs/SearchablePeopleList'
99+import * as Toast from '#/components/Toast'
1010import {useAnalytics} from '#/analytics'
11111212export function SendViaChatDialog({
···4747 },
4848 onError: error => {
4949 logger.error('Failed to share post to chat', {message: error})
5050- Toast.show(
5151- _(msg`An issue occurred while trying to open the chat`),
5252- 'xmark',
5353- )
5050+ Toast.show(_(msg`An issue occurred while trying to open the chat`), {
5151+ type: 'error',
5252+ })
5453 },
5554 })
5655
+7-3
src/components/hooks/useFollowMethods.ts
···66import {type Shadow} from '#/state/cache/types'
77import {useProfileFollowMutationQueue} from '#/state/queries/profile'
88import {useRequireAuth} from '#/state/session'
99-import * as Toast from '#/view/com/util/Toast'
99+import * as Toast from '#/components/Toast'
1010import {type Metrics} from '#/analytics/metrics'
1111import type * as bsky from '#/types/bsky'
1212···3232 } catch (e: any) {
3333 logger.error(`useFollowMethods: failed to follow`, {message: String(e)})
3434 if (e?.name !== 'AbortError') {
3535- Toast.show(_(msg`An issue occurred, please try again.`), 'xmark')
3535+ Toast.show(_(msg`An issue occurred, please try again.`), {
3636+ type: 'error',
3737+ })
3638 }
3739 }
3840 })
···4749 message: String(e),
4850 })
4951 if (e?.name !== 'AbortError') {
5050- Toast.show(_(msg`An issue occurred, please try again.`), 'xmark')
5252+ Toast.show(_(msg`An issue occurred, please try again.`), {
5353+ type: 'error',
5454+ })
5155 }
5256 }
5357 })
+1-1
src/components/moderation/LabelsOnMeDialog.tsx
···1414import {sanitizeHandle} from '#/lib/strings/handles'
1515import {logger} from '#/logger'
1616import {useAgent, useSession} from '#/state/session'
1717-import * as Toast from '#/view/com/util/Toast'
1817import {atoms as a, useBreakpoints, useTheme} from '#/alf'
1918import {Button, ButtonIcon, ButtonText} from '#/components/Button'
2019import * as Dialog from '#/components/Dialog'
2120import {InlineLinkText} from '#/components/Link'
2121+import * as Toast from '#/components/Toast'
2222import {Text} from '#/components/Typography'
2323import {IS_ANDROID} from '#/env'
2424import {Admonition} from '../Admonition'
···77import {logger} from '#/logger'
88import {useModerationOpts} from '#/state/preferences/moderation-opts'
99import {useVerificationCreateMutation} from '#/state/queries/verification/useVerificationCreateMutation'
1010-import * as Toast from '#/view/com/util/Toast'
1110import {atoms as a, useBreakpoints} from '#/alf'
1211import {Admonition} from '#/components/Admonition'
1312import {Button, ButtonIcon, ButtonText} from '#/components/Button'
···1716import {Loader} from '#/components/Loader'
1817import * as ProfileCard from '#/components/ProfileCard'
1918import * as Prompt from '#/components/Prompt'
1919+import * as Toast from '#/components/Toast'
2020import type * as bsky from '#/types/bsky'
21212222export function VerificationCreatePrompt({
···5566import {logger} from '#/logger'
77import {useVerificationsRemoveMutation} from '#/state/queries/verification/useVerificationsRemoveMutation'
88-import * as Toast from '#/view/com/util/Toast'
98import {type DialogControlProps} from '#/components/Dialog'
109import * as Prompt from '#/components/Prompt'
1010+import * as Toast from '#/components/Toast'
1111import type * as bsky from '#/types/bsky'
12121313export {useDialogControl as usePromptControl} from '#/components/Dialog'
···3131 await remove({profile, verifications})
3232 Toast.show(_(msg`Removed verification`))
3333 } catch (e) {
3434- Toast.show(_(msg`Failed to remove verification`), 'xmark')
3434+ Toast.show(_(msg`Failed to remove verification`), {
3535+ type: 'error',
3636+ })
3537 logger.error('Failed to remove verification', {
3638 safeMessage: e,
3739 })
+1-1
src/features/liveNow/index.tsx
···2323} from '#/state/cache/profile-shadow'
2424import {useAgent, useSession} from '#/state/session'
2525import {useTickEveryMinute} from '#/state/shell'
2626-import * as Toast from '#/view/com/util/Toast'
2726import {useDialogContext} from '#/components/Dialog'
2727+import * as Toast from '#/components/Toast'
2828import {useAnalytics} from '#/analytics'
2929import {getLiveNowHost, getLiveServiceNames} from '#/features/liveNow/utils'
3030import type * as bsky from '#/types/bsky'
+7-9
src/lib/hooks/useAccountSwitcher.ts
···55import {logger} from '#/logger'
66import {type SessionAccount, useSessionApi} from '#/state/session'
77import {useLoggedOutViewControls} from '#/state/shell/logged-out'
88-import * as Toast from '#/view/com/util/Toast'
88+import * as Toast from '#/components/Toast'
99import {useAnalytics} from '#/analytics'
1010import {type Metrics} from '#/analytics/metrics'
1111import {IS_WEB} from '#/env'
···4242 Toast.show(_(msg`Signed in as @${account.handle}`))
4343 } else {
4444 requestSwitchToAccount({requestedAccount: account.did})
4545- Toast.show(
4646- _(msg`Please sign in as @${account.handle}`),
4747- 'circle-exclamation',
4848- )
4545+ Toast.show(_(msg`Please sign in as @${account.handle}`), {
4646+ type: 'warning',
4747+ })
4948 }
5049 } catch (e: any) {
5150 logger.error(`switch account: selectAccount failed`, {
5251 message: e.message,
5352 })
5453 requestSwitchToAccount({requestedAccount: account.did})
5555- Toast.show(
5656- _(msg`Please sign in as @${account.handle}`),
5757- 'circle-exclamation',
5858- )
5454+ Toast.show(_(msg`Please sign in as @${account.handle}`), {
5555+ type: 'warning',
5656+ })
5957 } finally {
6058 setPendingDid(null)
6159 }
+4-2
src/lib/media/picker.shared.ts
···66import {t} from '@lingui/core/macro'
7788import {type ImageMeta} from '#/state/gallery'
99-import * as Toast from '#/view/com/util/Toast'
99+import * as Toast from '#/components/Toast'
1010import {IS_IOS, IS_WEB} from '#/env'
1111import {VIDEO_MAX_DURATION_MS} from '../constants'
1212import {getDataUriSize} from './util'
···3030 return (response.assets ?? [])
3131 .filter(asset => {
3232 if (asset.mimeType?.startsWith('image/')) return true
3333- Toast.show(t`Only image files are supported`, 'exclamation-circle')
3333+ Toast.show(t`Only image files are supported`, {
3434+ type: 'warning',
3535+ })
3436 return false
3537 })
3638 .map(image => ({
+7-3
src/lib/sharing.ts
···33import {setStringAsync} from 'expo-clipboard'
44import {t} from '@lingui/core/macro'
5566-import * as Toast from '#/view/com/util/Toast'
66+import * as Toast from '#/components/Toast'
77import {IS_ANDROID, IS_IOS} from '#/env'
8899/**
···2121 // React Native Share is not supported by web. Web Share API
2222 // has increasing but not full support, so default to clipboard
2323 setStringAsync(url)
2424- Toast.show(t`Copied to clipboard`, 'clipboard-check')
2424+ Toast.show(t`Copied to clipboard`, {
2525+ type: 'success',
2626+ })
2527 }
2628}
2729···3739 await Share.share({message: text})
3840 } else {
3941 await setStringAsync(text)
4040- Toast.show(t`Copied to clipboard`, 'clipboard-check')
4242+ Toast.show(t`Copied to clipboard`, {
4343+ type: 'success',
4444+ })
4145 }
4246}
+1-1
src/screens/List/ListHiddenScreen.tsx
···1919 useRemoveFeedMutation,
2020} from '#/state/queries/preferences'
2121import {useSession} from '#/state/session'
2222-import * as Toast from '#/view/com/util/Toast'
2322import {CenteredView} from '#/view/com/util/Views'
2423import {atoms as a, useBreakpoints, useTheme} from '#/alf'
2524import {Button, ButtonIcon, ButtonText} from '#/components/Button'
2625import {EyeSlash_Stroke2_Corner0_Rounded as EyeSlash} from '#/components/icons/EyeSlash'
2726import {Loader} from '#/components/Loader'
2827import {useHider} from '#/components/moderation/Hider'
2828+import * as Toast from '#/components/Toast'
2929import {Text} from '#/components/Typography'
30303131export function ListHiddenScreen({
+1-1
src/screens/Login/ChooseAccountForm.tsx
···77import {logger} from '#/logger'
88import {type SessionAccount, useSession, useSessionApi} from '#/state/session'
99import {useLoggedOutViewControls} from '#/state/shell/logged-out'
1010-import * as Toast from '#/view/com/util/Toast'
1110import {atoms as a, web} from '#/alf'
1211import {AccountList} from '#/components/AccountList'
1312import {Button, ButtonText} from '#/components/Button'
1413import * as TextField from '#/components/forms/TextField'
1414+import * as Toast from '#/components/Toast'
1515import {useAnalytics} from '#/analytics'
1616import {IS_WEB} from '#/env'
1717import {FormContainer} from './FormContainer'
+13-5
src/screens/Messages/Inbox.tsx
···3030import {FAB} from '#/view/com/util/fab/FAB'
3131import {List} from '#/view/com/util/List'
3232import {ChatListLoadingPlaceholder} from '#/view/com/util/LoadingPlaceholder'
3333-import * as Toast from '#/view/com/util/Toast'
3433import {atoms as a, useBreakpoints, useTheme} from '#/alf'
3534import {AgeRestrictedScreen} from '#/components/ageAssurance/AgeRestrictedScreen'
3635import {useAgeAssuranceCopy} from '#/components/ageAssurance/useAgeAssuranceCopy'
···4342import {Message_Stroke2_Corner0_Rounded as MessageIcon} from '#/components/icons/Message'
4443import * as Layout from '#/components/Layout'
4544import {ListFooter} from '#/components/Lists'
4545+import * as Toast from '#/components/Toast'
4646import {Text} from '#/components/Typography'
4747import {IS_NATIVE} from '#/env'
4848import {RequestListItem} from './components/RequestListItem'
···313313 const t = useTheme()
314314 const {mutate: markAllRead} = useUpdateAllRead('request', {
315315 onMutate: () => {
316316- Toast.show(_(msg`Marked all as read`), 'check')
316316+ Toast.show(_(msg`Marked all as read`), {
317317+ type: 'success',
318318+ })
317319 },
318320 onError: () => {
319319- Toast.show(_(msg`Failed to mark all requests as read`), 'xmark')
321321+ Toast.show(_(msg`Failed to mark all requests as read`), {
322322+ type: 'error',
323323+ })
320324 },
321325 })
322326···336340 const {_} = useLingui()
337341 const {mutate: markAllRead} = useUpdateAllRead('request', {
338342 onMutate: () => {
339339- Toast.show(_(msg`Marked all as read`), 'check')
343343+ Toast.show(_(msg`Marked all as read`), {
344344+ type: 'success',
345345+ })
340346 },
341347 onError: () => {
342342- Toast.show(_(msg`Failed to mark all requests as read`), 'xmark')
348348+ Toast.show(_(msg`Failed to mark all requests as read`), {
349349+ type: 'error',
350350+ })
343351 },
344352 })
345353
+4-2
src/screens/Messages/Settings.tsx
···99import {useUpdateActorDeclaration} from '#/state/queries/messages/actor-declaration'
1010import {useProfileQuery} from '#/state/queries/profile'
1111import {useSession} from '#/state/session'
1212-import * as Toast from '#/view/com/util/Toast'
1312import {atoms as a} from '#/alf'
1413import {Admonition} from '#/components/Admonition'
1514import {Divider} from '#/components/Divider'
1615import * as Toggle from '#/components/forms/Toggle'
1716import * as Layout from '#/components/Layout'
1717+import * as Toast from '#/components/Toast'
1818import {Text} from '#/components/Typography'
1919import {IS_NATIVE} from '#/env'
2020import {useBackgroundNotificationPreferences} from '../../../modules/expo-background-notification-handler/src/BackgroundNotificationHandlerProvider'
···37373838 const {mutate: updateDeclaration} = useUpdateActorDeclaration({
3939 onError: () => {
4040- Toast.show(_(msg`Failed to update settings`), 'xmark')
4040+ Toast.show(_(msg`Failed to update settings`), {
4141+ type: 'error',
4242+ })
4143 },
4244 })
4345
+4-2
src/screens/Messages/components/ChatDisabled.tsx
···99import {BLUESKY_MOD_SERVICE_HEADERS} from '#/lib/constants'
1010import {logger} from '#/logger'
1111import {useAgent, useSession} from '#/state/session'
1212-import * as Toast from '#/view/com/util/Toast'
1312import {atoms as a, useBreakpoints, useTheme} from '#/alf'
1413import {Button, ButtonIcon, ButtonText} from '#/components/Button'
1514import * as Dialog from '#/components/Dialog'
1615import {Loader} from '#/components/Loader'
1616+import * as Toast from '#/components/Toast'
1717import {Text} from '#/components/Typography'
18181919export function ChatDisabled() {
···9797 },
9898 onError: err => {
9999 logger.error('Failed to submit chat appeal', {message: err})
100100- Toast.show(_(msg`Failed to submit appeal, please try again.`), 'xmark')
100100+ Toast.show(_(msg`Failed to submit appeal, please try again.`), {
101101+ type: 'error',
102102+ })
101103 },
102104 onSuccess: () => {
103105 control.close()
+4-2
src/screens/Messages/components/MessageInput.tsx
···2424 useSaveMessageDraft,
2525} from '#/state/messages/message-drafts'
2626import {type EmojiPickerPosition} from '#/view/com/composer/text-input/web/EmojiPicker'
2727-import * as Toast from '#/view/com/util/Toast'
2827import {android, atoms as a, useTheme} from '#/alf'
2928import {useSharedInputStyles} from '#/components/forms/TextField'
3029import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlane} from '#/components/icons/PaperPlane'
3030+import * as Toast from '#/components/Toast'
3131import {IS_IOS, IS_WEB} from '#/env'
3232import {useExtractEmbedFromFacets} from './MessageInputEmbed'
3333···7676 return
7777 }
7878 if (countGraphemes(message) > MAX_DM_GRAPHEME_LENGTH) {
7979- Toast.show(_(msg`Message is too long`), 'xmark')
7979+ Toast.show(_(msg`Message is too long`), {
8080+ type: 'error',
8181+ })
8082 return
8183 }
8284 clearDraft()
···1717 type Emoji,
1818 type EmojiPickerPosition,
1919} from '#/view/com/composer/text-input/web/EmojiPicker'
2020-import * as Toast from '#/view/com/util/Toast'
2120import {atoms as a, flatten, useTheme} from '#/alf'
2221import {Button} from '#/components/Button'
2322import {useSharedInputStyles} from '#/components/forms/TextField'
2423import {EmojiArc_Stroke2_Corner0_Rounded as EmojiSmile} from '#/components/icons/Emoji'
2524import {PaperPlane_Stroke2_Corner0_Rounded as PaperPlane} from '#/components/icons/PaperPlane'
2525+import * as Toast from '#/components/Toast'
2626import {IS_WEB_SAFARI, IS_WEB_TOUCH_DEVICE} from '#/env'
2727import {useExtractEmbedFromFacets} from './MessageInputEmbed'
2828···5757 return
5858 }
5959 if (countGraphemes(message) > MAX_DM_GRAPHEME_LENGTH) {
6060- Toast.show(_(msg`Message is too long`), 'xmark')
6060+ Toast.show(_(msg`Message is too long`), {
6161+ type: 'error',
6262+ })
6163 return
6264 }
6365 clearDraft()
···1616 threadgateAllowUISettingToAllowRecordValue,
1717 threadgateRecordToAllowUISetting,
1818} from '#/state/queries/threadgate'
1919-import * as Toast from '#/view/com/util/Toast'
2019import {atoms as a, useGutters} from '#/alf'
2120import {Admonition} from '#/components/Admonition'
2221import {PostInteractionSettingsForm} from '#/components/dialogs/PostInteractionSettingsDialog'
2322import * as Layout from '#/components/Layout'
2423import {Loader} from '#/components/Loader'
2424+import * as Toast from '#/components/Toast'
25252626export function Screen() {
2727 const gutters = useGutters(['base'])
···1212 useProfileQuery,
1313} from '#/state/queries/profile'
1414import {useRequireAuth} from '#/state/session'
1515-import * as Toast from '#/view/com/util/Toast'
1615import {atoms as a, useBreakpoints} from '#/alf'
1716import {Button, ButtonIcon, ButtonText} from '#/components/Button'
1817import {Check_Stroke2_Corner0_Rounded as CheckIcon} from '#/components/icons/Check'
1918import {PlusLarge_Stroke2_Corner0_Rounded as PlusIcon} from '#/components/icons/Plus'
1919+import * as Toast from '#/components/Toast'
2020import {IS_IOS} from '#/env'
2121import {GrowthHack} from './GrowthHack'
2222···114114 } catch (e: any) {
115115 if (e?.name !== 'AbortError') {
116116 logger.error('Failed to follow', {message: String(e)})
117117- Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark')
117117+ Toast.show(_(msg`There was an issue! ${e.toString()}`), {
118118+ type: 'error',
119119+ })
118120 }
119121 }
120122 })
···125127 } catch (e: any) {
126128 if (e?.name !== 'AbortError') {
127129 logger.error('Failed to unfollow', {message: String(e)})
128128- Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark')
130130+ Toast.show(_(msg`There was an issue! ${e.toString()}`), {
131131+ type: 'error',
132132+ })
129133 }
130134 }
131135 })
+1-1
src/screens/Profile/Header/EditProfileDialog.tsx
···1212import {type ImageMeta} from '#/state/gallery'
1313import {useProfileUpdateMutation} from '#/state/queries/profile'
1414import {ErrorMessage} from '#/view/com/util/error/ErrorMessage'
1515-import * as Toast from '#/view/com/util/Toast'
1615import {EditableUserAvatar} from '#/view/com/util/UserAvatar'
1716import {UserBanner} from '#/view/com/util/UserBanner'
1817import {atoms as a, useTheme} from '#/alf'
···2322import {InlineLinkText} from '#/components/Link'
2423import {Loader} from '#/components/Loader'
2524import * as Prompt from '#/components/Prompt'
2525+import * as Toast from '#/components/Toast'
2626import {Text} from '#/components/Typography'
2727import {useSimpleVerificationState} from '#/components/verification'
2828
···2121} from '#/state/queries/preferences'
2222import {useSession} from '#/state/session'
2323import {formatCount} from '#/view/com/util/numeric/format'
2424-import * as Toast from '#/view/com/util/Toast'
2524import {UserAvatar} from '#/view/com/util/UserAvatar'
2625import {atoms as a, useBreakpoints, useTheme, web} from '#/alf'
2726import {Button, ButtonIcon, ButtonText} from '#/components/Button'
···5049 useReportDialogControl,
5150} from '#/components/moderation/ReportDialog'
5251import {RichText} from '#/components/RichText'
5252+import * as Toast from '#/components/Toast'
5353import {Text} from '#/components/Typography'
5454import {useAnalytics} from '#/analytics'
5555import {IS_WEB} from '#/env'
···139139 _(
140140 msg`There was an issue updating your feeds, please check your internet connection and try again.`,
141141 ),
142142- 'xmark',
142142+ {
143143+ type: 'error',
144144+ },
143145 )
144146 logger.error('Failed to update feeds', {message: err})
145147 }
···177179 ax.metric('feed:pin', {feedUrl: info.uri})
178180 }
179181 } catch (e) {
180180- Toast.show(_(msg`There was an issue contacting the server`), 'xmark')
182182+ Toast.show(_(msg`There was an issue contacting the server`), {
183183+ type: 'error',
184184+ })
181185 logger.error('Failed to toggle pinned feed', {message: e})
182186 }
183187 }
···421425 _(
422426 msg`There was an issue contacting the server, please check your internet connection and try again.`,
423427 ),
424424- 'xmark',
428428+ {
429429+ type: 'error',
430430+ },
425431 )
426432 logger.error('Failed to toggle like', {message: err})
427433 }
+7-3
src/screens/SavedFeeds.tsx
···2525import {type UsePreferencesQueryResponse} from '#/state/queries/preferences/types'
2626import {useSetMinimalShellMode} from '#/state/shell'
2727import {FeedSourceCard} from '#/view/com/feeds/FeedSourceCard'
2828-import * as Toast from '#/view/com/util/Toast'
2928import {NoFollowingFeed} from '#/screens/Feeds/NoFollowingFeed'
3029import {NoSavedFeedsOfAnyType} from '#/screens/Feeds/NoSavedFeedsOfAnyType'
3130import {atoms as a, useBreakpoints, useTheme} from '#/alf'
···4342import * as Layout from '#/components/Layout'
4443import {InlineLinkText} from '#/components/Link'
4544import {Loader} from '#/components/Loader'
4545+import * as Toast from '#/components/Toast'
4646import {Text} from '#/components/Typography'
47474848type Props = NativeStackScreenProps<CommonNavigatorParams, 'SavedFeeds'>
···104104 navigation.navigate('Feeds')
105105 }
106106 } catch (e) {
107107- Toast.show(_(msg`There was an issue contacting the server`), 'xmark')
107107+ Toast.show(_(msg`There was an issue contacting the server`), {
108108+ type: 'error',
109109+ })
108110 logger.error('Failed to toggle pinned feed', {message: e})
109111 }
110112 }
···288290 navigation.navigate('Feeds')
289291 }
290292 } catch (e) {
291291- Toast.show(_(msg`There was an issue contacting the server`), 'xmark')
293293+ Toast.show(_(msg`There was an issue contacting the server`), {
294294+ type: 'error',
295295+ })
292296 logger.error('Failed to toggle pinned feed', {message: e})
293297 }
294298 }
+1-1
src/screens/Settings/AboutSettings.tsx
···10101111import {STATUS_PAGE_URL} from '#/lib/constants'
1212import {type CommonNavigatorParams} from '#/lib/routes/types'
1313-import * as Toast from '#/view/com/util/Toast'
1413import * as SettingsList from '#/screens/Settings/components/SettingsList'
1514import {Atom_Stroke2_Corner0_Rounded as AtomIcon} from '#/components/icons/Atom'
1615import {BroomSparkle_Stroke2_Corner2_Rounded as BroomSparkleIcon} from '#/components/icons/BroomSparkle'
···2019import {Wrench_Stroke2_Corner2_Rounded as WrenchIcon} from '#/components/icons/Wrench'
2120import * as Layout from '#/components/Layout'
2221import {Loader} from '#/components/Loader'
2222+import * as Toast from '#/components/Toast'
2323import {getDeviceId} from '#/analytics/identifiers'
2424import {IS_ANDROID, IS_IOS, IS_NATIVE} from '#/env'
2525import * as env from '#/env'
+1-1
src/screens/Settings/AppPasswords.tsx
···2020} from '#/state/queries/app-passwords'
2121import {EmptyState} from '#/view/com/util/EmptyState'
2222import {ErrorScreen} from '#/view/com/util/error/ErrorScreen'
2323-import * as Toast from '#/view/com/util/Toast'
2423import {atoms as a, useTheme} from '#/alf'
2524import {Admonition} from '#/components/Admonition'
2625import {Button, ButtonIcon, ButtonText} from '#/components/Button'
···3231import * as Layout from '#/components/Layout'
3332import {Loader} from '#/components/Loader'
3433import * as Prompt from '#/components/Prompt'
3434+import * as Toast from '#/components/Toast'
3535import {Text} from '#/components/Typography'
3636import {AddAppPasswordDialog} from './components/AddAppPasswordDialog'
3737import * as SettingsList from './components/SettingsList'
+4-2
src/screens/Settings/InterestsSettings.tsx
···2222import {createGetSuggestedUsersQueryKey} from '#/state/queries/trending/useGetSuggestedUsersQuery'
2323import {createSuggestedStarterPacksQueryKey} from '#/state/queries/useSuggestedStarterPacksQuery'
2424import {useAgent} from '#/state/session'
2525-import * as Toast from '#/view/com/util/Toast'
2625import {atoms as a, useGutters, useTheme} from '#/alf'
2726import {Admonition} from '#/components/Admonition'
2827import {Divider} from '#/components/Divider'
2928import * as Toggle from '#/components/forms/Toggle'
3029import * as Layout from '#/components/Layout'
3130import {Loader} from '#/components/Loader'
3131+import * as Toast from '#/components/Toast'
3232import {Text} from '#/components/Typography'
33333434type Props = NativeStackScreenProps<CommonNavigatorParams, 'InterestsSettings'>
···139139 context: 'toast',
140140 }),
141141 ),
142142- 'xmark',
142142+ {
143143+ type: 'error',
144144+ },
143145 )
144146 } finally {
145147 setIsSaving(false)
+4-3
src/screens/Settings/Settings.tsx
···2828import {useOnboardingDispatch} from '#/state/shell'
2929import {useLoggedOutViewControls} from '#/state/shell/logged-out'
3030import {useCloseAllActiveElements} from '#/state/util'
3131-import * as Toast from '#/view/com/util/Toast'
3231import {UserAvatar} from '#/view/com/util/UserAvatar'
3332import * as SettingsList from '#/screens/Settings/components/SettingsList'
3433import {atoms as a, platform, tokens, useBreakpoints, useTheme} from '#/alf'
···6362import {ID as PolicyUpdate202508} from '#/components/PolicyUpdateOverlay/updates/202508/config'
6463import {ProfileBadges} from '#/components/ProfileBadges'
6564import * as Prompt from '#/components/Prompt'
6565+import * as Toast from '#/components/Toast'
6666import {Text} from '#/components/Typography'
6767import {useAnalytics} from '#/analytics'
6868import {IS_INTERNAL, IS_IOS, IS_NATIVE} from '#/env'
···520520 </SettingsList.ItemText>
521521 </SettingsList.PressableItem>
522522 ) : null}
523523-524523 <SettingsList.Divider />
525524 <View style={[a.p_xl, a.gap_md]}>
526525 <Text style={[a.text_lg, a.font_semi_bold]}>
···545544 onPress={() => {
546545 device.set([PolicyUpdate202508], false)
547546 agent.bskyAppRemoveNuxs([PolicyUpdate202508])
548548- Toast.show(`Done`, 'info')
547547+ Toast.show(`Done`, {
548548+ type: 'info',
549549+ })
549550 }}
550551 label="Reset policy update nux"
551552 color="secondary"
···77import {cleanError} from '#/lib/strings/errors'
88import {useAgent, useSession} from '#/state/session'
99import {ErrorMessage} from '#/view/com/util/error/ErrorMessage'
1010-import * as Toast from '#/view/com/util/Toast'
1110import {atoms as a, useBreakpoints, useTheme} from '#/alf'
1211import {Button, ButtonIcon, ButtonText} from '#/components/Button'
1312import * as Dialog from '#/components/Dialog'
1413import * as TextField from '#/components/forms/TextField'
1514import {Lock_Stroke2_Corner0_Rounded as Lock} from '#/components/icons/Lock'
1615import {Loader} from '#/components/Loader'
1616+import * as Toast from '#/components/Toast'
1717import {P, Text} from '#/components/Typography'
1818import {IS_NATIVE} from '#/env'
1919
+4-2
src/screens/Settings/components/OTAInfo.tsx
···44import {Trans} from '@lingui/react/macro'
55import {useMutation, useQuery} from '@tanstack/react-query'
6677-import * as Toast from '#/view/com/util/Toast'
87import {Button, ButtonIcon, ButtonText} from '#/components/Button'
98import {ArrowRotateCounterClockwise_Stroke2_Corner0_Rounded as RetryIcon} from '#/components/icons/ArrowRotate'
109import {Shapes_Stroke2_Corner0_Rounded as ShapesIcon} from '#/components/icons/Shapes'
1110import {Loader} from '#/components/Loader'
1111+import * as Toast from '#/components/Toast'
1212import * as SettingsList from '../components/SettingsList'
13131414export function OTAInfo() {
···3434 await Updates.reloadAsync()
3535 },
3636 onError: error =>
3737- Toast.show(`Failed to update: ${error.message}`, 'xmark'),
3737+ Toast.show(`Failed to update: ${error.message}`, {
3838+ type: 'error',
3939+ }),
3840 })
39414042 if (!Updates.isEnabled || __DEV__) {
+10-4
src/screens/StarterPack/StarterPackScreen.tsx
···4646import {useSetActiveStarterPack} from '#/state/shell/starter-pack'
4747import {PagerWithHeader} from '#/view/com/pager/PagerWithHeader'
4848import {ProfileSubpageHeader} from '#/view/com/profile/ProfileSubpageHeader'
4949-import * as Toast from '#/view/com/util/Toast'
5049import {bulkWriteFollows} from '#/screens/Onboarding/util'
5150import {atoms as a, useBreakpoints, useTheme} from '#/alf'
5251import {Button, ButtonIcon, ButtonText} from '#/components/Button'
···7473import {ProfilesList} from '#/components/StarterPack/Main/ProfilesList'
7574import {QrCodeDialog} from '#/components/StarterPack/QrCodeDialog'
7675import {ShareDialog} from '#/components/StarterPack/ShareDialog'
7676+import * as Toast from '#/components/Toast'
7777import {Text} from '#/components/Typography'
7878import {useAnalytics} from '#/analytics'
7979import {IS_WEB} from '#/env'
···356356 listItems = await getAllListMembers(agent, starterPack.list.uri)
357357 } catch (e) {
358358 setIsProcessing(false)
359359- Toast.show(_(msg`An error occurred while trying to follow all`), 'xmark')
359359+ Toast.show(_(msg`An error occurred while trying to follow all`), {
360360+ type: 'error',
361361+ })
360362 logger.error('Failed to get list members for starter pack', {
361363 safeMessage: e,
362364 })
···381383 })
382384 } catch (e) {
383385 setIsProcessing(false)
384384- Toast.show(_(msg`An error occurred while trying to follow all`), 'xmark')
386386+ Toast.show(_(msg`An error occurred while trying to follow all`), {
387387+ type: 'error',
388388+ })
385389 logger.error('Failed to follow all accounts', {safeMessage: e})
386390 }
387391···749753 onError: e => {
750754 setIsProcessing(false)
751755 logger.error('Failed to delete invalid starter pack', {safeMessage: e})
752752- Toast.show(_(msg`Failed to delete starter pack`), 'xmark')
756756+ Toast.show(_(msg`Failed to delete starter pack`), {
757757+ type: 'error',
758758+ })
753759 },
754760 })
755761
+7-3
src/screens/StarterPack/Wizard/State.tsx
···77import {msg, plural} from '@lingui/core/macro'
8899import {STARTER_PACK_MAX_SIZE} from '#/lib/constants'
1010-import * as Toast from '#/view/com/util/Toast'
1010+import * as Toast from '#/components/Toast'
1111import * as bsky from '#/types/bsky'
12121313const steps = ['Details', 'Profiles', 'Feeds'] as const
···8080 msg`You may only add up to ${plural(STARTER_PACK_MAX_SIZE, {
8181 other: `${STARTER_PACK_MAX_SIZE} profiles`,
8282 })}`.message ?? '',
8383- 'info',
8383+ {
8484+ type: 'info',
8585+ },
8486 )
8587 } else {
8688 updatedState = {...state, profiles: [...state.profiles, action.profile]}
···9698 break
9799 case 'AddFeed':
98100 if (state.feeds.length >= 3) {
9999- Toast.show(msg`You may only add up to 3 feeds`.message ?? '', 'info')
101101+ Toast.show(msg`You may only add up to 3 feeds`.message ?? '', {
102102+ type: 'info',
103103+ })
100104 } else {
101105 updatedState = {...state, feeds: [...state.feeds, action.feed]}
102106 }
+7-3
src/screens/StarterPack/Wizard/index.tsx
···4040} from '#/state/queries/starter-packs'
4141import {useSession} from '#/state/session'
4242import {useSetMinimalShellMode} from '#/state/shell'
4343-import * as Toast from '#/view/com/util/Toast'
4443import {UserAvatar} from '#/view/com/util/UserAvatar'
4544import {
4645 useWizardState,
···5655import {ListMaybePlaceholder} from '#/components/Lists'
5756import {Loader} from '#/components/Loader'
5857import {WizardEditListDialog} from '#/components/StarterPack/Wizard/WizardEditListDialog'
5858+import * as Toast from '#/components/Toast'
5959import {Text} from '#/components/Typography'
6060import {useAnalytics} from '#/analytics'
6161import {IS_NATIVE} from '#/env'
···258258 onError: e => {
259259 logger.error('Failed to create starter pack', {safeMessage: e})
260260 dispatch({type: 'SetProcessing', processing: false})
261261- Toast.show(_(msg`Failed to create starter pack`), 'xmark')
261261+ Toast.show(_(msg`Failed to create starter pack`), {
262262+ type: 'error',
263263+ })
262264 },
263265 })
264266 const {mutate: editStarterPack} = useEditStarterPackMutation({
···266268 onError: e => {
267269 logger.error('Failed to edit starter pack', {safeMessage: e})
268270 dispatch({type: 'SetProcessing', processing: false})
269269- Toast.show(_(msg`Failed to create starter pack`), 'xmark')
271271+ Toast.show(_(msg`Failed to create starter pack`), {
272272+ type: 'error',
273273+ })
270274 },
271275 })
272276
+1-1
src/state/queries/activity-subscriptions.ts
···1414} from '@tanstack/react-query'
15151616import {useAgent, useSession} from '#/state/session'
1717-import * as Toast from '#/view/com/util/Toast'
1717+import * as Toast from '#/components/Toast'
18181919export const RQKEY_getActivitySubscriptions = ['activity-subscriptions']
2020export const RQKEY_getNotificationDeclaration = ['notification-declaration']
+4-2
src/state/queries/notifications/settings.ts
···991010import {logger} from '#/logger'
1111import {useAgent} from '#/state/session'
1212-import * as Toast from '#/view/com/util/Toast'
1212+import * as Toast from '#/components/Toast'
13131414const RQKEY_ROOT = 'notification-settings'
1515const RQKEY = [RQKEY_ROOT]
···4646 onError: e => {
4747 logger.error('Could not update notification settings', {message: e})
4848 queryClient.invalidateQueries({queryKey: RQKEY})
4949- Toast.show(t`Could not update notification settings`, 'xmark')
4949+ Toast.show(t`Could not update notification settings`, {
5050+ type: 'error',
5151+ })
5052 },
5153 })
5254}
+1-1
src/state/queries/pinned-post.ts
···4455import {logger} from '#/logger'
66import {RQKEY as FEED_RQKEY} from '#/state/queries/post-feed'
77-import * as Toast from '#/view/com/util/Toast'
77+import * as Toast from '#/components/Toast'
88import {updatePostShadow} from '../cache/post-shadow'
99import {useAgent, useSession} from '../session'
1010import {useProfileUpdateMutation} from './profile'
+4-5
src/state/shell/composer/index.tsx
···1818 RQKEY_LINK_ROOT,
1919} from '#/state/queries/resolve-link'
2020import {type EmojiPickerPosition} from '#/view/com/composer/text-input/web/EmojiPicker'
2121-import * as Toast from '#/view/com/util/Toast'
2121+import * as Toast from '#/components/Toast'
22222323export interface ComposerOptsPostRef {
2424 uri: string
···104104 author.viewer?.blockingByList),
105105 )
106106 if (isBlocked) {
107107- Toast.show(
108108- _(msg`Cannot interact with a blocked user`),
109109- 'exclamation-circle',
110110- )
107107+ Toast.show(_(msg`Cannot interact with a blocked user`), {
108108+ type: 'warning',
109109+ })
111110 } else {
112111 setState(prevOpts => {
113112 if (prevOpts) {
···55import {Trans} from '@lingui/react/macro'
6677import {logger} from '#/logger'
88-import * as Toast from '#/view/com/util/Toast'
98import {atoms as a} from '#/alf'
109import {Button, ButtonIcon, ButtonText} from '#/components/Button'
1110import {CC_Stroke2_Corner0_Rounded as CCIcon} from '#/components/icons/CC'
1111+import * as Toast from '#/components/Toast'
12121313export function SubtitleFilePicker({
1414 onSelectFile,
+4-2
src/view/com/composer/videos/VideoPreview.web.tsx
···77import {clamp} from '#/lib/numbers'
88import {useAutoplayDisabled} from '#/state/preferences'
99import {ExternalEmbedRemoveBtn} from '#/view/com/composer/ExternalEmbedRemoveBtn'
1010-import * as Toast from '#/view/com/util/Toast'
1110import {atoms as a} from '#/alf'
1111+import * as Toast from '#/components/Toast'
1212import {PlayButtonIcon} from '#/components/video/PlayButtonIcon'
13131414export function VideoPreview({
···6363 playsInline
6464 onError={err => {
6565 console.error('Error loading video', err)
6666- Toast.show(_(msg`Could not process your video`), 'xmark')
6666+ Toast.show(_(msg`Could not process your video`), {
6767+ type: 'error',
6868+ })
6769 clear()
6870 }}
6971 />
···4444import {Post} from '#/view/com/post/Post'
4545import {formatCount} from '#/view/com/util/numeric/format'
4646import {TimeElapsed} from '#/view/com/util/TimeElapsed'
4747-import * as Toast from '#/view/com/util/Toast'
4847import {PreviewableUserAvatar, UserAvatar} from '#/view/com/util/UserAvatar'
4948import {atoms as a, platform, useTheme} from '#/alf'
5049import {Button, ButtonIcon, ButtonText} from '#/components/Button'
···6766import {ProfileHoverCard} from '#/components/ProfileHoverCard'
6867import {Notification as StarterPackCard} from '#/components/StarterPack/StarterPackCard'
6968import {SubtleHover} from '#/components/SubtleHover'
6969+import * as Toast from '#/components/Toast'
7070import {Text} from '#/components/Typography'
7171import * as bsky from '#/types/bsky'
7272···769769 )
770770 } catch (err: any) {
771771 if (err?.name !== 'AbortError') {
772772- Toast.show(_(msg`An issue occurred, please try again.`), 'xmark')
772772+ Toast.show(_(msg`An issue occurred, please try again.`), {
773773+ type: 'error',
774774+ })
773775 }
774776 }
775777 }
···789791 )
790792 } catch (err: any) {
791793 if (err?.name !== 'AbortError') {
792792- Toast.show(_(msg`An issue occurred, please try again.`), 'xmark')
794794+ Toast.show(_(msg`An issue occurred, please try again.`), {
795795+ type: 'error',
796796+ })
793797 }
794798 }
795799 }
+7-3
src/view/com/posts/FeedShutdownMsg.tsx
···1212 useReplaceForYouWithDiscoverFeedMutation,
1313} from '#/state/queries/preferences'
1414import {useSetSelectedFeed} from '#/state/shell/selected-feed'
1515-import * as Toast from '#/view/com/util/Toast'
1615import {atoms as a, useTheme} from '#/alf'
1716import {Button, ButtonIcon, ButtonText} from '#/components/Button'
1817import {InlineLinkText} from '#/components/Link'
1918import {Loader} from '#/components/Loader'
1919+import * as Toast from '#/components/Toast'
2020import {Text} from '#/components/Typography'
21212222export function FeedShutdownMsg({feedUri}: {feedUri: string}) {
···5252 _(
5353 msg`There was an issue updating your feeds, please check your internet connection and try again.`,
5454 ),
5555- 'exclamation-circle',
5555+ {
5656+ type: 'warning',
5757+ },
5658 )
5759 logger.error('Failed to update feeds', {message: err})
5860 }
···7173 _(
7274 msg`There was an issue updating your feeds, please check your internet connection and try again.`,
7375 ),
7474- 'exclamation-circle',
7676+ {
7777+ type: 'warning',
7878+ },
7579 )
7680 logger.error('Failed to update feeds', {message: err})
7781 }
+19-7
src/view/com/profile/ProfileMenu.tsx
···2222} from '#/state/queries/profile'
2323import {useSession} from '#/state/session'
2424import {EventStopper} from '#/view/com/util/EventStopper'
2525-import * as Toast from '#/view/com/util/Toast'
2625import {atoms as a, useTheme} from '#/alf'
2726import {Button, ButtonIcon} from '#/components/Button'
2827import {useDialogControl} from '#/components/Dialog'
···5251 useReportDialogControl,
5352} from '#/components/moderation/ReportDialog'
5453import * as Prompt from '#/components/Prompt'
5454+import * as Toast from '#/components/Toast'
5555import {useFullVerificationState} from '#/components/verification'
5656import {VerificationCreatePrompt} from '#/components/verification/VerificationCreatePrompt'
5757import {VerificationRemovePrompt} from '#/components/verification/VerificationRemovePrompt'
···149149 } catch (e: any) {
150150 if (e?.name !== 'AbortError') {
151151 ax.logger.error('Failed to unmute account', {message: e})
152152- Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark')
152152+ Toast.show(_(msg`There was an issue! ${e.toString()}`), {
153153+ type: 'error',
154154+ })
153155 }
154156 }
155157 } else {
···159161 } catch (e: any) {
160162 if (e?.name !== 'AbortError') {
161163 ax.logger.error('Failed to mute account', {message: e})
162162- Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark')
164164+ Toast.show(_(msg`There was an issue! ${e.toString()}`), {
165165+ type: 'error',
166166+ })
163167 }
164168 }
165169 }
···173177 } catch (e: any) {
174178 if (e?.name !== 'AbortError') {
175179 ax.logger.error('Failed to unblock account', {message: e})
176176- Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark')
180180+ Toast.show(_(msg`There was an issue! ${e.toString()}`), {
181181+ type: 'error',
182182+ })
177183 }
178184 }
179185 } else {
···183189 } catch (e: any) {
184190 if (e?.name !== 'AbortError') {
185191 ax.logger.error('Failed to block account', {message: e})
186186- Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark')
192192+ Toast.show(_(msg`There was an issue! ${e.toString()}`), {
193193+ type: 'error',
194194+ })
187195 }
188196 }
189197 }
···196204 } catch (e: any) {
197205 if (e?.name !== 'AbortError') {
198206 ax.logger.error('Failed to follow account', {message: e})
199199- Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark')
207207+ Toast.show(_(msg`There was an issue! ${e.toString()}`), {
208208+ type: 'error',
209209+ })
200210 }
201211 }
202212 }, [_, ax, queueFollow])
···208218 } catch (e: any) {
209219 if (e?.name !== 'AbortError') {
210220 ax.logger.error('Failed to unfollow account', {message: e})
211211- Toast.show(_(msg`There was an issue! ${e.toString()}`), 'xmark')
221221+ Toast.show(_(msg`There was an issue! ${e.toString()}`), {
222222+ type: 'error',
223223+ })
212224 }
213225 }
214226 }, [_, ax, queueUnfollow])
+1-1
src/view/screens/Debug.tsx
···1616import {Button} from '#/view/com/util/forms/Button'
1717import * as LoadingPlaceholder from '#/view/com/util/LoadingPlaceholder'
1818import {Text} from '#/view/com/util/text/Text'
1919-import * as Toast from '#/view/com/util/Toast'
2019import {ViewHeader} from '#/view/com/util/ViewHeader'
2120import {ViewSelector} from '#/view/com/util/ViewSelector'
2221import {HashtagWide_Stroke1_Corner0_Rounded as HashtagWideIcon} from '#/components/icons/Hashtag'
2322import * as Layout from '#/components/Layout'
2323+import * as Toast from '#/components/Toast'
24242525const MAIN_VIEWS = ['Base', 'Controls', 'Error', 'Notifs']
2626
+1-1
src/view/screens/Storybook/Settings.tsx
···11import {View} from 'react-native'
2233-import * as Toast from '#/view/com/util/Toast'
43import * as SettingsList from '#/screens/Settings/components/SettingsList'
54import {atoms as a, useTheme} from '#/alf'
65import {Alien_Stroke2_Corner0_Rounded as AlienIcon} from '#/components/icons/Alien'
···1615import {RaisingHand4Finger_Stroke2_Corner2_Rounded as HandIcon} from '#/components/icons/RaisingHand'
1716import {ShieldCheck_Stroke2_Corner0_Rounded as ShieldIcon} from '#/components/icons/Shield'
1817import {Window_Stroke2_Corner2_Rounded as WindowIcon} from '#/components/icons/Window'
1818+import * as Toast from '#/components/Toast'
1919import {Text} from '#/components/Typography'
20202121export function Settings() {