diff --git a/assets/icons/magnifyingGlassX_stroke2_corner0_rounded.svg b/assets/icons/magnifyingGlassX_stroke2_corner0_rounded.svg
new file mode 100644
index 0000000000..a21615b5f0
--- /dev/null
+++ b/assets/icons/magnifyingGlassX_stroke2_corner0_rounded.svg
@@ -0,0 +1 @@
+
diff --git a/assets/icons/magnifyingGlassX_stroke2_corner0_rounded_large.svg b/assets/icons/magnifyingGlassX_stroke2_corner0_rounded_large.svg
new file mode 100644
index 0000000000..e39b483268
--- /dev/null
+++ b/assets/icons/magnifyingGlassX_stroke2_corner0_rounded_large.svg
@@ -0,0 +1 @@
+
diff --git a/src/components/ProgressGuide/FollowDialog.tsx b/src/components/ProgressGuide/FollowDialog.tsx
index 4d1d27d15d..d1017c46f6 100644
--- a/src/components/ProgressGuide/FollowDialog.tsx
+++ b/src/components/ProgressGuide/FollowDialog.tsx
@@ -31,7 +31,7 @@ import {
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import * as Dialog from '#/components/Dialog'
import {useInteractionState} from '#/components/hooks/useInteractionState'
-import {MagnifyingGlass2_Stroke2_Corner0_Rounded as SearchIcon} from '#/components/icons/MagnifyingGlass2'
+import {MagnifyingGlass_Stroke2_Corner0_Rounded as SearchIcon} from '#/components/icons/MagnifyingGlass'
import {PersonGroup_Stroke2_Corner2_Rounded as PersonGroupIcon} from '#/components/icons/Person'
import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
import {boostInterests, InterestTabs} from '#/components/InterestTabs'
diff --git a/src/components/RichTextTag.tsx b/src/components/RichTextTag.tsx
index a24ebb15c2..4f1af6e1ea 100644
--- a/src/components/RichTextTag.tsx
+++ b/src/components/RichTextTag.tsx
@@ -12,7 +12,7 @@ import {
useRemoveMutedWordsMutation,
useUpsertMutedWordsMutation,
} from '#/state/queries/preferences'
-import {MagnifyingGlass2_Stroke2_Corner0_Rounded as Search} from '#/components/icons/MagnifyingGlass2'
+import {MagnifyingGlass_Stroke2_Corner0_Rounded as Search} from '#/components/icons/MagnifyingGlass'
import {Mute_Stroke2_Corner0_Rounded as Mute} from '#/components/icons/Mute'
import {Person_Stroke2_Corner0_Rounded as Person} from '#/components/icons/Person'
import {
diff --git a/src/components/SearchError.tsx b/src/components/SearchError.tsx
index d478ac8850..4c9b402612 100644
--- a/src/components/SearchError.tsx
+++ b/src/components/SearchError.tsx
@@ -1,10 +1,9 @@
import {View} from 'react-native'
-import {usePalette} from '#/lib/hooks/usePalette'
-import {atoms as a, useBreakpoints} from '#/alf'
+import {atoms as a, useBreakpoints, useTheme} from '#/alf'
+import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times'
import * as Layout from '#/components/Layout'
import {Text} from '#/components/Typography'
-import {TimesLarge_Stroke2_Corner0_Rounded} from './icons/Times'
export function SearchError({
title,
@@ -14,7 +13,7 @@ export function SearchError({
children?: React.ReactNode
}) {
const {gtMobile} = useBreakpoints()
- const pal = usePalette('default')
+ const t = useTheme()
return (
@@ -27,7 +26,7 @@ export function SearchError({
paddingVertical: 150,
},
]}>
-
+
{
// get otp
await new Promise(resolve => {
- setTimeout(resolve, 1000)
+ setTimeout(resolve, 500)
})
},
onSuccess: (_data, {countryCode, phoneNumber}) => {
diff --git a/src/components/contacts/screens/VerifyNumber.tsx b/src/components/contacts/screens/VerifyNumber.tsx
index 6db46f8c9c..49b7c2a52a 100644
--- a/src/components/contacts/screens/VerifyNumber.tsx
+++ b/src/components/contacts/screens/VerifyNumber.tsx
@@ -4,7 +4,6 @@ import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
import {useMutation} from '@tanstack/react-query'
-import {wait} from '#/lib/async/wait'
import {getPhoneCodeFromCountryCode} from '#/lib/international-telephone-codes'
import {clamp} from '#/lib/numbers'
import {cleanError, isNetworkError} from '#/lib/strings/errors'
@@ -55,11 +54,10 @@ export function VerifyNumber({
isSuccess,
} = useMutation({
mutationFn: async (_code: string) => {
- await new Promise(resolve => setTimeout(resolve, 1000))
+ await new Promise(resolve => setTimeout(resolve, 500))
return 'success'
},
onSuccess: async () => {
- await wait(2e3, () => {})
dispatch({
type: 'VERIFY_PHONE_NUMBER_SUCCESS',
payload: {
@@ -239,7 +237,6 @@ function OTPStatus({
text = _(msg`Phone verified`)
textColor = t.palette.positive_500
} else if (isPending) {
- Icon = Loader
text = _(msg`Verifying...`)
} else if (error) {
Icon = WarningIcon
diff --git a/src/components/contacts/screens/ViewMatches.tsx b/src/components/contacts/screens/ViewMatches.tsx
index 8f40b2838e..4973c12b43 100644
--- a/src/components/contacts/screens/ViewMatches.tsx
+++ b/src/components/contacts/screens/ViewMatches.tsx
@@ -1,22 +1,36 @@
-import {useMemo, useState} from 'react'
+import {useMemo, useRef, useState} from 'react'
import {View} from 'react-native'
import * as SMS from 'expo-sms'
import {type ModerationOpts} from '@atproto/api'
import {msg, Plural, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'
+import {useMutation, useQueryClient} from '@tanstack/react-query'
+import {wait} from '#/lib/async/wait'
+import {cleanError, isNetworkError} from '#/lib/strings/errors'
import {logger} from '#/logger'
+import {
+ updateProfileShadow,
+ useProfileShadow,
+} from '#/state/cache/profile-shadow'
import {useModerationOpts} from '#/state/preferences/moderation-opts'
-import {useSession} from '#/state/session'
-import {List} from '#/view/com/util/List'
+import {useProfilesQuery} from '#/state/queries/profile'
+import {useAgent, useSession} from '#/state/session'
+import {List, type ListMethods} from '#/view/com/util/List'
import {UserAvatar} from '#/view/com/util/UserAvatar'
+import {bulkWriteFollows} from '#/screens/Onboarding/util'
import {atoms as a, useGutters, useTheme} from '#/alf'
import {Button, ButtonIcon, ButtonText} from '#/components/Button'
import {SearchInput} from '#/components/forms/SearchInput'
+import {useInteractionState} from '#/components/hooks/useInteractionState'
+import {Check_Stroke2_Corner0_Rounded as CheckIcon} from '#/components/icons/Check'
import {Envelope_Stroke2_Corner0_Rounded as EnvelopeIcon} from '#/components/icons/Envelope'
+import {MagnifyingGlassX_Stroke2_Corner0_Rounded_Large as SearchFailedIcon} from '#/components/icons/MagnifyingGlass'
import {PlusLarge_Stroke2_Corner0_Rounded as PlusIcon} from '#/components/icons/Plus'
+import {TimesLarge_Stroke2_Corner0_Rounded as XIcon} from '#/components/icons/Times'
import * as Layout from '#/components/Layout'
import {ListFooter} from '#/components/Lists'
+import {Loader} from '#/components/Loader'
import * as ProfileCard from '#/components/ProfileCard'
import * as Toast from '#/components/Toast'
import {Text} from '#/components/Typography'
@@ -26,6 +40,7 @@ import {type Action, type Contact, type State} from '../state'
type Item =
| {
type: 'matches header'
+ count: number
}
| {
type: 'match'
@@ -43,6 +58,7 @@ type Item =
}
| {
type: 'search empty state'
+ query: string
}
// we could use Contacts.presentAccessPickerAsync() if we get limited permissions?
// | {
@@ -51,6 +67,7 @@ type Item =
export function ViewMatches({
state,
+ dispatch,
}: {
state: Extract
dispatch: React.Dispatch
@@ -58,37 +75,165 @@ export function ViewMatches({
const {_} = useLingui()
const gutter = useGutters([0, 'wide'])
const moderationOpts = useModerationOpts()
+ const queryClient = useQueryClient()
+ const agent = useAgent()
+ const listRef = useRef(null)
+
+ // TEMP!!!
+ const {data: profiles} = useProfilesQuery({
+ handles: ['pfrazee.com', 'internet.bsky.social', 'darrin.bsky.team'],
+ })
+ state.matches = profiles?.profiles?.map(profile => ({profile})) ?? []
const [search, setSearch] = useState('')
+ const {
+ state: searchFocused,
+ onIn: onFocus,
+ onOut: onBlur,
+ } = useInteractionState()
+
+ const followableDids = state.matches
+ .map(match => match.profile.did)
+ .filter(did => !state.dismissedMatches.includes(did))
+ const [didFollowAll, setDidFollowAll] = useState(followableDids.length === 0)
+
+ const {mutate: followAll, isPending: isFollowingAll} = useMutation({
+ mutationFn: async () => {
+ for (const did of followableDids) {
+ updateProfileShadow(queryClient, did, {
+ followingUri: 'pending',
+ })
+ }
+
+ const uris = await wait(500, bulkWriteFollows(agent, followableDids))
+
+ for (const did of followableDids) {
+ const uri = uris.get(did)
+ updateProfileShadow(queryClient, did, {
+ followingUri: uri,
+ })
+ }
+ return followableDids
+ },
+ onSuccess: () => {
+ setDidFollowAll(true)
+ Toast.show(_(msg`All friends followed!`), {type: 'success'})
+ },
+ onError: _err => {
+ Toast.show(_(msg`Failed to follow all your friends, please try again`), {
+ type: 'error',
+ })
+ for (const did of followableDids) {
+ updateProfileShadow(queryClient, did, {
+ followingUri: undefined,
+ })
+ }
+ },
+ })
const items = useMemo(() => {
const all: Item[] = []
- if (state.matches.length > 0) {
- all.push({type: 'matches header'})
+ if (searchFocused || search.length > 0) {
for (const match of state.matches) {
const profile = match.profile
- all.push({type: 'match', profile})
- }
- all.push({type: 'contacts header'})
- } else {
- all.push({type: 'no matches header'})
- }
- for (const contact of state.contacts) {
- all.push({type: 'contact', contact})
+ if (state.dismissedMatches.includes(profile.did)) continue
+
+ if (
+ search.length === 0 ||
+ (profile.displayName ?? '')
+ .toLocaleLowerCase()
+ .includes(search.toLocaleLowerCase()) ||
+ profile.handle
+ .toLocaleLowerCase()
+ .includes(search.toLocaleLowerCase())
+ ) {
+ all.push({type: 'match', profile})
+ }
+ }
+
+ for (const contact of state.contacts) {
+ if (
+ search.length === 0 ||
+ [contact.firstName, contact.lastName]
+ .filter(Boolean)
+ .join(' ')
+ .toLocaleLowerCase()
+ .includes(search.toLocaleLowerCase())
+ ) {
+ all.push({type: 'contact', contact})
+ }
+ }
+
+ if (all.length === 0) {
+ all.push({type: 'search empty state', query: search})
+ }
+ } else {
+ const matches = state.matches.filter(
+ match => !state.dismissedMatches.includes(match.profile.did),
+ )
+
+ if (matches.length > 0) {
+ all.push({type: 'matches header', count: matches.length})
+ for (const match of matches) {
+ const profile = match.profile
+ all.push({type: 'match', profile})
+ }
+ all.push({type: 'contacts header'})
+ } else {
+ all.push({type: 'no matches header'})
+ }
+
+ for (const contact of state.contacts) {
+ all.push({type: 'contact', contact})
+ }
}
return all
- }, [state.matches, state.contacts])
+ }, [
+ state.matches,
+ state.contacts,
+ state.dismissedMatches,
+ search,
+ searchFocused,
+ ])
- const numMatches = state.matches.length
+ const {mutate: dimissMatch} = useMutation({
+ mutationFn: async (_did: string) => {
+ await new Promise(resolve => setTimeout(resolve, 500))
+ },
+ onMutate: did => {
+ dispatch({type: 'DISMISS_MATCH', payload: {did}})
+ },
+ onError: (err, did) => {
+ dispatch({type: 'DISMISS_MATCH_FAILED', payload: {did}})
+ if (isNetworkError(err)) {
+ Toast.show(
+ _(
+ msg`Failed to hide suggestion, please check your internet connection`,
+ ),
+ {type: 'error'},
+ )
+ } else {
+ logger.error('Dismissing match failed', {safeMessage: err})
+ Toast.show(
+ _(msg`An error occurred while hiding suggestion. ${cleanError(err)}`),
+ {type: 'error'},
+ )
+ }
+ },
+ })
const renderItem = ({item}: {item: Item}) => {
switch (item.type) {
case 'match':
return (
-
+
)
case 'contact':
return
@@ -97,17 +242,27 @@ export function ViewMatches({
}>
- {numMatches > 1 && (
+ {item.count > 1 && (
)
}
+
+function SearchEmptyState({query}: {query: string}) {
+ const t = useTheme()
+
+ return (
+
+
+
+ No contacts with the name “{query}” found
+
+
+ )
+}
diff --git a/src/components/contacts/state.ts b/src/components/contacts/state.ts
index 4c0d843b1a..5a2909445f 100644
--- a/src/components/contacts/state.ts
+++ b/src/components/contacts/state.ts
@@ -32,6 +32,9 @@ export type State =
step: '4: view matches'
contacts: Contact[]
matches: Match[]
+ // rather than mutating `matches`, we keep track of dismissed matches
+ // so we can roll back optimistic updates
+ dismissedMatches: string[]
}
export type Action =
@@ -72,6 +75,12 @@ export type Action =
did: string
}
}
+ | {
+ type: 'DISMISS_MATCH_FAILED'
+ payload: {
+ did: string
+ }
+ }
function reducer(state: State, action: Action): State {
switch (action.type) {
@@ -118,14 +127,25 @@ function reducer(state: State, action: Action): State {
step: '4: view matches',
contacts: state.contacts ?? [],
matches: action.payload.matches,
+ dismissedMatches: [],
}
}
case 'DISMISS_MATCH': {
assertCurrentStep(state, '4: view matches')
return {
...state,
- matches: state.matches.filter(
- match => match.profile.did !== action.payload.did,
+ dismissedMatches: [
+ ...new Set(state.dismissedMatches),
+ action.payload.did,
+ ],
+ }
+ }
+ case 'DISMISS_MATCH_FAILED': {
+ assertCurrentStep(state, '4: view matches')
+ return {
+ ...state,
+ dismissedMatches: state.dismissedMatches.filter(
+ did => did !== action.payload.did,
),
}
}
diff --git a/src/components/dialogs/GifSelect.tsx b/src/components/dialogs/GifSelect.tsx
index 536483b080..58d669f0e2 100644
--- a/src/components/dialogs/GifSelect.tsx
+++ b/src/components/dialogs/GifSelect.tsx
@@ -29,7 +29,7 @@ import * as Dialog from '#/components/Dialog'
import * as TextField from '#/components/forms/TextField'
import {useThrottledValue} from '#/components/hooks/useThrottledValue'
import {ArrowLeft_Stroke2_Corner0_Rounded as Arrow} from '#/components/icons/Arrow'
-import {MagnifyingGlass2_Stroke2_Corner0_Rounded as Search} from '#/components/icons/MagnifyingGlass2'
+import {MagnifyingGlass_Stroke2_Corner0_Rounded as Search} from '#/components/icons/MagnifyingGlass'
import {ListFooter, ListMaybePlaceholder} from '#/components/Lists'
export function GifSelectDialog({
diff --git a/src/components/dialogs/SearchablePeopleList.tsx b/src/components/dialogs/SearchablePeopleList.tsx
index 41b31b255c..d8c44c3097 100644
--- a/src/components/dialogs/SearchablePeopleList.tsx
+++ b/src/components/dialogs/SearchablePeopleList.tsx
@@ -25,7 +25,7 @@ import {Button, ButtonIcon} from '#/components/Button'
import * as Dialog from '#/components/Dialog'
import {canBeMessaged} from '#/components/dms/util'
import {useInteractionState} from '#/components/hooks/useInteractionState'
-import {MagnifyingGlass2_Stroke2_Corner0_Rounded as Search} from '#/components/icons/MagnifyingGlass2'
+import {MagnifyingGlass_Stroke2_Corner0_Rounded as Search} from '#/components/icons/MagnifyingGlass'
import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
import * as ProfileCard from '#/components/ProfileCard'
import {Text} from '#/components/Typography'
diff --git a/src/components/forms/SearchInput.tsx b/src/components/forms/SearchInput.tsx
index 618a0040ef..ae0335abd4 100644
--- a/src/components/forms/SearchInput.tsx
+++ b/src/components/forms/SearchInput.tsx
@@ -8,7 +8,7 @@ import {isNative} from '#/platform/detection'
import {atoms as a, useTheme} from '#/alf'
import {Button, ButtonIcon} from '#/components/Button'
import * as TextField from '#/components/forms/TextField'
-import {MagnifyingGlass2_Stroke2_Corner0_Rounded as MagnifyingGlassIcon} from '#/components/icons/MagnifyingGlass2'
+import {MagnifyingGlass_Stroke2_Corner0_Rounded as MagnifyingGlassIcon} from '#/components/icons/MagnifyingGlass'
import {TimesLarge_Stroke2_Corner0_Rounded as X} from '#/components/icons/Times'
type SearchInputProps = Omit & {
diff --git a/src/components/icons/MagnifyingGlass.tsx b/src/components/icons/MagnifyingGlass.tsx
index de5f83c9cb..b10b326276 100644
--- a/src/components/icons/MagnifyingGlass.tsx
+++ b/src/components/icons/MagnifyingGlass.tsx
@@ -1,6 +1,20 @@
import {createSinglePathSVG} from './TEMPLATE'
+export const MagnifyingGlass_Stroke2_Corner0_Rounded = createSinglePathSVG({
+ path: 'M11 5a6 6 0 1 0 0 12 6 6 0 0 0 0-12Zm-8 6a8 8 0 1 1 14.32 4.906l3.387 3.387a1 1 0 0 1-1.414 1.414l-3.387-3.387A8 8 0 0 1 3 11Z',
+})
+
export const MagnifyingGlass_Filled_Stroke2_Corner0_Rounded =
createSinglePathSVG({
path: 'M5 11a6 6 0 1 1 12 0 6 6 0 0 1-12 0Zm6-8a8 8 0 1 0 4.906 14.32l3.387 3.387a1 1 0 0 0 1.414-1.414l-3.387-3.387A8 8 0 0 0 11 3Zm4 8a4 4 0 1 1-8 0 4 4 0 0 1 8 0Z',
})
+
+export const MagnifyingGlassX_Stroke2_Corner0_Rounded = createSinglePathSVG({
+ path: 'M20 12a8 8 0 1 0-8 8c2.204 0 4.2-.89 5.648-2.333A7.97 7.97 0 0 0 20 12Zm-5.707-3.707a1 1 0 1 1 1.414 1.414L13.414 12l2.293 2.293a1 1 0 1 1-1.414 1.414L12 13.414l-2.293 2.293a1 1 0 1 1-1.414-1.414L10.586 12 8.293 9.707a1 1 0 1 1 1.414-1.414L12 10.586l2.293-2.293ZM22 12a9.96 9.96 0 0 1-2.269 6.34l2.891 2.89a1 1 0 1 1-1.414 1.415l-2.893-2.893A9.96 9.96 0 0 1 12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10Z',
+})
+
+export const MagnifyingGlassX_Stroke2_Corner0_Rounded_Large =
+ createSinglePathSVG({
+ viewBox: '0 0 64 64',
+ path: 'M55 32C55 19.298 44.703 9 32 9S9 19.298 9 32s10.298 23 23 23a22.93 22.93 0 0 0 16.235-6.708A22.93 22.93 0 0 0 55 32Zm-15.707-8.707a1 1 0 1 1 1.414 1.414L33.414 32l7.293 7.293a1 1 0 1 1-1.414 1.414L32 33.414l-7.293 7.293a1 1 0 1 1-1.414-1.414L30.586 32l-7.293-7.293a1 1 0 1 1 1.414-1.414L32 30.586l7.293-7.293ZM57 32a24.9 24.9 0 0 1-6.66 16.985l8.808 8.808a1 1 0 0 1-1.414 1.414l-8.81-8.81A24.9 24.9 0 0 1 32 57C18.193 57 7 45.807 7 32S18.193 7 32 7s25 11.193 25 25Z',
+ })
diff --git a/src/components/icons/MagnifyingGlass2.tsx b/src/components/icons/MagnifyingGlass2.tsx
deleted file mode 100644
index 3ca4034001..0000000000
--- a/src/components/icons/MagnifyingGlass2.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import {createSinglePathSVG} from './TEMPLATE'
-
-export const MagnifyingGlass2_Stroke2_Corner0_Rounded = createSinglePathSVG({
- path: 'M11 5a6 6 0 1 0 0 12 6 6 0 0 0 0-12Zm-8 6a8 8 0 1 1 14.32 4.906l3.387 3.387a1 1 0 0 1-1.414 1.414l-3.387-3.387A8 8 0 0 1 3 11Z',
-})
diff --git a/src/screens/Search/components/ModuleHeader.tsx b/src/screens/Search/components/ModuleHeader.tsx
index 202137a354..440f2f3b51 100644
--- a/src/screens/Search/components/ModuleHeader.tsx
+++ b/src/screens/Search/components/ModuleHeader.tsx
@@ -10,7 +10,7 @@ import {atoms as a, native, useTheme, type ViewStyleProp} from '#/alf'
import {Button, ButtonIcon} from '#/components/Button'
import * as FeedCard from '#/components/FeedCard'
import {sizes as iconSizes} from '#/components/icons/common'
-import {MagnifyingGlass2_Stroke2_Corner0_Rounded as SearchIcon} from '#/components/icons/MagnifyingGlass2'
+import {MagnifyingGlass_Stroke2_Corner0_Rounded as SearchIcon} from '#/components/icons/MagnifyingGlass'
import {Link} from '#/components/Link'
import {Text, type TextProps} from '#/components/Typography'
diff --git a/src/view/com/profile/ProfileMenu.tsx b/src/view/com/profile/ProfileMenu.tsx
index c065b2d1f8..5fc976ecc2 100644
--- a/src/view/com/profile/ProfileMenu.tsx
+++ b/src/view/com/profile/ProfileMenu.tsx
@@ -37,7 +37,7 @@ import {DotGrid_Stroke2_Corner0_Rounded as Ellipsis} from '#/components/icons/Do
import {Flag_Stroke2_Corner0_Rounded as Flag} from '#/components/icons/Flag'
import {ListSparkle_Stroke2_Corner0_Rounded as List} from '#/components/icons/ListSparkle'
import {Live_Stroke2_Corner0_Rounded as LiveIcon} from '#/components/icons/Live'
-import {MagnifyingGlass2_Stroke2_Corner0_Rounded as SearchIcon} from '#/components/icons/MagnifyingGlass2'
+import {MagnifyingGlass_Stroke2_Corner0_Rounded as SearchIcon} from '#/components/icons/MagnifyingGlass'
import {Mute_Stroke2_Corner0_Rounded as Mute} from '#/components/icons/Mute'
import {PeopleRemove2_Stroke2_Corner0_Rounded as UserMinus} from '#/components/icons/PeopleRemove2'
import {
diff --git a/src/view/screens/Storybook/Menus.tsx b/src/view/screens/Storybook/Menus.tsx
index 28689b7273..9723d871b6 100644
--- a/src/view/screens/Storybook/Menus.tsx
+++ b/src/view/screens/Storybook/Menus.tsx
@@ -1,7 +1,7 @@
import {View} from 'react-native'
import {atoms as a, useTheme} from '#/alf'
-import {MagnifyingGlass2_Stroke2_Corner0_Rounded as Search} from '#/components/icons/MagnifyingGlass2'
+import {MagnifyingGlass_Stroke2_Corner0_Rounded as Search} from '#/components/icons/MagnifyingGlass'
import * as Menu from '#/components/Menu'
import {Text} from '#/components/Typography'
// import {useDialogStateControlContext} from '#/state/dialogs'
diff --git a/src/view/shell/Drawer.tsx b/src/view/shell/Drawer.tsx
index ed2a6cfb7e..f76147ccf7 100644
--- a/src/view/shell/Drawer.tsx
+++ b/src/view/shell/Drawer.tsx
@@ -41,7 +41,7 @@ import {
HomeOpen_Stoke2_Corner0_Rounded as Home,
} from '#/components/icons/HomeOpen'
import {MagnifyingGlass_Filled_Stroke2_Corner0_Rounded as MagnifyingGlassFilled} from '#/components/icons/MagnifyingGlass'
-import {MagnifyingGlass2_Stroke2_Corner0_Rounded as MagnifyingGlass} from '#/components/icons/MagnifyingGlass2'
+import {MagnifyingGlass_Stroke2_Corner0_Rounded as MagnifyingGlass} from '#/components/icons/MagnifyingGlass'
import {
Message_Stroke2_Corner0_Rounded as Message,
Message_Stroke2_Corner0_Rounded_Filled as MessageFilled,
diff --git a/src/view/shell/bottom-bar/BottomBar.tsx b/src/view/shell/bottom-bar/BottomBar.tsx
index 779ebda681..c3fc5827a9 100644
--- a/src/view/shell/bottom-bar/BottomBar.tsx
+++ b/src/view/shell/bottom-bar/BottomBar.tsx
@@ -44,7 +44,7 @@ import {
HomeOpen_Stoke2_Corner0_Rounded as Home,
} from '#/components/icons/HomeOpen'
import {MagnifyingGlass_Filled_Stroke2_Corner0_Rounded as MagnifyingGlassFilled} from '#/components/icons/MagnifyingGlass'
-import {MagnifyingGlass2_Stroke2_Corner0_Rounded as MagnifyingGlass} from '#/components/icons/MagnifyingGlass2'
+import {MagnifyingGlass_Stroke2_Corner0_Rounded as MagnifyingGlass} from '#/components/icons/MagnifyingGlass'
import {
Message_Stroke2_Corner0_Rounded as Message,
Message_Stroke2_Corner0_Rounded_Filled as MessageFilled,
diff --git a/src/view/shell/bottom-bar/BottomBarWeb.tsx b/src/view/shell/bottom-bar/BottomBarWeb.tsx
index 61b32c6434..37a8e45d4c 100644
--- a/src/view/shell/bottom-bar/BottomBarWeb.tsx
+++ b/src/view/shell/bottom-bar/BottomBarWeb.tsx
@@ -32,7 +32,7 @@ import {
HomeOpen_Stoke2_Corner0_Rounded as Home,
} from '#/components/icons/HomeOpen'
import {MagnifyingGlass_Filled_Stroke2_Corner0_Rounded as MagnifyingGlassFilled} from '#/components/icons/MagnifyingGlass'
-import {MagnifyingGlass2_Stroke2_Corner0_Rounded as MagnifyingGlass} from '#/components/icons/MagnifyingGlass2'
+import {MagnifyingGlass_Stroke2_Corner0_Rounded as MagnifyingGlass} from '#/components/icons/MagnifyingGlass'
import {
Message_Stroke2_Corner0_Rounded as Message,
Message_Stroke2_Corner0_Rounded_Filled as MessageFilled,
diff --git a/src/view/shell/desktop/LeftNav.tsx b/src/view/shell/desktop/LeftNav.tsx
index 2c44a5b00f..32b85d0836 100644
--- a/src/view/shell/desktop/LeftNav.tsx
+++ b/src/view/shell/desktop/LeftNav.tsx
@@ -56,7 +56,7 @@ import {
HomeOpen_Stoke2_Corner0_Rounded as Home,
} from '#/components/icons/HomeOpen'
import {MagnifyingGlass_Filled_Stroke2_Corner0_Rounded as MagnifyingGlassFilled} from '#/components/icons/MagnifyingGlass'
-import {MagnifyingGlass2_Stroke2_Corner0_Rounded as MagnifyingGlass} from '#/components/icons/MagnifyingGlass2'
+import {MagnifyingGlass_Stroke2_Corner0_Rounded as MagnifyingGlass} from '#/components/icons/MagnifyingGlass'
import {
Message_Stroke2_Corner0_Rounded as Message,
Message_Stroke2_Corner0_Rounded_Filled as MessageFilled,