Bluesky app fork with some witchin' additions 💫

Move `PreferencesHomeFeed` to a screen instead of a modal (#1335)

* move `PreferencesHomeFeed` to a screen instead of a modal

* add web route for home feed preferences

* upgrade `@miblanchard/react-native-slider` to fix lint

* fix web route naming

* fix desktop web styling

* add `react-native-slider` mock

authored by Ansh and committed by GitHub 9446c678 a29f10ae

Changed files
+49 -38
__mocks__
@miblanchard
bskyweb
cmd
bskyweb
src
+1
__mocks__/@miblanchard/react-native-slider.js
··· 1 + export const Slider = {}
+1
bskyweb/cmd/bskyweb/server.go
··· 168 168 e.GET("/moderation/blocked-accounts", server.WebGeneric) 169 169 e.GET("/settings", server.WebGeneric) 170 170 e.GET("/settings/app-passwords", server.WebGeneric) 171 + e.GET("/settings/home-feed", server.WebGeneric) 171 172 e.GET("/settings/saved-feeds", server.WebGeneric) 172 173 e.GET("/sys/debug", server.WebGeneric) 173 174 e.GET("/sys/log", server.WebGeneric)
+1 -1
package.json
··· 36 36 "@fortawesome/react-native-fontawesome": "^0.3.0", 37 37 "@gorhom/bottom-sheet": "^4.4.7", 38 38 "@mattermost/react-native-paste-input": "^0.6.4", 39 - "@miblanchard/react-native-slider": "^2.2.0", 39 + "@miblanchard/react-native-slider": "^2.3.1", 40 40 "@react-native-async-storage/async-storage": "^1.17.6", 41 41 "@react-native-camera-roll/camera-roll": "^5.2.2", 42 42 "@react-native-clipboard/clipboard": "^1.10.0",
+6
src/Navigation.tsx
··· 67 67 import {bskyTitle} from 'lib/strings/headings' 68 68 import {JSX} from 'react/jsx-runtime' 69 69 import {timeout} from 'lib/async/timeout' 70 + import {PreferencesHomeFeed} from 'view/screens/PreferencesHomeFeed' 70 71 71 72 const navigationRef = createNavigationContainerRef<AllNavigatorParams>() 72 73 ··· 218 219 name="SavedFeeds" 219 220 component={SavedFeeds} 220 221 options={{title: title('Edit My Feeds')}} 222 + /> 223 + <Stack.Screen 224 + name="PreferencesHomeFeed" 225 + component={PreferencesHomeFeed} 226 + options={{title: title('Home Feed Preferences')}} 221 227 /> 222 228 </> 223 229 )
+1
src/lib/routes/types.ts
··· 29 29 CopyrightPolicy: undefined 30 30 AppPasswords: undefined 31 31 SavedFeeds: undefined 32 + PreferencesHomeFeed: undefined 32 33 } 33 34 34 35 export type BottomTabNavigatorParams = CommonNavigatorParams & {
+1
src/routes.ts
··· 23 23 Debug: '/sys/debug', 24 24 Log: '/sys/log', 25 25 AppPasswords: '/settings/app-passwords', 26 + PreferencesHomeFeed: '/settings/home-feed', 26 27 SavedFeeds: '/settings/saved-feeds', 27 28 Support: '/support', 28 29 PrivacyPolicy: '/support/privacy',
-5
src/state/models/ui/shell.ts
··· 136 136 name: 'post-languages-settings' 137 137 } 138 138 139 - export interface PreferencesHomeFeed { 140 - name: 'preferences-home-feed' 141 - } 142 - 143 139 export interface OnboardingModal { 144 140 name: 'onboarding' 145 141 } ··· 156 152 | ContentFilteringSettingsModal 157 153 | ContentLanguagesSettingsModal 158 154 | PostLanguagesSettingsModal 159 - | PreferencesHomeFeed 160 155 161 156 // Moderation 162 157 | ModerationDetailsModal
-4
src/view/com/modals/Modal.tsx
··· 28 28 import * as ContentFilteringSettingsModal from './ContentFilteringSettings' 29 29 import * as ContentLanguagesSettingsModal from './lang-settings/ContentLanguagesSettings' 30 30 import * as PostLanguagesSettingsModal from './lang-settings/PostLanguagesSettings' 31 - import * as PreferencesHomeFeed from './PreferencesHomeFeed' 32 31 import * as OnboardingModal from './OnboardingModal' 33 32 import * as ModerationDetailsModal from './ModerationDetails' 34 33 ··· 131 130 } else if (activeModal?.name === 'post-languages-settings') { 132 131 snapPoints = PostLanguagesSettingsModal.snapPoints 133 132 element = <PostLanguagesSettingsModal.Component /> 134 - } else if (activeModal?.name === 'preferences-home-feed') { 135 - snapPoints = PreferencesHomeFeed.snapPoints 136 - element = <PreferencesHomeFeed.Component /> 137 133 } else if (activeModal?.name === 'onboarding') { 138 134 snapPoints = OnboardingModal.snapPoints 139 135 element = <OnboardingModal.Component />
-4
src/view/com/modals/Modal.web.tsx
··· 29 29 import * as OnboardingModal from './OnboardingModal' 30 30 import * as ModerationDetailsModal from './ModerationDetails' 31 31 32 - import * as PreferencesHomeFeed from './PreferencesHomeFeed' 33 - 34 32 export const ModalsContainer = observer(function ModalsContainer() { 35 33 const store = useStores() 36 34 ··· 107 105 element = <AltTextImageModal.Component {...modal} /> 108 106 } else if (modal.name === 'edit-image') { 109 107 element = <EditImageModal.Component {...modal} /> 110 - } else if (modal.name === 'preferences-home-feed') { 111 - element = <PreferencesHomeFeed.Component /> 112 108 } else if (modal.name === 'onboarding') { 113 109 element = <OnboardingModal.Component /> 114 110 } else if (modal.name === 'moderation-details') {
+34 -18
src/view/com/modals/PreferencesHomeFeed.tsx src/view/screens/PreferencesHomeFeed.tsx
··· 1 1 import React, {useState} from 'react' 2 - import {StyleSheet, TouchableOpacity, View} from 'react-native' 2 + import {ScrollView, StyleSheet, TouchableOpacity, View} from 'react-native' 3 3 import {observer} from 'mobx-react-lite' 4 4 import {Slider} from '@miblanchard/react-native-slider' 5 - import {Text} from '../util/text/Text' 5 + import {Text} from '../com/util/text/Text' 6 6 import {useStores} from 'state/index' 7 7 import {s, colors} from 'lib/styles' 8 8 import {usePalette} from 'lib/hooks/usePalette' 9 9 import {isWeb, isDesktopWeb} from 'platform/detection' 10 10 import {ToggleButton} from 'view/com/util/forms/ToggleButton' 11 - import {ScrollView} from 'view/com/modals/util' 12 - 13 - export const snapPoints = ['90%'] 11 + import {CommonNavigatorParams, NativeStackScreenProps} from 'lib/routes/types' 12 + import {ViewHeader} from 'view/com/util/ViewHeader' 13 + import {CenteredView} from 'view/com/util/Views' 14 14 15 15 function RepliesThresholdInput({enabled}: {enabled: boolean}) { 16 16 const store = useStores() ··· 43 43 ) 44 44 } 45 45 46 - export const Component = observer(function Component() { 46 + type Props = NativeStackScreenProps< 47 + CommonNavigatorParams, 48 + 'PreferencesHomeFeed' 49 + > 50 + export const PreferencesHomeFeed = observer(({navigation}: Props) => { 47 51 const pal = usePalette('default') 48 52 const store = useStores() 49 53 50 54 return ( 51 - <View 52 - testID="preferencesHomeFeedModal" 53 - style={[pal.view, styles.container]}> 55 + <CenteredView 56 + testID="preferencesHomeFeedScreen" 57 + style={[ 58 + pal.view, 59 + pal.border, 60 + styles.container, 61 + isDesktopWeb && styles.desktopContainer, 62 + ]}> 63 + <ViewHeader title="Home Feed Preferences" showOnDesktop /> 54 64 <View style={styles.titleSection}> 55 - <Text type="title-lg" style={[pal.text, styles.title]}> 56 - Home Feed Preferences 57 - </Text> 58 65 <Text type="xl" style={[pal.textLight, styles.description]}> 59 66 Fine-tune the content you see on your home screen. 60 67 </Text> ··· 119 126 <TouchableOpacity 120 127 testID="confirmBtn" 121 128 onPress={() => { 122 - store.shell.closeModal() 129 + navigation.canGoBack() 130 + ? navigation.goBack() 131 + : navigation.navigate('Settings') 123 132 }} 124 - style={[styles.btn]} 133 + style={[styles.btn, isDesktopWeb && styles.btnDesktop]} 125 134 accessibilityRole="button" 126 135 accessibilityLabel="Confirm" 127 136 accessibilityHint=""> 128 137 <Text style={[s.white, s.bold, s.f18]}>Done</Text> 129 138 </TouchableOpacity> 130 139 </View> 131 - </View> 140 + </CenteredView> 132 141 ) 133 142 }) 134 143 135 144 const styles = StyleSheet.create({ 136 145 container: { 137 146 flex: 1, 138 - paddingBottom: isDesktopWeb ? 0 : 60, 147 + paddingBottom: isDesktopWeb ? 40 : 90, 148 + }, 149 + desktopContainer: { 150 + borderLeftWidth: 1, 151 + borderRightWidth: 1, 139 152 }, 140 153 titleSection: { 141 - padding: 20, 142 154 paddingBottom: 30, 155 + paddingTop: isDesktopWeb ? 20 : 0, 143 156 }, 144 157 title: { 145 158 textAlign: 'center', ··· 165 178 padding: 14, 166 179 backgroundColor: colors.blue3, 167 180 }, 181 + btnDesktop: { 182 + marginHorizontal: 'auto', 183 + paddingHorizontal: 80, 184 + }, 168 185 btnContainer: { 169 186 paddingTop: 20, 170 - paddingHorizontal: 20, 171 187 borderTopWidth: isDesktopWeb ? 0 : 1, 172 188 }, 173 189 dimmed: {
+3 -5
src/view/screens/Settings.tsx
··· 170 170 }, []) 171 171 172 172 const openPreferencesModal = React.useCallback(() => { 173 - store.shell.openModal({ 174 - name: 'preferences-home-feed', 175 - }) 176 - }, [store]) 173 + navigation.navigate('PreferencesHomeFeed') 174 + }, [navigation]) 177 175 178 176 const onPressAppPasswords = React.useCallback(() => { 179 177 navigation.navigate('AppPasswords') ··· 386 384 Advanced 387 385 </Text> 388 386 <TouchableOpacity 389 - testID="preferencesHomeFeedModalButton" 387 + testID="preferencesHomeFeedButton" 390 388 style={[styles.linkCard, pal.view, isSwitching && styles.dimmed]} 391 389 onPress={openPreferencesModal} 392 390 accessibilityRole="button"
+1 -1
yarn.lock
··· 3497 3497 dependencies: 3498 3498 semver "7.5.4" 3499 3499 3500 - "@miblanchard/react-native-slider@^2.2.0": 3500 + "@miblanchard/react-native-slider@^2.3.1": 3501 3501 version "2.3.1" 3502 3502 resolved "https://registry.yarnpkg.com/@miblanchard/react-native-slider/-/react-native-slider-2.3.1.tgz#79e0f1f9b1ce43ef25ee51ee9256c012e5dfa412" 3503 3503 integrity sha512-J/hZDBWmXq8fJeOnTVHqIUVDHshqMSpJVxJ4WqwuCBKl5Rke9OBYXIdkSlgi75OgtScAr8FKK5KNkDKHUf6JIg==