diff options
author | Paul Frazee <pfrazee@gmail.com> | 2023-05-11 16:08:21 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-05-11 16:08:21 -0500 |
commit | ebcd6333863a2073278fad482981d9898c0f20ca (patch) | |
tree | 9417a5c282fc6ce22af2251f437f02b0700c7714 /src/view/screens/ModerationMutedAccounts.tsx | |
parent | 34d8fa59916d87922c83a6cf93e3e288d43dadcc (diff) | |
download | voidsky-ebcd6333863a2073278fad482981d9898c0f20ca.tar.zst |
[APP-635] Mutelists (#601)
* Add lists and profilelist screens * Implement lists screen and lists-list in profiles * Add empty states to the lists screen * Switch (mostly) from blocklists to mutelists * Rework: create a new moderation screen and move everything related under it * Fix moderation screen on desktop web * Tune the empty state code * Change content moderation modal to content filtering * Add CreateMuteList modal * Implement mutelist creation * Add lists listings * Add the ability to create new mutelists * Add 'add to list' tool * Satisfy the hashtag hyphen haters * Add update/delete/subscribe/unsubscribe to lists * Show which list caused a mute * Add list un/subscribe * Add the mute override when viewing a profile's posts * Update to latest backend * Add simulation tests and tune some behaviors * Fix lint * Bump deps * Fix list refresh after creation * Mute list subscriptions -> Mute lists
Diffstat (limited to 'src/view/screens/ModerationMutedAccounts.tsx')
-rw-r--r-- | src/view/screens/ModerationMutedAccounts.tsx | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/src/view/screens/ModerationMutedAccounts.tsx b/src/view/screens/ModerationMutedAccounts.tsx new file mode 100644 index 000000000..ec732f682 --- /dev/null +++ b/src/view/screens/ModerationMutedAccounts.tsx @@ -0,0 +1,171 @@ +import React, {useMemo} from 'react' +import { + ActivityIndicator, + FlatList, + RefreshControl, + StyleSheet, + View, +} from 'react-native' +import {AppBskyActorDefs as ActorDefs} from '@atproto/api' +import {Text} from '../com/util/text/Text' +import {useStores} from 'state/index' +import {usePalette} from 'lib/hooks/usePalette' +import {isDesktopWeb} from 'platform/detection' +import {withAuthRequired} from 'view/com/auth/withAuthRequired' +import {observer} from 'mobx-react-lite' +import {NativeStackScreenProps} from '@react-navigation/native-stack' +import {CommonNavigatorParams} from 'lib/routes/types' +import {MutedAccountsModel} from 'state/models/lists/muted-accounts' +import {useAnalytics} from 'lib/analytics' +import {useFocusEffect} from '@react-navigation/native' +import {ViewHeader} from '../com/util/ViewHeader' +import {CenteredView} from 'view/com/util/Views' +import {ProfileCard} from 'view/com/profile/ProfileCard' + +type Props = NativeStackScreenProps< + CommonNavigatorParams, + 'ModerationMutedAccounts' +> +export const ModerationMutedAccounts = withAuthRequired( + observer(({}: Props) => { + const pal = usePalette('default') + const store = useStores() + const {screen} = useAnalytics() + const mutedAccounts = useMemo(() => new MutedAccountsModel(store), [store]) + + useFocusEffect( + React.useCallback(() => { + screen('MutedAccounts') + store.shell.setMinimalShellMode(false) + mutedAccounts.refresh() + }, [screen, store, mutedAccounts]), + ) + + const onRefresh = React.useCallback(() => { + mutedAccounts.refresh() + }, [mutedAccounts]) + const onEndReached = React.useCallback(() => { + mutedAccounts + .loadMore() + .catch(err => + store.log.error('Failed to load more muted accounts', err), + ) + }, [mutedAccounts, store]) + + const renderItem = ({ + item, + index, + }: { + item: ActorDefs.ProfileView + index: number + }) => ( + <ProfileCard + testID={`mutedAccount-${index}`} + key={item.did} + profile={item} + overrideModeration + /> + ) + return ( + <CenteredView + style={[ + styles.container, + isDesktopWeb && styles.containerDesktop, + pal.view, + pal.border, + ]} + testID="mutedAccountsScreen"> + <ViewHeader title="Muted Accounts" showOnDesktop /> + <Text + type="sm" + style={[ + styles.description, + pal.text, + isDesktopWeb && styles.descriptionDesktop, + ]}> + Muted accounts have their posts removed from your feed and from your + notifications. Mutes are completely private. + </Text> + {!mutedAccounts.hasContent ? ( + <View style={[pal.border, !isDesktopWeb && styles.flex1]}> + <View style={[styles.empty, pal.viewLight]}> + <Text type="lg" style={[pal.text, styles.emptyText]}> + You have not muted any accounts yet. To mute an account, go to + their profile and selected "Mute account" from the menu on their + account. + </Text> + </View> + </View> + ) : ( + <FlatList + style={[!isDesktopWeb && styles.flex1]} + data={mutedAccounts.mutes} + keyExtractor={(item: ActorDefs.ProfileView) => item.did} + refreshControl={ + <RefreshControl + refreshing={mutedAccounts.isRefreshing} + onRefresh={onRefresh} + tintColor={pal.colors.text} + titleColor={pal.colors.text} + /> + } + onEndReached={onEndReached} + renderItem={renderItem} + initialNumToRender={15} + ListFooterComponent={() => ( + <View style={styles.footer}> + {mutedAccounts.isLoading && <ActivityIndicator />} + </View> + )} + extraData={mutedAccounts.isLoading} + // @ts-ignore our .web version only -prf + desktopFixedHeight + /> + )} + </CenteredView> + ) + }), +) + +const styles = StyleSheet.create({ + container: { + flex: 1, + paddingBottom: isDesktopWeb ? 0 : 100, + }, + containerDesktop: { + borderLeftWidth: 1, + borderRightWidth: 1, + }, + title: { + textAlign: 'center', + marginTop: 12, + marginBottom: 12, + }, + description: { + textAlign: 'center', + paddingHorizontal: 30, + marginBottom: 14, + }, + descriptionDesktop: { + marginTop: 14, + }, + + flex1: { + flex: 1, + }, + empty: { + paddingHorizontal: 20, + paddingVertical: 20, + borderRadius: 16, + marginHorizontal: 24, + marginTop: 10, + }, + emptyText: { + textAlign: 'center', + }, + + footer: { + height: 200, + paddingTop: 20, + }, +}) |