Compare commits

..

2 Commits

Author SHA1 Message Date
Eric Bailey df5ff1b72e Override scrollRef types on profile 2023-11-17 10:46:59 -06:00
Eric Bailey 54bf784faf Fix some low-hanging type errors 2023-11-17 10:42:14 -06:00
13 changed files with 48 additions and 107 deletions
+4 -6
View File
@@ -1,4 +1,4 @@
import {useEffect, useState, useMemo, useCallback, useRef} from 'react'
import {useEffect, useState, useCallback, useRef} from 'react'
import EventEmitter from 'eventemitter3'
import {AppBskyFeedDefs} from '@atproto/api'
import {Shadow} from './types'
@@ -55,11 +55,9 @@ export function usePostShadow(
firstRun.current = false
}, [post])
return useMemo(() => {
return state.ts > ifAfterTS
? mergeShadow(post, state.value)
: {...post, isShadowed: true}
}, [post, state, ifAfterTS])
return state.ts > ifAfterTS
? mergeShadow(post, state.value)
: {...post, isShadowed: true}
}
export function updatePostShadow(uri: string, value: Partial<PostShadow>) {
+4 -6
View File
@@ -1,4 +1,4 @@
import {useEffect, useState, useMemo, useCallback, useRef} from 'react'
import {useEffect, useState, useCallback, useRef} from 'react'
import EventEmitter from 'eventemitter3'
import {AppBskyActorDefs} from '@atproto/api'
import {Shadow} from './types'
@@ -56,11 +56,9 @@ export function useProfileShadow(
firstRun.current = false
}, [profile])
return useMemo(() => {
return state.ts > ifAfterTS
? mergeShadow(profile, state.value)
: {...profile, isShadowed: true}
}, [profile, state, ifAfterTS])
return state.ts > ifAfterTS
? mergeShadow(profile, state.value)
: {...profile, isShadowed: true}
}
export function updateProfileShadow(
-12
View File
@@ -128,8 +128,6 @@ export async function migrate() {
const newData = transform(legacyData)
await write(newData)
logger.debug('persisted state: migrated legacy storage')
} else {
logger.debug('persisted state: no migration needed')
}
} catch (e) {
logger.error('persisted state: error migrating legacy storage', {
@@ -137,13 +135,3 @@ export async function migrate() {
})
}
}
export async function clearLegacyStorage() {
try {
await AsyncStorage.removeItem(DEPRECATED_ROOT_STATE_STORAGE_KEY)
} catch (e: any) {
logger.error(`persisted legacy store: failed to clear`, {
error: e.toString(),
})
}
}
-9
View File
@@ -1,7 +1,6 @@
import AsyncStorage from '@react-native-async-storage/async-storage'
import {Schema, schema} from '#/state/persisted/schema'
import {logger} from '#/logger'
const BSKY_STORAGE = 'BSKY_STORAGE'
@@ -17,11 +16,3 @@ export async function read(): Promise<Schema | undefined> {
return objData
}
}
export async function clear() {
try {
await AsyncStorage.removeItem(BSKY_STORAGE)
} catch (e: any) {
logger.error(`persisted store: failed to clear`, {error: e.toString()})
}
}
+15 -5
View File
@@ -1,6 +1,11 @@
import {useMemo} from 'react'
import {useEffect, useState} from 'react'
import {useQuery, useMutation, useQueryClient} from '@tanstack/react-query'
import {LabelPreference, BskyFeedViewPreference} from '@atproto/api'
import {
LabelPreference,
BskyFeedViewPreference,
ModerationOpts,
} from '@atproto/api'
import isEqual from 'lodash.isequal'
import {track} from '#/lib/analytics/analytics'
import {getAge} from '#/lib/strings/time'
@@ -86,16 +91,21 @@ export function usePreferencesQuery() {
export function useModerationOpts() {
const {currentAccount} = useSession()
const [opts, setOpts] = useState<ModerationOpts | undefined>()
const prefs = usePreferencesQuery()
const opts = useMemo(() => {
useEffect(() => {
if (!prefs.data) {
return
}
return getModerationOpts({
// only update this hook when the moderation options change
const newOpts = getModerationOpts({
userDid: currentAccount?.did || '',
preferences: prefs.data,
})
}, [currentAccount?.did, prefs.data])
if (!isEqual(opts, newOpts)) {
setOpts(newOpts)
}
}, [prefs.data, currentAccount, opts, setOpts])
return opts
}
+1 -6
View File
@@ -75,12 +75,7 @@ export function ProfileLists({
items = items.concat([EMPTY])
} else if (data?.pages) {
for (const page of data?.pages) {
items = items.concat(
page.lists.map(l => ({
...l,
_reactKey: l.uri,
})),
)
items = items.concat(page.lists)
}
}
if (isError && !isEmpty) {
+3 -5
View File
@@ -1,4 +1,4 @@
import React, {memo, useMemo, useState, useEffect} from 'react'
import React, {useMemo, useState, useEffect} from 'react'
import {
Animated,
TouchableOpacity,
@@ -56,7 +56,7 @@ interface Author {
moderation: ProfileModeration
}
let FeedItem = ({
export function FeedItem({
item,
dataUpdatedAt,
moderationOpts,
@@ -64,7 +64,7 @@ let FeedItem = ({
item: FeedNotification
dataUpdatedAt: number
moderationOpts: ModerationOpts
}): React.ReactNode => {
}) {
const pal = usePalette('default')
const [isAuthorsExpanded, setAuthorsExpanded] = useState<boolean>(false)
const itemHref = useMemo(() => {
@@ -262,8 +262,6 @@ let FeedItem = ({
</Link>
)
}
FeedItem = memo(FeedItem)
export {FeedItem}
function ExpandListPressable({
hasMultipleAuthors,
+4 -5
View File
@@ -1,4 +1,4 @@
import React, {memo, useMemo} from 'react'
import React, {useMemo} from 'react'
import {StyleSheet, View} from 'react-native'
import {
AtUri,
@@ -118,7 +118,7 @@ function PostThreadItemDeleted() {
)
}
let PostThreadItemLoaded = ({
function PostThreadItemLoaded({
post,
record,
richText,
@@ -144,12 +144,12 @@ let PostThreadItemLoaded = ({
showParentReplyLine?: boolean
hasPrecedingItem: boolean
onPostReply: () => void
}): React.ReactNode => {
}) {
const pal = usePalette('default')
const langPrefs = useLanguagePrefs()
const {openComposer} = useComposerControls()
const [limitLines, setLimitLines] = React.useState(
() => countLines(richText?.text) >= MAX_POST_LINES,
countLines(richText?.text) >= MAX_POST_LINES,
)
const styles = useStyles()
const hasEngagement = post.likeCount || post.repostCount
@@ -565,7 +565,6 @@ let PostThreadItemLoaded = ({
)
}
}
PostThreadItemLoaded = memo(PostThreadItemLoaded)
function PostOuterWrapper({
post,
+1 -1
View File
@@ -99,7 +99,7 @@ function PostInner({
const pal = usePalette('default')
const {openComposer} = useComposerControls()
const [limitLines, setLimitLines] = useState(
() => countLines(richText?.text) >= MAX_POST_LINES,
countLines(richText?.text) >= MAX_POST_LINES,
)
const itemUrip = new AtUri(post.uri)
const itemHref = makeProfileLink(post.author, 'post', itemUrip.rkey)
+1 -1
View File
@@ -106,7 +106,7 @@ let FeedItemInner = ({
const pal = usePalette('default')
const {track} = useAnalytics()
const [limitLines, setLimitLines] = useState(
() => countLines(richText.text) >= MAX_POST_LINES,
countLines(richText.text) >= MAX_POST_LINES,
)
const href = useMemo(() => {
-4
View File
@@ -38,10 +38,6 @@ import {useQueryClient} from '@tanstack/react-query'
import {useComposerControls} from '#/state/shell/composer'
import {listenSoftReset} from '#/state/events'
interface SectionRef {
scrollToTop: () => void
}
type Props = NativeStackScreenProps<CommonNavigatorParams, 'Profile'>
export const ProfileScreen = withAuthRequired(function ProfileScreenImpl({
route,
+15 -14
View File
@@ -119,28 +119,29 @@ function SearchScreenSuggestedFollows() {
React.useEffect(() => {
async function getSuggestions() {
// TODO not quite right, doesn't fetch your follows
const friends = await getSuggestedFollowsByActor(
currentAccount!.did,
).then(friendsRes => friendsRes.suggestions)
if (!friends) return // :(
const friendsOfFriends = new Map<
string,
AppBskyActorDefs.ProfileViewBasic
>()
const friendsOfFriends = (
await Promise.all(
friends
.slice(0, 4)
.map(friend =>
getSuggestedFollowsByActor(friend.did).then(
foafsRes => foafsRes.suggestions,
),
),
)
).flat()
await Promise.all(
friends.slice(0, 4).map(friend =>
getSuggestedFollowsByActor(friend.did).then(foafsRes => {
for (const user of foafsRes.suggestions) {
friendsOfFriends.set(user.did, user)
}
}),
),
setSuggestions(
// dedupe
friendsOfFriends.filter(f => !friends.find(f2 => f.did === f2.did)),
)
setSuggestions(Array.from(friendsOfFriends.values()))
setDataUpdatedAt(Date.now())
}
-33
View File
@@ -64,8 +64,6 @@ import {
import {useProfileQuery} from '#/state/queries/profile'
import {useClearPreferencesMutation} from '#/state/queries/preferences'
import {useInviteCodesQuery} from '#/state/queries/invites'
import {clear as clearStorage} from '#/state/persisted/store'
import {clearLegacyStorage} from '#/state/persisted/legacy'
// TEMPORARY (APP-700)
// remove after backend testing finishes
@@ -268,15 +266,6 @@ export const SettingsScreen = withAuthRequired(function Settings({}: Props) {
Linking.openURL(STATUS_PAGE_URL)
}, [])
const clearAllStorage = React.useCallback(async () => {
await clearStorage()
Toast.show(`Storage cleared, you need to restart the app now.`)
}, [])
const clearAllLegacyStorage = React.useCallback(async () => {
await clearLegacyStorage()
Toast.show(`Legacy storage cleared, you need to restart the app now.`)
}, [])
return (
<View style={[s.hContentRegion]} testID="settingsScreen">
<ViewHeader title="Settings" />
@@ -682,28 +671,6 @@ export const SettingsScreen = withAuthRequired(function Settings({}: Props) {
<Trans>Reset onboarding state</Trans>
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[pal.view, styles.linkCardNoIcon]}
onPress={clearAllLegacyStorage}
accessibilityRole="button"
accessibilityHint="Clear all legacy storage data"
accessibilityLabel={_(msg`Clear all legacy storage data`)}>
<Text type="lg" style={pal.text}>
<Trans>
Clear all legacy storage data (restart after this)
</Trans>
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[pal.view, styles.linkCardNoIcon]}
onPress={clearAllStorage}
accessibilityRole="button"
accessibilityHint="Clear all storage data"
accessibilityLabel={_(msg`Clear all storage data`)}>
<Text type="lg" style={pal.text}>
<Trans>Clear all storage data (restart after this)</Trans>
</Text>
</TouchableOpacity>
</>
) : null}
<View style={[styles.footer]}>