Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d840faacc | |||
| ded615d9f9 | |||
| 551af88f22 | |||
| a49fe13223 | |||
| 9f001526d3 | |||
| d6b8313932 | |||
| e4b4d854d6 | |||
| c352e0f8b4 |
@@ -16,6 +16,7 @@ import {sanitizeDisplayName} from '#/lib/strings/display-names'
|
||||
import {sanitizeHandle} from '#/lib/strings/handles'
|
||||
import {isWeb} from '#/platform/detection'
|
||||
import {useModerationOpts} from '#/state/preferences/moderation-opts'
|
||||
import {useListConvosQuery} from '#/state/queries/messages/list-converations'
|
||||
import {useProfileFollowsQuery} from '#/state/queries/profile-follows'
|
||||
import {useSession} from '#/state/session'
|
||||
import {useActorAutocompleteQuery} from 'state/queries/actor-autocomplete'
|
||||
@@ -55,9 +56,11 @@ type Item =
|
||||
export function SearchablePeopleList({
|
||||
title,
|
||||
onSelectChat,
|
||||
showRecentConvos,
|
||||
}: {
|
||||
title: string
|
||||
onSelectChat: (did: string) => void
|
||||
showRecentConvos?: boolean
|
||||
}) {
|
||||
const t = useTheme()
|
||||
const {_} = useLingui()
|
||||
@@ -75,6 +78,7 @@ export function SearchablePeopleList({
|
||||
isFetching,
|
||||
} = useActorAutocompleteQuery(searchText, true, 12)
|
||||
const {data: follows} = useProfileFollowsQuery(currentAccount?.did)
|
||||
const {data: convos} = useListConvosQuery({enabled: showRecentConvos})
|
||||
|
||||
const items = useMemo(() => {
|
||||
let _items: Item[] = []
|
||||
@@ -103,7 +107,65 @@ export function SearchablePeopleList({
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (follows) {
|
||||
const placeholders: Item[] = Array(10)
|
||||
.fill(0)
|
||||
.map((_, i) => ({
|
||||
type: 'placeholder',
|
||||
key: i + '',
|
||||
}))
|
||||
|
||||
if (showRecentConvos) {
|
||||
if (convos && follows) {
|
||||
const usedDids = new Set()
|
||||
|
||||
for (const page of convos.pages) {
|
||||
for (const convo of page.convos) {
|
||||
const profiles = convo.members.filter(
|
||||
m => m.did !== currentAccount?.did,
|
||||
)
|
||||
|
||||
for (const profile of profiles) {
|
||||
if (usedDids.has(profile.did)) continue
|
||||
|
||||
usedDids.add(profile.did)
|
||||
|
||||
_items.push({
|
||||
type: 'profile',
|
||||
key: profile.did,
|
||||
enabled: true,
|
||||
profile,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let followsItems: typeof _items = []
|
||||
|
||||
for (const page of follows.pages) {
|
||||
for (const profile of page.follows) {
|
||||
if (usedDids.has(profile.did)) continue
|
||||
|
||||
followsItems.push({
|
||||
type: 'profile',
|
||||
key: profile.did,
|
||||
enabled: canBeMessaged(profile),
|
||||
profile,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// only sort follows
|
||||
followsItems = followsItems.sort(a => {
|
||||
// @ts-ignore
|
||||
return a.enabled ? -1 : 1
|
||||
})
|
||||
|
||||
// then append
|
||||
_items.push(...followsItems)
|
||||
} else {
|
||||
_items.push(...placeholders)
|
||||
}
|
||||
} else if (follows) {
|
||||
for (const page of follows.pages) {
|
||||
for (const profile of page.follows) {
|
||||
_items.push({
|
||||
@@ -120,19 +182,21 @@ export function SearchablePeopleList({
|
||||
return a.enabled ? -1 : 1
|
||||
})
|
||||
} else {
|
||||
Array(10)
|
||||
.fill(0)
|
||||
.forEach((_, i) => {
|
||||
_items.push({
|
||||
type: 'placeholder',
|
||||
key: i + '',
|
||||
})
|
||||
})
|
||||
_items.push(...placeholders)
|
||||
}
|
||||
}
|
||||
|
||||
return _items
|
||||
}, [_, searchText, results, isError, currentAccount?.did, follows])
|
||||
}, [
|
||||
_,
|
||||
searchText,
|
||||
results,
|
||||
isError,
|
||||
currentAccount?.did,
|
||||
follows,
|
||||
convos,
|
||||
showRecentConvos,
|
||||
])
|
||||
|
||||
if (searchText && !isFetching && !items.length && !isError) {
|
||||
items.push({type: 'empty', key: 'empty', message: _(msg`No results`)})
|
||||
|
||||
@@ -46,6 +46,7 @@ export function SendViaChatDialog({
|
||||
<SearchablePeopleList
|
||||
title={_(msg`Send post to...`)}
|
||||
onSelectChat={onCreateChat}
|
||||
showRecentConvos
|
||||
/>
|
||||
</Dialog.Outer>
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage'
|
||||
|
||||
import {Schema, schema} from '#/state/persisted/schema'
|
||||
import {logger} from '#/logger'
|
||||
import {Schema, schema} from '#/state/persisted/schema'
|
||||
|
||||
const BSKY_STORAGE = 'BSKY_STORAGE'
|
||||
|
||||
@@ -13,8 +13,19 @@ export async function write(value: Schema) {
|
||||
export async function read(): Promise<Schema | undefined> {
|
||||
const rawData = await AsyncStorage.getItem(BSKY_STORAGE)
|
||||
const objData = rawData ? JSON.parse(rawData) : undefined
|
||||
if (schema.safeParse(objData).success) {
|
||||
const parsed = schema.safeParse(objData)
|
||||
if (parsed.success) {
|
||||
return objData
|
||||
} else {
|
||||
const errors =
|
||||
parsed.error?.errors?.map(e => ({
|
||||
code: e.code,
|
||||
// @ts-ignore exists on some types
|
||||
expected: e?.expected,
|
||||
path: e.path,
|
||||
})) || []
|
||||
logger.error(`persisted store: data failed validation on read`, {errors})
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -26,10 +26,15 @@ import {useAgent, useSession} from '#/state/session'
|
||||
export const RQKEY = ['convo-list']
|
||||
type RQPageParam = string | undefined
|
||||
|
||||
export function useListConvosQuery() {
|
||||
export function useListConvosQuery({
|
||||
enabled,
|
||||
}: {
|
||||
enabled?: boolean
|
||||
} = {}) {
|
||||
const agent = useAgent()
|
||||
|
||||
return useInfiniteQuery({
|
||||
enabled,
|
||||
queryKey: RQKEY,
|
||||
queryFn: async ({pageParam}) => {
|
||||
const {data} = await agent.api.chat.bsky.convo.listConvos(
|
||||
|
||||
@@ -59,7 +59,7 @@ describe('session', () => {
|
||||
"refreshJwt": "alice-refresh-jwt-1",
|
||||
"service": "https://alice.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -97,7 +97,7 @@ describe('session', () => {
|
||||
"refreshJwt": undefined,
|
||||
"service": "https://alice.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -147,7 +147,7 @@ describe('session', () => {
|
||||
"refreshJwt": "alice-refresh-jwt-1",
|
||||
"service": "https://alice.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -195,7 +195,7 @@ describe('session', () => {
|
||||
"refreshJwt": "bob-refresh-jwt-1",
|
||||
"service": "https://bob.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
{
|
||||
"accessJwt": "alice-access-jwt-1",
|
||||
@@ -208,7 +208,7 @@ describe('session', () => {
|
||||
"refreshJwt": "alice-refresh-jwt-1",
|
||||
"service": "https://alice.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -256,7 +256,7 @@ describe('session', () => {
|
||||
"refreshJwt": "alice-refresh-jwt-2",
|
||||
"service": "https://alice.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
{
|
||||
"accessJwt": "bob-access-jwt-1",
|
||||
@@ -269,7 +269,7 @@ describe('session', () => {
|
||||
"refreshJwt": "bob-refresh-jwt-1",
|
||||
"service": "https://bob.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -315,7 +315,7 @@ describe('session', () => {
|
||||
"refreshJwt": "jay-refresh-jwt-1",
|
||||
"service": "https://jay.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
{
|
||||
"accessJwt": "alice-access-jwt-2",
|
||||
@@ -328,7 +328,7 @@ describe('session', () => {
|
||||
"refreshJwt": "alice-refresh-jwt-2",
|
||||
"service": "https://alice.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
{
|
||||
"accessJwt": "bob-access-jwt-1",
|
||||
@@ -341,7 +341,7 @@ describe('session', () => {
|
||||
"refreshJwt": "bob-refresh-jwt-1",
|
||||
"service": "https://bob.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -383,7 +383,7 @@ describe('session', () => {
|
||||
"refreshJwt": undefined,
|
||||
"service": "https://jay.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
{
|
||||
"accessJwt": undefined,
|
||||
@@ -396,7 +396,7 @@ describe('session', () => {
|
||||
"refreshJwt": undefined,
|
||||
"service": "https://alice.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
{
|
||||
"accessJwt": undefined,
|
||||
@@ -409,7 +409,7 @@ describe('session', () => {
|
||||
"refreshJwt": undefined,
|
||||
"service": "https://bob.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -468,7 +468,7 @@ describe('session', () => {
|
||||
"refreshJwt": undefined,
|
||||
"service": "https://alice.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -513,7 +513,7 @@ describe('session', () => {
|
||||
"refreshJwt": "alice-refresh-jwt-2",
|
||||
"service": "https://alice.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -625,7 +625,7 @@ describe('session', () => {
|
||||
"refreshJwt": "bob-refresh-jwt-1",
|
||||
"service": "https://bob.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -706,7 +706,7 @@ describe('session', () => {
|
||||
"refreshJwt": "alice-refresh-jwt-2",
|
||||
"service": "https://alice.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -757,7 +757,7 @@ describe('session', () => {
|
||||
"refreshJwt": "alice-refresh-jwt-3",
|
||||
"service": "https://alice.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -808,7 +808,7 @@ describe('session', () => {
|
||||
"refreshJwt": "alice-refresh-jwt-4",
|
||||
"service": "https://alice.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -965,7 +965,7 @@ describe('session', () => {
|
||||
"refreshJwt": "bob-refresh-jwt-1",
|
||||
"service": "https://bob.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
{
|
||||
"accessJwt": "alice-access-jwt-2",
|
||||
@@ -978,7 +978,7 @@ describe('session', () => {
|
||||
"refreshJwt": "alice-refresh-jwt-2",
|
||||
"service": "https://alice.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -1027,7 +1027,7 @@ describe('session', () => {
|
||||
"refreshJwt": "bob-refresh-jwt-2",
|
||||
"service": "https://bob.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
{
|
||||
"accessJwt": "alice-access-jwt-2",
|
||||
@@ -1040,7 +1040,7 @@ describe('session', () => {
|
||||
"refreshJwt": "alice-refresh-jwt-2",
|
||||
"service": "https://alice.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -1188,7 +1188,7 @@ describe('session', () => {
|
||||
"refreshJwt": "alice-refresh-jwt-1",
|
||||
"service": "https://alice.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -1251,7 +1251,7 @@ describe('session', () => {
|
||||
"refreshJwt": undefined,
|
||||
"service": "https://alice.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -1314,7 +1314,7 @@ describe('session', () => {
|
||||
"refreshJwt": undefined,
|
||||
"service": "https://alice.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -1406,7 +1406,7 @@ describe('session', () => {
|
||||
"refreshJwt": "jay-refresh-jwt-1",
|
||||
"service": "https://jay.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
{
|
||||
"accessJwt": "bob-access-jwt-2",
|
||||
@@ -1419,7 +1419,7 @@ describe('session', () => {
|
||||
"refreshJwt": "bob-refresh-jwt-2",
|
||||
"service": "https://alice.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
@@ -1466,7 +1466,7 @@ describe('session', () => {
|
||||
"refreshJwt": "clarence-refresh-jwt-2",
|
||||
"service": "https://clarence.com/",
|
||||
"signupQueued": false,
|
||||
"status": "active",
|
||||
"status": undefined,
|
||||
},
|
||||
],
|
||||
"currentAgentState": {
|
||||
|
||||
@@ -236,7 +236,7 @@ export function agentToSessionAccount(
|
||||
accessJwt: agent.session.accessJwt,
|
||||
signupQueued: isSignupQueued(agent.session.accessJwt),
|
||||
// @ts-expect-error TODO remove when backend is ready
|
||||
status: agent.session.status || 'active',
|
||||
status: agent.session.status,
|
||||
pdsUrl: agent.pdsUrl?.toString(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,7 +129,11 @@ export function Feed({
|
||||
)
|
||||
} else if (item === LOADING_ITEM) {
|
||||
return (
|
||||
<View style={[pal.border, {borderTopWidth: hairlineWidth}]}>
|
||||
<View
|
||||
style={[
|
||||
pal.border,
|
||||
!isTabletOrMobile && {borderTopWidth: hairlineWidth},
|
||||
]}>
|
||||
<NotificationFeedLoadingPlaceholder />
|
||||
</View>
|
||||
)
|
||||
@@ -185,6 +189,7 @@ export function Feed({
|
||||
desktopFixedHeight
|
||||
initialNumToRender={initialNumToRender}
|
||||
windowSize={11}
|
||||
sideBorders={false}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
|
||||
@@ -29,6 +29,7 @@ import {colors, s} from 'lib/styles'
|
||||
import {TextLink} from 'view/com/util/Link'
|
||||
import {ListMethods} from 'view/com/util/List'
|
||||
import {LoadLatestBtn} from 'view/com/util/load-latest/LoadLatestBtn'
|
||||
import {CenteredView} from 'view/com/util/Views'
|
||||
import {Feed} from '../com/notifications/Feed'
|
||||
import {FAB} from '../com/util/fab/FAB'
|
||||
import {MainScrollProvider} from '../com/util/MainScrollProvider'
|
||||
@@ -145,7 +146,10 @@ export function NotificationsScreen({}: Props) {
|
||||
}, [isDesktop, pal, hasNew])
|
||||
|
||||
return (
|
||||
<View testID="notificationsScreen" style={s.hContentRegion}>
|
||||
<CenteredView
|
||||
testID="notificationsScreen"
|
||||
style={s.hContentRegion}
|
||||
sideBorders={true}>
|
||||
<ViewHeader
|
||||
title={_(msg`Notifications`)}
|
||||
canGoBack={false}
|
||||
@@ -173,6 +177,6 @@ export function NotificationsScreen({}: Props) {
|
||||
accessibilityLabel={_(msg`New post`)}
|
||||
accessibilityHint=""
|
||||
/>
|
||||
</View>
|
||||
</CenteredView>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import {NoFollowingFeed} from '#/screens/Feeds/NoFollowingFeed'
|
||||
import {NoSavedFeedsOfAnyType} from '#/screens/Feeds/NoSavedFeedsOfAnyType'
|
||||
import {atoms as a, useTheme} from '#/alf'
|
||||
import {FilterTimeline_Stroke2_Corner0_Rounded as FilterTimeline} from '#/components/icons/FilterTimeline'
|
||||
import hairlineWidth = StyleSheet.hairlineWidth
|
||||
|
||||
const HITSLOP_TOP = {
|
||||
top: 20,
|
||||
@@ -92,7 +93,7 @@ export function SavedFeeds({}: Props) {
|
||||
<ViewHeader title={_(msg`Edit My Feeds`)} showOnDesktop showBorder />
|
||||
<ScrollView style={s.flex1} contentContainerStyle={[styles.noBorder]}>
|
||||
{noSavedFeedsOfAnyType && (
|
||||
<View style={[pal.border, {borderBottomWidth: 1}]}>
|
||||
<View style={[pal.border, {borderBottomWidth: hairlineWidth}]}>
|
||||
<NoSavedFeedsOfAnyType />
|
||||
</View>
|
||||
)}
|
||||
@@ -134,7 +135,7 @@ export function SavedFeeds({}: Props) {
|
||||
)}
|
||||
|
||||
{noFollowingFeed && (
|
||||
<View style={[pal.border, {borderBottomWidth: 1}]}>
|
||||
<View style={[pal.border, {borderBottomWidth: hairlineWidth}]}>
|
||||
<NoFollowingFeed />
|
||||
</View>
|
||||
)}
|
||||
@@ -298,9 +299,10 @@ function ListItem({
|
||||
<FeedSourceCard
|
||||
key={feedUri}
|
||||
feedUri={feedUri}
|
||||
style={[styles.noTopBorder, isPinned && {paddingRight: 8}]}
|
||||
style={[isPinned && {paddingRight: 8}]}
|
||||
showMinimalPlaceholder
|
||||
showSaveBtn={!isPinned}
|
||||
hideTopBorder={true}
|
||||
/>
|
||||
)}
|
||||
{isPinned ? (
|
||||
@@ -435,15 +437,12 @@ const styles = StyleSheet.create({
|
||||
paddingHorizontal: 14,
|
||||
paddingTop: 20,
|
||||
paddingBottom: 10,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomWidth: hairlineWidth,
|
||||
},
|
||||
itemContainer: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
borderBottomWidth: 1,
|
||||
},
|
||||
noTopBorder: {
|
||||
borderTopWidth: 0,
|
||||
borderBottomWidth: hairlineWidth,
|
||||
},
|
||||
footerText: {
|
||||
paddingHorizontal: 26,
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
TextInput,
|
||||
View,
|
||||
} from 'react-native'
|
||||
import {ScrollView as RNGHScrollView} from 'react-native-gesture-handler'
|
||||
import {AppBskyActorDefs, AppBskyFeedDefs, moderateProfile} from '@atproto/api'
|
||||
import {
|
||||
FontAwesomeIcon,
|
||||
@@ -957,6 +958,7 @@ function SearchHistory({
|
||||
}) {
|
||||
const {isTabletOrDesktop, isMobile} = useWebMediaQueries()
|
||||
const pal = usePalette('default')
|
||||
const {_} = useLingui()
|
||||
|
||||
return (
|
||||
<CenteredView
|
||||
@@ -977,7 +979,7 @@ function SearchHistory({
|
||||
styles.selectedProfilesContainer,
|
||||
isMobile && styles.selectedProfilesContainerMobile,
|
||||
]}>
|
||||
<ScrollView
|
||||
<RNGHScrollView
|
||||
keyboardShouldPersistTaps="handled"
|
||||
horizontal={true}
|
||||
style={styles.profilesRow}
|
||||
@@ -1009,8 +1011,10 @@ function SearchHistory({
|
||||
</Link>
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel="Remove profile"
|
||||
accessibilityHint="Remove profile from search history"
|
||||
accessibilityLabel={_(msg`Remove profile`)}
|
||||
accessibilityHint={_(
|
||||
msg`Remove profile from search history`,
|
||||
)}
|
||||
onPress={() => onRemoveProfileClick(profile)}
|
||||
hitSlop={createHitslop(6)}
|
||||
style={styles.profileRemoveBtn}>
|
||||
@@ -1022,7 +1026,7 @@ function SearchHistory({
|
||||
</Pressable>
|
||||
</View>
|
||||
))}
|
||||
</ScrollView>
|
||||
</RNGHScrollView>
|
||||
</View>
|
||||
)}
|
||||
{searchHistory.length > 0 && (
|
||||
|
||||
Reference in New Issue
Block a user