diff options
Diffstat (limited to 'src/view')
-rw-r--r-- | src/view/com/modals/Modal.tsx | 4 | ||||
-rw-r--r-- | src/view/com/modals/Modal.web.tsx | 3 | ||||
-rw-r--r-- | src/view/com/modals/PreferencesHomeFeed.tsx | 176 | ||||
-rw-r--r-- | src/view/index.ts | 6 | ||||
-rw-r--r-- | src/view/screens/Settings.tsx | 23 |
5 files changed, 210 insertions, 2 deletions
diff --git a/src/view/com/modals/Modal.tsx b/src/view/com/modals/Modal.tsx index 864dcc847..5989d9ff9 100644 --- a/src/view/com/modals/Modal.tsx +++ b/src/view/com/modals/Modal.tsx @@ -24,6 +24,7 @@ import * as InviteCodesModal from './InviteCodes' import * as AddAppPassword from './AddAppPasswords' import * as ContentFilteringSettingsModal from './ContentFilteringSettings' import * as ContentLanguagesSettingsModal from './ContentLanguagesSettings' +import * as PreferencesHomeFeed from './PreferencesHomeFeed' const DEFAULT_SNAPPOINTS = ['90%'] @@ -105,6 +106,9 @@ export const ModalsContainer = observer(function ModalsContainer() { } else if (activeModal?.name === 'content-languages-settings') { snapPoints = ContentLanguagesSettingsModal.snapPoints element = <ContentLanguagesSettingsModal.Component /> + } else if (activeModal?.name === 'preferences-home-feed') { + snapPoints = PreferencesHomeFeed.snapPoints + element = <PreferencesHomeFeed.Component /> } else { return null } diff --git a/src/view/com/modals/Modal.web.tsx b/src/view/com/modals/Modal.web.tsx index 27b2641ba..3895d47ac 100644 --- a/src/view/com/modals/Modal.web.tsx +++ b/src/view/com/modals/Modal.web.tsx @@ -24,6 +24,7 @@ import * as InviteCodesModal from './InviteCodes' import * as AddAppPassword from './AddAppPasswords' import * as ContentFilteringSettingsModal from './ContentFilteringSettings' import * as ContentLanguagesSettingsModal from './ContentLanguagesSettings' +import * as PreferencesHomeFeed from './PreferencesHomeFeed' export const ModalsContainer = observer(function ModalsContainer() { const store = useStores() @@ -97,6 +98,8 @@ function Modal({modal}: {modal: ModalIface}) { element = <AltTextImageModal.Component {...modal} /> } else if (modal.name === 'edit-image') { element = <EditImageModal.Component {...modal} /> + } else if (modal.name === 'preferences-home-feed') { + element = <PreferencesHomeFeed.Component /> } else { return null } diff --git a/src/view/com/modals/PreferencesHomeFeed.tsx b/src/view/com/modals/PreferencesHomeFeed.tsx new file mode 100644 index 000000000..14bf01e7d --- /dev/null +++ b/src/view/com/modals/PreferencesHomeFeed.tsx @@ -0,0 +1,176 @@ +import React, {useState} from 'react' +import {StyleSheet, TouchableOpacity, View} from 'react-native' +import {observer} from 'mobx-react-lite' +import {Slider} from '@miblanchard/react-native-slider' +import {Text} from '../util/text/Text' +import {useStores} from 'state/index' +import {s, colors} from 'lib/styles' +import {usePalette} from 'lib/hooks/usePalette' +import {isWeb, isDesktopWeb} from 'platform/detection' +import {ToggleButton} from 'view/com/util/forms/ToggleButton' +import {ScrollView} from 'view/com/modals/util' + +export const snapPoints = ['90%'] + +function RepliesThresholdInput({enabled}: {enabled: boolean}) { + const store = useStores() + const [value, setValue] = useState(store.preferences.homeFeedRepliesThreshold) + + return ( + <View style={[s.mt10, !enabled && styles.dimmed]}> + <Text type="xs"> + {value === 0 + ? `Show all replies` + : `Show replies with greater than ${value} ${ + value > 1 ? `likes` : `like` + }`} + </Text> + <Slider + value={value} + onValueChange={(v: number | number[]) => { + const threshold = Math.floor(Array.isArray(v) ? v[0] : v) + setValue(threshold) + store.preferences.setHomeFeedRepliesThreshold(threshold) + }} + minimumValue={0} + maximumValue={25} + containerStyle={isWeb ? undefined : s.flex1} + disabled={!enabled} + thumbTintColor={colors.blue3} + /> + </View> + ) +} + +export const Component = observer(function Component() { + const pal = usePalette('default') + const store = useStores() + + return ( + <View + testID="preferencesHomeFeedModal" + style={[pal.view, styles.container]}> + <View style={styles.titleSection}> + <Text type="title-lg" style={[pal.text, styles.title]}> + Home Feed Preferences + </Text> + <Text type="xl" style={[pal.textLight, styles.description]}> + Fine-tune the content you see on your home screen. + </Text> + </View> + + <ScrollView> + <View style={styles.cardsContainer}> + <View style={[styles.card]}> + <Text type="title-sm" style={[s.pb5]}> + Show Replies + </Text> + <Text style={[s.pb10]}> + Adjust the number of likes a reply must have to be shown in your + feed. + </Text> + <ToggleButton + type="default-light" + label={store.preferences.homeFeedRepliesEnabled ? 'Yes' : 'No'} + isSelected={store.preferences.homeFeedRepliesEnabled} + onPress={store.preferences.toggleHomeFeedRepliesEnabled} + /> + + <RepliesThresholdInput + enabled={store.preferences.homeFeedRepliesEnabled} + /> + </View> + + <View style={[styles.card]}> + <Text type="title-sm" style={[s.pb5]}> + Show Reposts + </Text> + <Text style={[s.pb10]}> + Disable this setting to hide all reposts from your feed. + </Text> + <ToggleButton + type="default-light" + label={store.preferences.homeFeedRepostsEnabled ? 'Yes' : 'No'} + isSelected={store.preferences.homeFeedRepostsEnabled} + onPress={store.preferences.toggleHomeFeedRepostsEnabled} + /> + </View> + + <View style={[styles.card]}> + <Text type="title-sm" style={[s.pb5]}> + Show Quote Posts + </Text> + <Text style={[s.pb10]}> + Disable this setting to hide all quote posts from your feed. + Reposts will still be visible. + </Text> + <ToggleButton + type="default-light" + label={store.preferences.homeFeedQuotePostsEnabled ? 'Yes' : 'No'} + isSelected={store.preferences.homeFeedQuotePostsEnabled} + onPress={store.preferences.toggleHomeFeedQuotePostsEnabled} + /> + </View> + </View> + </ScrollView> + + <View style={[styles.btnContainer, pal.borderDark]}> + <TouchableOpacity + testID="confirmBtn" + onPress={() => { + store.shell.closeModal() + }} + style={[styles.btn]} + accessibilityRole="button" + accessibilityLabel="Confirm" + accessibilityHint=""> + <Text style={[s.white, s.bold, s.f18]}>Done</Text> + </TouchableOpacity> + </View> + </View> + ) +}) + +const styles = StyleSheet.create({ + container: { + flex: 1, + paddingBottom: isDesktopWeb ? 0 : 60, + }, + titleSection: { + padding: 20, + paddingBottom: 30, + }, + title: { + textAlign: 'center', + marginBottom: 5, + }, + description: { + textAlign: 'center', + paddingHorizontal: 32, + }, + cardsContainer: { + paddingHorizontal: 20, + }, + card: { + padding: 16, + backgroundColor: s.gray1.color, + borderRadius: 10, + marginBottom: 20, + }, + btn: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + borderRadius: 32, + padding: 14, + backgroundColor: colors.blue3, + }, + btnContainer: { + paddingTop: 20, + paddingHorizontal: 20, + borderTopWidth: isDesktopWeb ? 0 : 1, + }, + dimmed: { + opacity: 0.3, + }, +}) diff --git a/src/view/index.ts b/src/view/index.ts index f06bdaccc..118a6de22 100644 --- a/src/view/index.ts +++ b/src/view/index.ts @@ -67,8 +67,9 @@ import {faSatelliteDish} from '@fortawesome/free-solid-svg-icons/faSatelliteDish import {faShare} from '@fortawesome/free-solid-svg-icons/faShare' import {faShareFromSquare} from '@fortawesome/free-solid-svg-icons/faShareFromSquare' import {faShield} from '@fortawesome/free-solid-svg-icons/faShield' -import {faSquarePlus} from '@fortawesome/free-regular-svg-icons/faSquarePlus' import {faSignal} from '@fortawesome/free-solid-svg-icons/faSignal' +import {faSliders} from '@fortawesome/free-solid-svg-icons/faSliders' +import {faSquarePlus} from '@fortawesome/free-regular-svg-icons/faSquarePlus' import {faTicket} from '@fortawesome/free-solid-svg-icons/faTicket' import {faTrashCan} from '@fortawesome/free-regular-svg-icons/faTrashCan' import {faUser} from '@fortawesome/free-regular-svg-icons/faUser' @@ -153,8 +154,9 @@ export function setup() { faShare, faShareFromSquare, faShield, - faSquarePlus, faSignal, + faSliders, + faSquarePlus, faUser, faUsers, faUserCheck, diff --git a/src/view/screens/Settings.tsx b/src/view/screens/Settings.tsx index 3d057451a..3f02bbee5 100644 --- a/src/view/screens/Settings.tsx +++ b/src/view/screens/Settings.tsx @@ -166,6 +166,12 @@ export const SettingsScreen = withAuthRequired( Toast.show('Copied build version to clipboard') }, []) + const openPreferencesModal = React.useCallback(() => { + store.shell.openModal({ + name: 'preferences-home-feed', + }) + }, [store]) + return ( <View style={[s.hContentRegion]} testID="settingsScreen"> <ViewHeader title="Settings" /> @@ -346,6 +352,23 @@ export const SettingsScreen = withAuthRequired( <Text type="xl-bold" style={[pal.text, styles.heading]}> Advanced </Text> + <TouchableOpacity + testID="preferencesHomeFeedModalButton" + style={[styles.linkCard, pal.view, isSwitching && styles.dimmed]} + onPress={openPreferencesModal} + accessibilityRole="button" + accessibilityHint="Open home feed preferences modal" + accessibilityLabel="Opens the home feed preferences modal"> + <View style={[styles.iconContainer, pal.btn]}> + <FontAwesomeIcon + icon="sliders" + style={pal.text as FontAwesomeIconStyle} + /> + </View> + <Text type="lg" style={pal.text}> + Home Feed Preferences + </Text> + </TouchableOpacity> <Link testID="appPasswordBtn" style={[styles.linkCard, pal.view, isSwitching && styles.dimmed]} |