From 1befc04dcb7c13e9fc231452bcd767126bd343ce Mon Sep 17 00:00:00 2001 From: Paul Frazee Date: Sun, 7 May 2023 12:06:14 -0500 Subject: [PATCH] Add the ability to create new mutelists --- src/view/com/lists/ListsList.tsx | 48 +++++++++++++++- src/view/com/modals/CreateMuteList.tsx | 8 ++- src/view/com/modals/Modal.tsx | 2 +- src/view/com/util/ViewHeader.tsx | 8 ++- src/view/screens/ModerationMuteLists.tsx | 70 +++++++++++------------- 5 files changed, 93 insertions(+), 43 deletions(-) diff --git a/src/view/com/lists/ListsList.tsx b/src/view/com/lists/ListsList.tsx index e50361be64..a6eed0ff4c 100644 --- a/src/view/com/lists/ListsList.tsx +++ b/src/view/com/lists/ListsList.tsx @@ -8,17 +8,25 @@ import { ViewStyle, } from 'react-native' import {observer} from 'mobx-react-lite' +import { + FontAwesomeIcon, + FontAwesomeIconStyle, +} from '@fortawesome/react-native-fontawesome' import {FlatList} from '../util/Views' import {ListCard} from './ListCard' import {ProfileCardFeedLoadingPlaceholder} from '../util/LoadingPlaceholder' import {ErrorMessage} from '../util/error/ErrorMessage' import {LoadMoreRetryBtn} from '../util/LoadMoreRetryBtn' +import {Button} from '../util/forms/Button' +import {Text} from '../util/text/Text' import {ListsListModel} from 'state/models/lists/lists-list' import {useAnalytics} from 'lib/analytics' import {usePalette} from 'lib/hooks/usePalette' import {s} from 'lib/styles' +import {isDesktopWeb} from 'platform/detection' const LOADING_ITEM = {_reactKey: '__loading__'} +const CREATENEW_ITEM = {_reactKey: '__loading__'} const EMPTY_ITEM = {_reactKey: '__empty__'} const ERROR_ITEM = {_reactKey: '__error__'} const LOAD_MORE_ERROR_ITEM = {_reactKey: '__load_more_error__'} @@ -27,17 +35,17 @@ export const ListsList = observer( ({ listsList, style, - showPostFollowBtn, scrollElRef, onPressTryAgain, + onPressCreateNew, renderEmptyState, testID, headerOffset = 0, }: { listsList: ListsListModel style?: StyleProp - showPostFollowBtn?: boolean scrollElRef?: MutableRefObject | null> + onPressCreateNew: () => void onPressTryAgain?: () => void renderEmptyState?: () => JSX.Element testID?: string @@ -56,6 +64,9 @@ export const ListsList = observer( if (listsList.isEmpty) { items = items.concat([EMPTY_ITEM]) } else { + if (isDesktopWeb) { + items = items.concat([CREATENEW_ITEM]) + } items = items.concat(listsList.lists) } if (listsList.loadMoreError) { @@ -111,6 +122,8 @@ export const ListsList = observer( return renderEmptyState() } return + } else if (item === CREATENEW_ITEM) { + return } else if (item === ERROR_ITEM) { return ( }, - [listsList, onPressTryAgain, onPressRetryLoadMore, showPostFollowBtn], + [listsList, onPressTryAgain, onPressRetryLoadMore, onPressCreateNew], ) const Footer = React.useCallback( @@ -179,6 +192,35 @@ export const ListsList = observer( }, ) +function CreateNewItem({onPress}: {onPress: () => void}) { + const palInverted = usePalette('inverted') + + return ( + + + + ) +} + const styles = StyleSheet.create({ + createNewContainer: { + flexDirection: 'row', + alignItems: 'center', + paddingVertical: 16, + paddingHorizontal: 18, + }, + createNewButton: { + flexDirection: 'row', + alignItems: 'center', + gap: 8, + }, feedFooter: {paddingTop: 20}, }) diff --git a/src/view/com/modals/CreateMuteList.tsx b/src/view/com/modals/CreateMuteList.tsx index 1af0504c16..8b8cf4a164 100644 --- a/src/view/com/modals/CreateMuteList.tsx +++ b/src/view/com/modals/CreateMuteList.tsx @@ -23,6 +23,7 @@ import {usePalette} from 'lib/hooks/usePalette' import {useTheme} from 'lib/ThemeContext' import {useAnalytics} from 'lib/analytics' import {cleanError, isNetworkError} from 'lib/strings/errors' +import {isDesktopWeb} from 'platform/detection' const MAX_NAME = 64 // todo const MAX_DESCRIPTION = 300 // todo @@ -104,7 +105,9 @@ export function Component({onCreate}: {onCreate?: (uri: string) => void}) { return ( - + New Mute List {error !== '' && ( @@ -190,6 +193,9 @@ export function Component({onCreate}: {onCreate?: (uri: string) => void}) { } const styles = StyleSheet.create({ + container: { + paddingHorizontal: isDesktopWeb ? 0 : 16, + }, title: { textAlign: 'center', fontWeight: 'bold', diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx index 4f7d098085..453e7435ec 100644 --- a/src/view/com/modals/Modal.tsx +++ b/src/view/com/modals/Modal.tsx @@ -68,7 +68,7 @@ export const ModalsContainer = observer(function ModalsContainer() { snapPoints = ReportAccountModal.snapPoints element = } else if (activeModal?.name === 'create-mute-list') { - snapPoints = ReportAccountModal.snapPoints + snapPoints = CreateMuteListModal.snapPoints element = } else if (activeModal?.name === 'delete-account') { snapPoints = DeleteAccountModal.snapPoints diff --git a/src/view/com/util/ViewHeader.tsx b/src/view/com/util/ViewHeader.tsx index 7f5b5b7c21..8ebbf486ef 100644 --- a/src/view/com/util/ViewHeader.tsx +++ b/src/view/com/util/ViewHeader.tsx @@ -20,11 +20,13 @@ export const ViewHeader = observer(function ({ canGoBack, hideOnScroll, showOnDesktop, + renderButton, }: { title: string canGoBack?: boolean hideOnScroll?: boolean showOnDesktop?: boolean + renderButton?: () => JSX.Element }) { const pal = usePalette('default') const store = useStores() @@ -79,7 +81,11 @@ export const ViewHeader = observer(function ({ {title} - + {renderButton ? ( + renderButton() + ) : ( + + )} ) } diff --git a/src/view/screens/ModerationMuteLists.tsx b/src/view/screens/ModerationMuteLists.tsx index ab7d566787..a5dd82cb15 100644 --- a/src/view/screens/ModerationMuteLists.tsx +++ b/src/view/screens/ModerationMuteLists.tsx @@ -1,10 +1,10 @@ import React from 'react' import {StyleSheet} from 'react-native' +import {useFocusEffect, useNavigation} from '@react-navigation/native' import { - useFocusEffect, - useNavigation, - StackActions, -} from '@react-navigation/native' + FontAwesomeIcon, + FontAwesomeIconStyle, +} from '@fortawesome/react-native-fontawesome' import {AtUri} from '@atproto/api' import {NativeStackScreenProps, CommonNavigatorParams} from 'lib/routes/types' import {withAuthRequired} from 'view/com/auth/withAuthRequired' @@ -12,6 +12,7 @@ import {EmptyStateWithButton} from 'view/com/util/EmptyStateWithButton' import {useStores} from 'state/index' import {ListsListModel} from 'state/models/lists/lists-list' import {ListsList} from 'view/com/lists/ListsList' +import {Button} from 'view/com/util/forms/Button' import {NavigationProp} from 'lib/routes/types' import {usePalette} from 'lib/hooks/usePalette' import {CenteredView} from 'view/com/util/Views' @@ -65,6 +66,22 @@ export const ModerationMuteListsScreen = withAuthRequired(({route}: Props) => { ) }, [onPressNewMuteList]) + const renderHeaderButton = React.useCallback( + () => ( + + ), + [onPressNewMuteList, pal], + ) + return ( { pal.border, ]} testID="moderationMutelistsScreen"> - - + + ) }) @@ -89,36 +114,7 @@ const styles = StyleSheet.create({ 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, + createBtn: { + width: 40, }, })