mirror of
				https://github.com/tooot-app/app
				synced 2025-06-05 22:19:13 +02:00 
			
		
		
		
	
							
								
								
									
										1
									
								
								src/@types/mastodon.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								src/@types/mastodon.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -452,6 +452,7 @@ declare namespace Mastodon { | |||||||
|     'posting:default:language'?: string |     'posting:default:language'?: string | ||||||
|     'reading:expand:media'?: 'default' | 'show_all' | 'hide_all' |     'reading:expand:media'?: 'default' | 'show_all' | 'hide_all' | ||||||
|     'reading:expand:spoilers'?: boolean |     'reading:expand:spoilers'?: boolean | ||||||
|  |     'reading:autoplay:gifs'?: boolean | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   type PushSubscription = { |   type PushSubscription = { | ||||||
|   | |||||||
| @@ -1,17 +1,19 @@ | |||||||
| import { StyleConstants } from '@utils/styles/constants' | import { StyleConstants } from '@utils/styles/constants' | ||||||
| import React from 'react' | import React from 'react' | ||||||
| import { View } from 'react-native' | import { View, ViewStyle } from 'react-native' | ||||||
|  |  | ||||||
| export interface Props { | export interface Props { | ||||||
|  |   style?: ViewStyle | ||||||
|   children: React.ReactNode |   children: React.ReactNode | ||||||
| } | } | ||||||
|  |  | ||||||
| const MenuContainer: React.FC<Props> = ({ children }) => { | const MenuContainer: React.FC<Props> = ({ style, children }) => { | ||||||
|   return ( |   return ( | ||||||
|     <View |     <View | ||||||
|       style={{ |       style={{ | ||||||
|         paddingHorizontal: StyleConstants.Spacing.Global.PagePadding, |         paddingHorizontal: StyleConstants.Spacing.Global.PagePadding, | ||||||
|         marginBottom: StyleConstants.Spacing.Global.PagePadding |         marginBottom: StyleConstants.Spacing.Global.PagePadding, | ||||||
|  |         ...style | ||||||
|       }} |       }} | ||||||
|     > |     > | ||||||
|       {children} |       {children} | ||||||
|   | |||||||
| @@ -13,7 +13,6 @@ import { StyleConstants } from '@utils/styles/constants' | |||||||
| import { useTheme } from '@utils/styles/ThemeManager' | import { useTheme } from '@utils/styles/ThemeManager' | ||||||
| import React from 'react' | import React from 'react' | ||||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||||
| import { View } from 'react-native' |  | ||||||
|  |  | ||||||
| export interface Props { | export interface Props { | ||||||
|   id: Mastodon.Account['id'] |   id: Mastodon.Account['id'] | ||||||
| @@ -127,7 +126,7 @@ const RelationshipOutgoing: React.FC<Props> = ({ id }: Props) => { | |||||||
|   const isPageNotifications = name === 'Tab-Notifications-Root' |   const isPageNotifications = name === 'Tab-Notifications-Root' | ||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <View style={{ flexDirection: 'row', alignItems: 'center' }}> |     <> | ||||||
|       {!isPageNotifications && canFollowNotify && query.data?.following ? ( |       {!isPageNotifications && canFollowNotify && query.data?.following ? ( | ||||||
|         <Button |         <Button | ||||||
|           type='icon' |           type='icon' | ||||||
| @@ -155,7 +154,7 @@ const RelationshipOutgoing: React.FC<Props> = ({ id }: Props) => { | |||||||
|         loading={query.isLoading || mutation.isLoading} |         loading={query.isLoading || mutation.isLoading} | ||||||
|         disabled={query.isError || query.data?.blocked_by} |         disabled={query.isError || query.data?.blocked_by} | ||||||
|       /> |       /> | ||||||
|     </View> |     </> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| import Button from '@components/Button' | import Button from '@components/Button' | ||||||
| import { useAccessibility } from '@utils/accessibility/AccessibilityManager' | import { useAccessibility } from '@utils/accessibility/AccessibilityManager' | ||||||
| import { useGlobalStorage } from '@utils/storage/actions' | import { useAccountStorage, useGlobalStorage } from '@utils/storage/actions' | ||||||
| import { StyleConstants } from '@utils/styles/constants' | import { StyleConstants } from '@utils/styles/constants' | ||||||
| import { ResizeMode, Video, VideoFullscreenUpdate } from 'expo-av' | import { ResizeMode, Video, VideoFullscreenUpdate } from 'expo-av' | ||||||
| import { Platform } from 'expo-modules-core' | import { Platform } from 'expo-modules-core' | ||||||
| @@ -28,6 +28,11 @@ const AttachmentVideo: React.FC<Props> = ({ | |||||||
| }) => { | }) => { | ||||||
|   const { reduceMotionEnabled } = useAccessibility() |   const { reduceMotionEnabled } = useAccessibility() | ||||||
|   const [autoplayGifv] = useGlobalStorage.boolean('app.auto_play_gifv') |   const [autoplayGifv] = useGlobalStorage.boolean('app.auto_play_gifv') | ||||||
|  |   const [preferences] = useAccountStorage.object('preferences') | ||||||
|  |   const shouldAutoplayGifv = | ||||||
|  |     preferences?.['reading:autoplay:gifs'] !== undefined | ||||||
|  |       ? preferences['reading:autoplay:gifs'] | ||||||
|  |       : autoplayGifv | ||||||
|  |  | ||||||
|   const videoPlayer = useRef<Video>(null) |   const videoPlayer = useRef<Video>(null) | ||||||
|   const [videoLoading, setVideoLoading] = useState(false) |   const [videoLoading, setVideoLoading] = useState(false) | ||||||
| @@ -63,7 +68,7 @@ const AttachmentVideo: React.FC<Props> = ({ | |||||||
|         resizeMode={videoResizeMode} |         resizeMode={videoResizeMode} | ||||||
|         {...(gifv |         {...(gifv | ||||||
|           ? { |           ? { | ||||||
|               shouldPlay: reduceMotionEnabled || !autoplayGifv ? false : true, |               shouldPlay: reduceMotionEnabled || !shouldAutoplayGifv ? false : true, | ||||||
|               isMuted: true, |               isMuted: true, | ||||||
|               isLooping: true, |               isLooping: true, | ||||||
|               source: { uri: video.url } |               source: { uri: video.url } | ||||||
| @@ -82,7 +87,7 @@ const AttachmentVideo: React.FC<Props> = ({ | |||||||
|               Platform.OS === 'android' && |               Platform.OS === 'android' && | ||||||
|                 (await ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.PORTRAIT)) |                 (await ScreenOrientation.lockAsync(ScreenOrientation.OrientationLock.PORTRAIT)) | ||||||
|               Platform.OS === 'android' && setVideoResizeMode(ResizeMode.COVER) |               Platform.OS === 'android' && setVideoResizeMode(ResizeMode.COVER) | ||||||
|               if (gifv && !reduceMotionEnabled && autoplayGifv) { |               if (gifv && !reduceMotionEnabled && shouldAutoplayGifv) { | ||||||
|                 videoPlayer.current?.playAsync() |                 videoPlayer.current?.playAsync() | ||||||
|               } else { |               } else { | ||||||
|                 videoPlayer.current?.pauseAsync() |                 videoPlayer.current?.pauseAsync() | ||||||
| @@ -116,7 +121,7 @@ const AttachmentVideo: React.FC<Props> = ({ | |||||||
|           video.blurhash ? ( |           video.blurhash ? ( | ||||||
|             <Blurhash blurhash={video.blurhash} style={{ width: '100%', height: '100%' }} /> |             <Blurhash blurhash={video.blurhash} style={{ width: '100%', height: '100%' }} /> | ||||||
|           ) : null |           ) : null | ||||||
|         ) : !gifv || (gifv && (reduceMotionEnabled || !autoplayGifv)) ? ( |         ) : !gifv || (gifv && (reduceMotionEnabled || !shouldAutoplayGifv)) ? ( | ||||||
|           <Button |           <Button | ||||||
|             round |             round | ||||||
|             overlay |             overlay | ||||||
| @@ -129,7 +134,7 @@ const AttachmentVideo: React.FC<Props> = ({ | |||||||
|         ) : null} |         ) : null} | ||||||
|         <AttachmentAltText sensitiveShown={sensitiveShown} text={video.description} /> |         <AttachmentAltText sensitiveShown={sensitiveShown} text={video.description} /> | ||||||
|       </Pressable> |       </Pressable> | ||||||
|       {gifv && !autoplayGifv ? ( |       {gifv && !shouldAutoplayGifv ? ( | ||||||
|         <Button |         <Button | ||||||
|           style={{ |           style={{ | ||||||
|             position: 'absolute', |             position: 'absolute', | ||||||
|   | |||||||
| @@ -69,6 +69,9 @@ | |||||||
|       "push": { |       "push": { | ||||||
|         "name": "Push Notification" |         "name": "Push Notification" | ||||||
|       }, |       }, | ||||||
|  |       "preferences": { | ||||||
|  |         "name": "Preferences" | ||||||
|  |       }, | ||||||
|       "profile": { |       "profile": { | ||||||
|         "name": "Edit Profile" |         "name": "Edit Profile" | ||||||
|       }, |       }, | ||||||
| @@ -84,9 +87,6 @@ | |||||||
|       "settings": { |       "settings": { | ||||||
|         "name": "App Settings" |         "name": "App Settings" | ||||||
|       }, |       }, | ||||||
|       "webSettings": { |  | ||||||
|         "name": "More Account Settings" |  | ||||||
|       }, |  | ||||||
|       "switch": { |       "switch": { | ||||||
|         "name": "Switch Account" |         "name": "Switch Account" | ||||||
|       } |       } | ||||||
| @@ -125,6 +125,37 @@ | |||||||
|         "message": "This action is not recoverable." |         "message": "This action is not recoverable." | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "preferences": { | ||||||
|  |       "visibility": { | ||||||
|  |         "title": "Posting visibility", | ||||||
|  |         "options": { | ||||||
|  |           "public": "Public", | ||||||
|  |           "unlisted": "Unlisted", | ||||||
|  |           "private": "Followers only" | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "sensitive": { | ||||||
|  |         "title": "Posting media sensitive" | ||||||
|  |       }, | ||||||
|  |       "media": { | ||||||
|  |         "title": "Media display", | ||||||
|  |         "options": { | ||||||
|  |           "default": "Hide media marked as sensitive", | ||||||
|  |           "show_all": "Always show media", | ||||||
|  |           "hide_all": "Always hide media" | ||||||
|  |         } | ||||||
|  |       }, | ||||||
|  |       "spoilers": { | ||||||
|  |         "title": "Auto expand toots with content warning", | ||||||
|  |       }, | ||||||
|  |       "autoplay_gifs": { | ||||||
|  |         "title": "Autoplay GIF in toots" | ||||||
|  |       }, | ||||||
|  |       "web_only": { | ||||||
|  |         "title": "Update settings", | ||||||
|  |         "description": "Settings below can only be updated using the web UI" | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "profile": { |     "profile": { | ||||||
|       "feedback": { |       "feedback": { | ||||||
|         "succeed": "{{type}} updated", |         "succeed": "{{type}} updated", | ||||||
| @@ -150,17 +181,6 @@ | |||||||
|           "total_one": "{{count}} field", |           "total_one": "{{count}} field", | ||||||
|           "total_other": "{{count}} fields" |           "total_other": "{{count}} fields" | ||||||
|         }, |         }, | ||||||
|         "visibility": { |  | ||||||
|           "title": "Posting Visibility", |  | ||||||
|           "options": { |  | ||||||
|             "public": "Public", |  | ||||||
|             "unlisted": "Unlisted", |  | ||||||
|             "private": "Followers only" |  | ||||||
|           } |  | ||||||
|         }, |  | ||||||
|         "sensitive": { |  | ||||||
|           "title": "Posting Media Sensitive" |  | ||||||
|         }, |  | ||||||
|         "lock": { |         "lock": { | ||||||
|           "title": "Lock Account", |           "title": "Lock Account", | ||||||
|           "description": "Requires you to manually approve followers" |           "description": "Requires you to manually approve followers" | ||||||
|   | |||||||
							
								
								
									
										158
									
								
								src/screens/Tabs/Me/Preferences.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								src/screens/Tabs/Me/Preferences.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,158 @@ | |||||||
|  | import { MenuContainer, MenuRow } from '@components/Menu' | ||||||
|  | import { Message } from '@components/Message' | ||||||
|  | import { useActionSheet } from '@expo/react-native-action-sheet' | ||||||
|  | import { androidActionSheetStyles } from '@utils/helpers/androidActionSheetStyles' | ||||||
|  | import browserPackage from '@utils/helpers/browserPackage' | ||||||
|  | import { TabMeProfileStackScreenProps } from '@utils/navigation/navigators' | ||||||
|  | import { usePreferencesQuery } from '@utils/queryHooks/preferences' | ||||||
|  | import { useProfileMutation } from '@utils/queryHooks/profile' | ||||||
|  | import { getAccountStorage } from '@utils/storage/actions' | ||||||
|  | import { StyleConstants } from '@utils/styles/constants' | ||||||
|  | import { useTheme } from '@utils/styles/ThemeManager' | ||||||
|  | import * as WebBrowser from 'expo-web-browser' | ||||||
|  | import React, { useRef } from 'react' | ||||||
|  | import { useTranslation } from 'react-i18next' | ||||||
|  | import FlashMessage from 'react-native-flash-message' | ||||||
|  | import { ScrollView } from 'react-native-gesture-handler' | ||||||
|  |  | ||||||
|  | const TabMePreferences: React.FC<TabMeProfileStackScreenProps<'Tab-Me-Profile-Root'>> = () => { | ||||||
|  |   const { colors } = useTheme() | ||||||
|  |   const { t } = useTranslation(['common', 'screenTabs']) | ||||||
|  |  | ||||||
|  |   const { showActionSheetWithOptions } = useActionSheet() | ||||||
|  |  | ||||||
|  |   const { mutateAsync } = useProfileMutation() | ||||||
|  |  | ||||||
|  |   const { data, isFetching, refetch } = usePreferencesQuery() | ||||||
|  |  | ||||||
|  |   const messageRef = useRef<FlashMessage>(null) | ||||||
|  |  | ||||||
|  |   return ( | ||||||
|  |     <ScrollView> | ||||||
|  |       <MenuContainer> | ||||||
|  |         {data?.['posting:default:visibility'] !== 'direct' ? ( | ||||||
|  |           <MenuRow | ||||||
|  |             title={t('screenTabs:me.preferences.visibility.title')} | ||||||
|  |             content={ | ||||||
|  |               data?.['posting:default:visibility'] | ||||||
|  |                 ? t( | ||||||
|  |                     `screenTabs:me.preferences.visibility.options.${data['posting:default:visibility']}` | ||||||
|  |                   ) | ||||||
|  |                 : undefined | ||||||
|  |             } | ||||||
|  |             loading={isFetching} | ||||||
|  |             iconBack='ChevronRight' | ||||||
|  |             onPress={() => | ||||||
|  |               showActionSheetWithOptions( | ||||||
|  |                 { | ||||||
|  |                   title: t('screenTabs:me.preferences.visibility.title'), | ||||||
|  |                   options: [ | ||||||
|  |                     t('screenTabs:me.preferences.visibility.options.public'), | ||||||
|  |                     t('screenTabs:me.preferences.visibility.options.unlisted'), | ||||||
|  |                     t('screenTabs:me.preferences.visibility.options.private'), | ||||||
|  |                     t('common:buttons.cancel') | ||||||
|  |                   ], | ||||||
|  |                   cancelButtonIndex: 3, | ||||||
|  |                   ...androidActionSheetStyles(colors) | ||||||
|  |                 }, | ||||||
|  |                 async buttonIndex => { | ||||||
|  |                   switch (buttonIndex) { | ||||||
|  |                     case 0: | ||||||
|  |                     case 1: | ||||||
|  |                     case 2: | ||||||
|  |                       const indexVisibilityMapping = ['public', 'unlisted', 'private'] as [ | ||||||
|  |                         'public', | ||||||
|  |                         'unlisted', | ||||||
|  |                         'private' | ||||||
|  |                       ] | ||||||
|  |                       if ( | ||||||
|  |                         data?.['posting:default:visibility'] && | ||||||
|  |                         data['posting:default:visibility'] !== indexVisibilityMapping[buttonIndex] | ||||||
|  |                       ) { | ||||||
|  |                         mutateAsync({ | ||||||
|  |                           messageRef, | ||||||
|  |                           message: { | ||||||
|  |                             text: 'me.profile.root.visibility.title', | ||||||
|  |                             succeed: false, | ||||||
|  |                             failed: true | ||||||
|  |                           }, | ||||||
|  |                           type: 'source[privacy]', | ||||||
|  |                           data: indexVisibilityMapping[buttonIndex] | ||||||
|  |                         }).then(() => refetch()) | ||||||
|  |                       } | ||||||
|  |                       break | ||||||
|  |                   } | ||||||
|  |                 } | ||||||
|  |               ) | ||||||
|  |             } | ||||||
|  |           /> | ||||||
|  |         ) : null} | ||||||
|  |         <MenuRow | ||||||
|  |           title={t('screenTabs:me.preferences.sensitive.title')} | ||||||
|  |           switchValue={data?.['posting:default:sensitive']} | ||||||
|  |           switchOnValueChange={() => | ||||||
|  |             mutateAsync({ | ||||||
|  |               messageRef, | ||||||
|  |               message: { | ||||||
|  |                 text: 'me.profile.root.sensitive.title', | ||||||
|  |                 succeed: false, | ||||||
|  |                 failed: true | ||||||
|  |               }, | ||||||
|  |               type: 'source[sensitive]', | ||||||
|  |               data: | ||||||
|  |                 data?.['posting:default:sensitive'] === undefined | ||||||
|  |                   ? true | ||||||
|  |                   : !data['posting:default:sensitive'] | ||||||
|  |             }).then(() => refetch()) | ||||||
|  |           } | ||||||
|  |           loading={isFetching} | ||||||
|  |         /> | ||||||
|  |       </MenuContainer> | ||||||
|  |       <MenuContainer style={{ marginTop: StyleConstants.Spacing.L }}> | ||||||
|  |         <MenuRow | ||||||
|  |           iconBack='ExternalLink' | ||||||
|  |           title={t('screenTabs:me.preferences.web_only.title')} | ||||||
|  |           description={t('screenTabs:me.preferences.web_only.description')} | ||||||
|  |           onPress={async () => | ||||||
|  |             WebBrowser.openAuthSessionAsync( | ||||||
|  |               `https://${getAccountStorage.string('auth.domain')}/settings/preferences`, | ||||||
|  |               'tooot://tooot', | ||||||
|  |               { | ||||||
|  |                 ...(await browserPackage()), | ||||||
|  |                 dismissButtonStyle: 'done', | ||||||
|  |                 readerMode: false | ||||||
|  |               } | ||||||
|  |             ).then(() => refetch()) | ||||||
|  |           } | ||||||
|  |         /> | ||||||
|  |         <MenuRow | ||||||
|  |           title={t('screenTabs:me.preferences.media.title')} | ||||||
|  |           content={ | ||||||
|  |             data?.['reading:expand:media'] | ||||||
|  |               ? t(`screenTabs:me.preferences.media.options.${data['reading:expand:media']}`) | ||||||
|  |               : undefined | ||||||
|  |           } | ||||||
|  |           loading={isFetching} | ||||||
|  |         /> | ||||||
|  |         <MenuRow | ||||||
|  |           title={t('screenTabs:me.preferences.spoilers.title')} | ||||||
|  |           switchValue={data?.['reading:expand:spoilers'] || false} | ||||||
|  |           switchDisabled={true} | ||||||
|  |           loading={isFetching} | ||||||
|  |         /> | ||||||
|  |         {data?.['reading:autoplay:gifs'] !== undefined ? ( | ||||||
|  |           <MenuRow | ||||||
|  |             title={t('screenTabs:me.preferences.autoplay_gifs.title')} | ||||||
|  |             switchValue={data['reading:autoplay:gifs'] || false} | ||||||
|  |             switchDisabled={true} | ||||||
|  |             loading={isFetching} | ||||||
|  |           /> | ||||||
|  |         ) : null} | ||||||
|  |       </MenuContainer> | ||||||
|  |  | ||||||
|  |       <Message ref={messageRef} /> | ||||||
|  |     </ScrollView> | ||||||
|  |   ) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | export default TabMePreferences | ||||||
| @@ -1,11 +1,6 @@ | |||||||
| import { MenuContainer, MenuRow } from '@components/Menu' | import { MenuContainer, MenuRow } from '@components/Menu' | ||||||
| import { useActionSheet } from '@expo/react-native-action-sheet' |  | ||||||
| import { androidActionSheetStyles } from '@utils/helpers/androidActionSheetStyles' |  | ||||||
| import { TabMeProfileStackScreenProps } from '@utils/navigation/navigators' | import { TabMeProfileStackScreenProps } from '@utils/navigation/navigators' | ||||||
| import { queryClient } from '@utils/queryHooks' |  | ||||||
| import { QueryKeyPreferences } from '@utils/queryHooks/preferences' |  | ||||||
| import { useProfileMutation, useProfileQuery } from '@utils/queryHooks/profile' | import { useProfileMutation, useProfileQuery } from '@utils/queryHooks/profile' | ||||||
| import { useTheme } from '@utils/styles/ThemeManager' |  | ||||||
| import React, { RefObject } from 'react' | import React, { RefObject } from 'react' | ||||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||||
| import FlashMessage from 'react-native-flash-message' | import FlashMessage from 'react-native-flash-message' | ||||||
| @@ -17,19 +12,11 @@ const TabMeProfileRoot: React.FC< | |||||||
|     messageRef: RefObject<FlashMessage> |     messageRef: RefObject<FlashMessage> | ||||||
|   } |   } | ||||||
| > = ({ messageRef, navigation }) => { | > = ({ messageRef, navigation }) => { | ||||||
|   const { colors } = useTheme() |  | ||||||
|   const { t } = useTranslation(['common', 'screenTabs']) |   const { t } = useTranslation(['common', 'screenTabs']) | ||||||
|  |  | ||||||
|   const { showActionSheetWithOptions } = useActionSheet() |  | ||||||
|  |  | ||||||
|   const { data, isFetching } = useProfileQuery() |   const { data, isFetching } = useProfileQuery() | ||||||
|   const { mutateAsync } = useProfileMutation() |   const { mutateAsync } = useProfileMutation() | ||||||
|  |  | ||||||
|   const refetchPreferences = () => { |  | ||||||
|     const queryKeyPreferences: QueryKeyPreferences = ['Preferences'] |  | ||||||
|     queryClient.refetchQueries(queryKeyPreferences) |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <ScrollView> |     <ScrollView> | ||||||
|       <MenuContainer> |       <MenuContainer> | ||||||
| @@ -77,77 +64,6 @@ const TabMeProfileRoot: React.FC< | |||||||
|           }} |           }} | ||||||
|         /> |         /> | ||||||
|       </MenuContainer> |       </MenuContainer> | ||||||
|       <MenuContainer> |  | ||||||
|         {data?.source.privacy !== 'direct' ? ( |  | ||||||
|           <MenuRow |  | ||||||
|             title={t('screenTabs:me.profile.root.visibility.title')} |  | ||||||
|             content={ |  | ||||||
|               data?.source.privacy |  | ||||||
|                 ? t(`screenTabs:me.profile.root.visibility.options.${data.source.privacy}`) |  | ||||||
|                 : undefined |  | ||||||
|             } |  | ||||||
|             loading={isFetching} |  | ||||||
|             iconBack='ChevronRight' |  | ||||||
|             onPress={() => |  | ||||||
|               showActionSheetWithOptions( |  | ||||||
|                 { |  | ||||||
|                   title: t('screenTabs:me.profile.root.visibility.title'), |  | ||||||
|                   options: [ |  | ||||||
|                     t('screenTabs:me.profile.root.visibility.options.public'), |  | ||||||
|                     t('screenTabs:me.profile.root.visibility.options.unlisted'), |  | ||||||
|                     t('screenTabs:me.profile.root.visibility.options.private'), |  | ||||||
|                     t('common:buttons.cancel') |  | ||||||
|                   ], |  | ||||||
|                   cancelButtonIndex: 3, |  | ||||||
|                   ...androidActionSheetStyles(colors) |  | ||||||
|                 }, |  | ||||||
|                 async buttonIndex => { |  | ||||||
|                   switch (buttonIndex) { |  | ||||||
|                     case 0: |  | ||||||
|                     case 1: |  | ||||||
|                     case 2: |  | ||||||
|                       const indexVisibilityMapping = ['public', 'unlisted', 'private'] as [ |  | ||||||
|                         'public', |  | ||||||
|                         'unlisted', |  | ||||||
|                         'private' |  | ||||||
|                       ] |  | ||||||
|                       if (data?.source.privacy !== indexVisibilityMapping[buttonIndex]) { |  | ||||||
|                         mutateAsync({ |  | ||||||
|                           messageRef, |  | ||||||
|                           message: { |  | ||||||
|                             text: 'me.profile.root.visibility.title', |  | ||||||
|                             succeed: false, |  | ||||||
|                             failed: true |  | ||||||
|                           }, |  | ||||||
|                           type: 'source[privacy]', |  | ||||||
|                           data: indexVisibilityMapping[buttonIndex] |  | ||||||
|                         }).then(() => refetchPreferences()) |  | ||||||
|                       } |  | ||||||
|                       break |  | ||||||
|                   } |  | ||||||
|                 } |  | ||||||
|               ) |  | ||||||
|             } |  | ||||||
|           /> |  | ||||||
|         ) : null} |  | ||||||
|         <MenuRow |  | ||||||
|           title={t('screenTabs:me.profile.root.sensitive.title')} |  | ||||||
|           switchValue={data?.source.sensitive} |  | ||||||
|           switchOnValueChange={() => |  | ||||||
|             mutateAsync({ |  | ||||||
|               messageRef, |  | ||||||
|               message: { |  | ||||||
|                 text: 'me.profile.root.sensitive.title', |  | ||||||
|                 succeed: false, |  | ||||||
|                 failed: true |  | ||||||
|               }, |  | ||||||
|               type: 'source[sensitive]', |  | ||||||
|               data: data?.source.sensitive === undefined ? true : !data.source.sensitive |  | ||||||
|             }).then(() => refetchPreferences()) |  | ||||||
|           } |  | ||||||
|           loading={isFetching} |  | ||||||
|         /> |  | ||||||
|       </MenuContainer> |  | ||||||
|       <MenuContainer> |       <MenuContainer> | ||||||
|         <MenuRow |         <MenuRow | ||||||
|           title={t('screenTabs:me.profile.root.lock.title')} |           title={t('screenTabs:me.profile.root.lock.title')} | ||||||
|   | |||||||
| @@ -1,8 +1,5 @@ | |||||||
| import { MenuContainer, MenuRow } from '@components/Menu' | import { MenuContainer, MenuRow } from '@components/Menu' | ||||||
| import { useNavigation } from '@react-navigation/native' | import { useNavigation } from '@react-navigation/native' | ||||||
| import browserPackage from '@utils/helpers/browserPackage' |  | ||||||
| import { getAccountStorage, useGlobalStorage } from '@utils/storage/actions' |  | ||||||
| import * as WebBrowser from 'expo-web-browser' |  | ||||||
| import React from 'react' | import React from 'react' | ||||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||||
|  |  | ||||||
| @@ -10,8 +7,6 @@ const Settings: React.FC = () => { | |||||||
|   const { t } = useTranslation('screenTabs') |   const { t } = useTranslation('screenTabs') | ||||||
|   const navigation = useNavigation<any>() |   const navigation = useNavigation<any>() | ||||||
|  |  | ||||||
|   const [accountActive] = useGlobalStorage.string('account.active') |  | ||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <MenuContainer> |     <MenuContainer> | ||||||
|       <MenuRow |       <MenuRow | ||||||
| @@ -20,24 +15,6 @@ const Settings: React.FC = () => { | |||||||
|         title={t('me.stacks.settings.name')} |         title={t('me.stacks.settings.name')} | ||||||
|         onPress={() => navigation.navigate('Tab-Me-Settings')} |         onPress={() => navigation.navigate('Tab-Me-Settings')} | ||||||
|       /> |       /> | ||||||
|       {accountActive ? ( |  | ||||||
|         <MenuRow |  | ||||||
|           iconFront='Sliders' |  | ||||||
|           iconBack='ExternalLink' |  | ||||||
|           title={t('me.stacks.webSettings.name')} |  | ||||||
|           onPress={async () => |  | ||||||
|             WebBrowser.openAuthSessionAsync( |  | ||||||
|               `https://${getAccountStorage.string('auth.domain')}/settings/preferences`, |  | ||||||
|               'tooot://tooot', |  | ||||||
|               { |  | ||||||
|                 ...(await browserPackage()), |  | ||||||
|                 dismissButtonStyle: 'done', |  | ||||||
|                 readerMode: false |  | ||||||
|               } |  | ||||||
|             ) |  | ||||||
|           } |  | ||||||
|         /> |  | ||||||
|       ) : null} |  | ||||||
|     </MenuContainer> |     </MenuContainer> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -12,6 +12,7 @@ import TabMeList from './List' | |||||||
| import TabMeListAccounts from './List/Accounts' | import TabMeListAccounts from './List/Accounts' | ||||||
| import TabMeListEdit from './List/Edit' | import TabMeListEdit from './List/Edit' | ||||||
| import TabMeListList from './List/List' | import TabMeListList from './List/List' | ||||||
|  | import TabMePreferences from './Preferences' | ||||||
| import TabMeProfile from './Profile' | import TabMeProfile from './Profile' | ||||||
| import TabMePush from './Push' | import TabMePush from './Push' | ||||||
| import TabMeRoot from './Root' | import TabMeRoot from './Root' | ||||||
| @@ -100,13 +101,19 @@ const TabMe: React.FC = () => { | |||||||
|           headerLeft: () => <HeaderLeft onPress={() => navigation.pop(1)} /> |           headerLeft: () => <HeaderLeft onPress={() => navigation.pop(1)} /> | ||||||
|         })} |         })} | ||||||
|       /> |       /> | ||||||
|  |       <Stack.Screen | ||||||
|  |         name='Tab-Me-Preferences' | ||||||
|  |         component={TabMePreferences} | ||||||
|  |         options={({ navigation }: any) => ({ | ||||||
|  |           presentation: 'modal', | ||||||
|  |           title: t('me.stacks.preferences.name'), | ||||||
|  |           headerLeft: () => <HeaderLeft content='ChevronDown' onPress={() => navigation.pop(1)} /> | ||||||
|  |         })} | ||||||
|  |       /> | ||||||
|       <Stack.Screen |       <Stack.Screen | ||||||
|         name='Tab-Me-Profile' |         name='Tab-Me-Profile' | ||||||
|         component={TabMeProfile} |         component={TabMeProfile} | ||||||
|         options={{ |         options={{ headerShown: false, presentation: 'modal' }} | ||||||
|           headerShown: false, |  | ||||||
|           presentation: 'modal' |  | ||||||
|         }} |  | ||||||
|       /> |       /> | ||||||
|       <Stack.Screen |       <Stack.Screen | ||||||
|         name='Tab-Me-Push' |         name='Tab-Me-Push' | ||||||
|   | |||||||
| @@ -42,6 +42,14 @@ const AccountInformationActions: React.FC = () => { | |||||||
|           content={t('me.stacks.profile.name')} |           content={t('me.stacks.profile.name')} | ||||||
|           onPress={() => navigation.navigate('Tab-Me-Profile')} |           onPress={() => navigation.navigate('Tab-Me-Profile')} | ||||||
|         /> |         /> | ||||||
|  |         <Button | ||||||
|  |           round | ||||||
|  |           type='icon' | ||||||
|  |           disabled={account === undefined} | ||||||
|  |           content='Settings' | ||||||
|  |           style={{ marginLeft: StyleConstants.Spacing.S }} | ||||||
|  |           onPress={() => navigation.navigate('Tab-Me-Preferences')} | ||||||
|  |         /> | ||||||
|       </View> |       </View> | ||||||
|     ) |     ) | ||||||
|   } |   } | ||||||
| @@ -61,7 +69,7 @@ const AccountInformationActions: React.FC = () => { | |||||||
|                 round |                 round | ||||||
|                 type='icon' |                 type='icon' | ||||||
|                 content='AtSign' |                 content='AtSign' | ||||||
|                 style={{ marginRight: StyleConstants.Spacing.S }} |                 style={{ flex: 1, marginRight: StyleConstants.Spacing.S }} | ||||||
|                 onPress={() => {}} |                 onPress={() => {}} | ||||||
|               /> |               /> | ||||||
|             </DropdownMenu.Trigger> |             </DropdownMenu.Trigger> | ||||||
| @@ -119,7 +127,7 @@ const styles = StyleSheet.create({ | |||||||
|   base: { |   base: { | ||||||
|     alignSelf: 'flex-end', |     alignSelf: 'flex-end', | ||||||
|     flexDirection: 'row', |     flexDirection: 'row', | ||||||
|     alignItems: 'center' |     alignItems: 'stretch' | ||||||
|   } |   } | ||||||
| }) | }) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -157,6 +157,7 @@ export type TabMeStackParamList = { | |||||||
|         key: string // To update title after successful mutation |         key: string // To update title after successful mutation | ||||||
|       } |       } | ||||||
|   'Tab-Me-List-List': undefined |   'Tab-Me-List-List': undefined | ||||||
|  |   'Tab-Me-Preferences': undefined | ||||||
|   'Tab-Me-Profile': undefined |   'Tab-Me-Profile': undefined | ||||||
|   'Tab-Me-Push': undefined |   'Tab-Me-Push': undefined | ||||||
|   'Tab-Me-Settings': undefined |   'Tab-Me-Settings': undefined | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ const usePreferencesQuery = (params?: { | |||||||
|     ...params?.options, |     ...params?.options, | ||||||
|     staleTime: Infinity, |     staleTime: Infinity, | ||||||
|     cacheTime: Infinity, |     cacheTime: Infinity, | ||||||
|     initialData: getAccountStorage.object('preferences'), |     placeholderData: getAccountStorage.object('preferences'), | ||||||
|     onSuccess: data => setAccountStorage([{ key: 'preferences', value: data }]) |     onSuccess: data => setAccountStorage([{ key: 'preferences', value: data }]) | ||||||
|   }) |   }) | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user