mirror of
				https://github.com/tooot-app/app
				synced 2025-06-05 22:19:13 +02:00 
			
		
		
		
	Added font size settings
This commit is contained in:
		
							
								
								
									
										1
									
								
								src/@types/react-navigation.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								src/@types/react-navigation.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -118,6 +118,7 @@ declare namespace Nav { | |||||||
|       title: Mastodon.List['title'] |       title: Mastodon.List['title'] | ||||||
|     } |     } | ||||||
|     'Tab-Me-Settings': undefined |     'Tab-Me-Settings': undefined | ||||||
|  |     'Tab-Me-Settings-Fontsize': undefined | ||||||
|     'Tab-Me-Settings-Push': undefined |     'Tab-Me-Settings-Push': undefined | ||||||
|     'Tab-Me-Switch': undefined |     'Tab-Me-Switch': undefined | ||||||
|   } & TabSharedStackParamList |   } & TabSharedStackParamList | ||||||
|   | |||||||
| @@ -1,8 +1,6 @@ | |||||||
| import { ParseHTML } from '@components/Parse' |  | ||||||
| import { StyleConstants } from '@utils/styles/constants' | 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 { StyleSheet, Text, View, ViewStyle } from 'react-native' | import { StyleSheet, Text, View, ViewStyle } from 'react-native' | ||||||
| import { PlaceholderLine } from 'rn-placeholder' | import { PlaceholderLine } from 'rn-placeholder' | ||||||
|  |  | ||||||
| @@ -15,19 +13,15 @@ export interface Props { | |||||||
|  |  | ||||||
| const InstanceInfo = React.memo( | const InstanceInfo = React.memo( | ||||||
|   ({ style, header, content, potentialWidth }: Props) => { |   ({ style, header, content, potentialWidth }: Props) => { | ||||||
|     const { t } = useTranslation('componentInstance') |  | ||||||
|     const { theme } = useTheme() |     const { theme } = useTheme() | ||||||
|  |  | ||||||
|     return ( |     return ( | ||||||
|       <View style={[styles.base, style]}> |       <View style={[styles.base, style]}> | ||||||
|         <Text style={[styles.header, { color: theme.primary }]}>{header}</Text> |         <Text style={[styles.header, { color: theme.primary }]}>{header}</Text> | ||||||
|         {content ? ( |         {content ? ( | ||||||
|           <ParseHTML |           <Text style={[styles.content, { color: theme.primary }]}> | ||||||
|             content={content} |             {content} | ||||||
|             size={'M'} |           </Text> | ||||||
|             numberOfLines={5} |  | ||||||
|             expandHint={t('server.information.description.expandHint')} |  | ||||||
|           /> |  | ||||||
|         ) : ( |         ) : ( | ||||||
|           <PlaceholderLine |           <PlaceholderLine | ||||||
|             width={ |             width={ | ||||||
| @@ -58,6 +52,9 @@ const styles = StyleSheet.create({ | |||||||
|     ...StyleConstants.FontStyle.S, |     ...StyleConstants.FontStyle.S, | ||||||
|     fontWeight: StyleConstants.Font.Weight.Bold, |     fontWeight: StyleConstants.Font.Weight.Bold, | ||||||
|     marginBottom: StyleConstants.Spacing.XS |     marginBottom: StyleConstants.Spacing.XS | ||||||
|  |   }, | ||||||
|  |   content: { | ||||||
|  |     ...StyleConstants.FontStyle.M | ||||||
|   } |   } | ||||||
| }) | }) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,8 +1,10 @@ | |||||||
| import { StyleConstants } from '@utils/styles/constants' | import { getSettingsFontsize } from '@utils/slices/settingsSlice' | ||||||
|  | import { adaptiveScale, StyleConstants } from '@utils/styles/constants' | ||||||
| import { useTheme } from '@utils/styles/ThemeManager' | import { useTheme } from '@utils/styles/ThemeManager' | ||||||
| import React, { useMemo } from 'react' | import React, { useMemo } from 'react' | ||||||
| import { StyleSheet, Text } from 'react-native' | import { StyleSheet, Text } from 'react-native' | ||||||
| import FastImage from 'react-native-fast-image' | import FastImage from 'react-native-fast-image' | ||||||
|  | import { useSelector } from 'react-redux' | ||||||
|  |  | ||||||
| const regexEmoji = new RegExp(/(:[A-Za-z0-9_]+:)/) | const regexEmoji = new RegExp(/(:[A-Za-z0-9_]+:)/) | ||||||
|  |  | ||||||
| @@ -10,26 +12,44 @@ export interface Props { | |||||||
|   content: string |   content: string | ||||||
|   emojis?: Mastodon.Emoji[] |   emojis?: Mastodon.Emoji[] | ||||||
|   size?: 'S' | 'M' | 'L' |   size?: 'S' | 'M' | 'L' | ||||||
|  |   adaptiveSize?: boolean | ||||||
|   fontBold?: boolean |   fontBold?: boolean | ||||||
| } | } | ||||||
|  |  | ||||||
| const ParseEmojis = React.memo( | const ParseEmojis = React.memo( | ||||||
|   ({ content, emojis, size = 'M', fontBold = false }: Props) => { |   ({ | ||||||
|  |     content, | ||||||
|  |     emojis, | ||||||
|  |     size = 'M', | ||||||
|  |     adaptiveSize = false, | ||||||
|  |     fontBold = false | ||||||
|  |   }: Props) => { | ||||||
|  |     const adaptiveFontsize = useSelector(getSettingsFontsize) | ||||||
|  |     const adaptedFontsize = adaptiveScale( | ||||||
|  |       StyleConstants.Font.Size[size], | ||||||
|  |       adaptiveSize ? adaptiveFontsize : 0 | ||||||
|  |     ) | ||||||
|  |     const adaptedLineheight = adaptiveScale( | ||||||
|  |       StyleConstants.Font.LineHeight[size], | ||||||
|  |       adaptiveSize ? adaptiveFontsize : 0 | ||||||
|  |     ) | ||||||
|  |  | ||||||
|     const { mode, theme } = useTheme() |     const { mode, theme } = useTheme() | ||||||
|     const styles = useMemo(() => { |     const styles = useMemo(() => { | ||||||
|       return StyleSheet.create({ |       return StyleSheet.create({ | ||||||
|         text: { |         text: { | ||||||
|           color: theme.primary, |           color: theme.primary, | ||||||
|           ...StyleConstants.FontStyle[size], |           fontSize: adaptedFontsize, | ||||||
|  |           lineHeight: adaptedLineheight, | ||||||
|           ...(fontBold && { fontWeight: StyleConstants.Font.Weight.Bold }) |           ...(fontBold && { fontWeight: StyleConstants.Font.Weight.Bold }) | ||||||
|         }, |         }, | ||||||
|         image: { |         image: { | ||||||
|           width: StyleConstants.Font.Size[size], |           width: adaptedFontsize, | ||||||
|           height: StyleConstants.Font.Size[size], |           height: adaptedFontsize, | ||||||
|           transform: [{ translateY: size === 'L' ? -3 : -1 }] |           transform: [{ translateY: -2 }] | ||||||
|         } |         } | ||||||
|       }) |       }) | ||||||
|     }, [mode]) |     }, [mode, adaptiveFontsize]) | ||||||
|  |  | ||||||
|     return ( |     return ( | ||||||
|       <Text style={styles.text}> |       <Text style={styles.text}> | ||||||
| @@ -50,6 +70,7 @@ const ParseEmojis = React.memo( | |||||||
|                     {/* When emoji starts a paragraph, lineHeight will break */} |                     {/* When emoji starts a paragraph, lineHeight will break */} | ||||||
|                     {i === 0 ? <Text> </Text> : null} |                     {i === 0 ? <Text> </Text> : null} | ||||||
|                     <FastImage |                     <FastImage | ||||||
|  |                       key={adaptiveFontsize} | ||||||
|                       source={{ uri: emojis[emojiIndex].url }} |                       source={{ uri: emojis[emojiIndex].url }} | ||||||
|                       style={styles.image} |                       style={styles.image} | ||||||
|                     /> |                     /> | ||||||
|   | |||||||
| @@ -4,7 +4,8 @@ import openLink from '@components/openLink' | |||||||
| import ParseEmojis from '@components/Parse/Emojis' | import ParseEmojis from '@components/Parse/Emojis' | ||||||
| import { useNavigation, useRoute } from '@react-navigation/native' | import { useNavigation, useRoute } from '@react-navigation/native' | ||||||
| import { StackNavigationProp } from '@react-navigation/stack' | import { StackNavigationProp } from '@react-navigation/stack' | ||||||
| import { StyleConstants } from '@utils/styles/constants' | import { getSettingsFontsize } from '@utils/slices/settingsSlice' | ||||||
|  | import { adaptiveScale, StyleConstants } from '@utils/styles/constants' | ||||||
| import layoutAnimation from '@utils/styles/layoutAnimation' | import layoutAnimation from '@utils/styles/layoutAnimation' | ||||||
| import { useTheme } from '@utils/styles/ThemeManager' | import { useTheme } from '@utils/styles/ThemeManager' | ||||||
| import { LinearGradient } from 'expo-linear-gradient' | import { LinearGradient } from 'expo-linear-gradient' | ||||||
| @@ -12,6 +13,7 @@ import React, { useCallback, useState } from 'react' | |||||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||||
| import { Platform, Pressable, Text, View } from 'react-native' | import { Platform, Pressable, Text, View } from 'react-native' | ||||||
| import HTMLView from 'react-native-htmlview' | import HTMLView from 'react-native-htmlview' | ||||||
|  | import { useSelector } from 'react-redux' | ||||||
|  |  | ||||||
| // Prevent going to the same hashtag multiple times | // Prevent going to the same hashtag multiple times | ||||||
| const renderNode = ({ | const renderNode = ({ | ||||||
| @@ -19,7 +21,8 @@ const renderNode = ({ | |||||||
|   theme, |   theme, | ||||||
|   node, |   node, | ||||||
|   index, |   index, | ||||||
|   size, |   adaptedFontsize, | ||||||
|  |   adaptedLineheight, | ||||||
|   navigation, |   navigation, | ||||||
|   mentions, |   mentions, | ||||||
|   tags, |   tags, | ||||||
| @@ -30,7 +33,8 @@ const renderNode = ({ | |||||||
|   theme: any |   theme: any | ||||||
|   node: any |   node: any | ||||||
|   index: number |   index: number | ||||||
|   size: 'S' | 'M' | 'L' |   adaptedFontsize: number | ||||||
|  |   adaptedLineheight: number | ||||||
|   navigation: StackNavigationProp<Nav.TabLocalStackParamList> |   navigation: StackNavigationProp<Nav.TabLocalStackParamList> | ||||||
|   mentions?: Mastodon.Mention[] |   mentions?: Mastodon.Mention[] | ||||||
|   tags?: Mastodon.Tag[] |   tags?: Mastodon.Tag[] | ||||||
| @@ -52,7 +56,8 @@ const renderNode = ({ | |||||||
|               key={index} |               key={index} | ||||||
|               style={{ |               style={{ | ||||||
|                 color: theme.blue, |                 color: theme.blue, | ||||||
|                 ...StyleConstants.FontStyle[size] |                 fontSize: adaptedFontsize, | ||||||
|  |                 lineHeight: adaptedLineheight | ||||||
|               }} |               }} | ||||||
|               onPress={() => { |               onPress={() => { | ||||||
|                 analytics('status_hashtag_press') |                 analytics('status_hashtag_press') | ||||||
| @@ -79,7 +84,8 @@ const renderNode = ({ | |||||||
|               key={index} |               key={index} | ||||||
|               style={{ |               style={{ | ||||||
|                 color: accountIndex !== -1 ? theme.blue : undefined, |                 color: accountIndex !== -1 ? theme.blue : undefined, | ||||||
|                 ...StyleConstants.FontStyle[size] |                 fontSize: adaptedFontsize, | ||||||
|  |                 lineHeight: adaptedLineheight | ||||||
|               }} |               }} | ||||||
|               onPress={() => { |               onPress={() => { | ||||||
|                 analytics('status_mention_press') |                 analytics('status_mention_press') | ||||||
| @@ -108,8 +114,9 @@ const renderNode = ({ | |||||||
|             key={index} |             key={index} | ||||||
|             style={{ |             style={{ | ||||||
|               color: theme.blue, |               color: theme.blue, | ||||||
|               ...StyleConstants.FontStyle[size], |               alignItems: 'center', | ||||||
|               alignItems: 'center' |               fontSize: adaptedFontsize, | ||||||
|  |               lineHeight: adaptedLineheight | ||||||
|             }} |             }} | ||||||
|             onPress={async () => { |             onPress={async () => { | ||||||
|               analytics('status_link_press') |               analytics('status_link_press') | ||||||
| @@ -125,9 +132,9 @@ const renderNode = ({ | |||||||
|               <Icon |               <Icon | ||||||
|                 color={theme.blue} |                 color={theme.blue} | ||||||
|                 name='ExternalLink' |                 name='ExternalLink' | ||||||
|                 size={StyleConstants.Font.Size[size]} |                 size={adaptedFontsize} | ||||||
|                 style={{ |                 style={{ | ||||||
|                   transform: [{ translateY: size === 'L' ? -3 : -1 }] |                   transform: [{ translateY: -2 }] | ||||||
|                 }} |                 }} | ||||||
|               /> |               /> | ||||||
|             ) : null} |             ) : null} | ||||||
| @@ -146,6 +153,7 @@ const renderNode = ({ | |||||||
| export interface Props { | export interface Props { | ||||||
|   content: string |   content: string | ||||||
|   size?: 'S' | 'M' | 'L' |   size?: 'S' | 'M' | 'L' | ||||||
|  |   adaptiveSize?: boolean | ||||||
|   emojis?: Mastodon.Emoji[] |   emojis?: Mastodon.Emoji[] | ||||||
|   mentions?: Mastodon.Mention[] |   mentions?: Mastodon.Mention[] | ||||||
|   tags?: Mastodon.Tag[] |   tags?: Mastodon.Tag[] | ||||||
| @@ -158,6 +166,7 @@ export interface Props { | |||||||
| const ParseHTML: React.FC<Props> = ({ | const ParseHTML: React.FC<Props> = ({ | ||||||
|   content, |   content, | ||||||
|   size = 'M', |   size = 'M', | ||||||
|  |   adaptiveSize = false, | ||||||
|   emojis, |   emojis, | ||||||
|   mentions, |   mentions, | ||||||
|   tags, |   tags, | ||||||
| @@ -166,6 +175,16 @@ const ParseHTML: React.FC<Props> = ({ | |||||||
|   expandHint, |   expandHint, | ||||||
|   disableDetails = false |   disableDetails = false | ||||||
| }) => { | }) => { | ||||||
|  |   const adaptiveFontsize = useSelector(getSettingsFontsize) | ||||||
|  |   const adaptedFontsize = adaptiveScale( | ||||||
|  |     StyleConstants.Font.Size[size], | ||||||
|  |     adaptiveSize ? adaptiveFontsize : 0 | ||||||
|  |   ) | ||||||
|  |   const adaptedLineheight = adaptiveScale( | ||||||
|  |     StyleConstants.Font.LineHeight[size], | ||||||
|  |     adaptiveSize ? adaptiveFontsize : 0 | ||||||
|  |   ) | ||||||
|  |  | ||||||
|   const navigation = useNavigation< |   const navigation = useNavigation< | ||||||
|     StackNavigationProp<Nav.TabLocalStackParamList> |     StackNavigationProp<Nav.TabLocalStackParamList> | ||||||
|   >() |   >() | ||||||
| @@ -183,7 +202,8 @@ const ParseHTML: React.FC<Props> = ({ | |||||||
|         theme, |         theme, | ||||||
|         node, |         node, | ||||||
|         index, |         index, | ||||||
|         size, |         adaptedFontsize, | ||||||
|  |         adaptedLineheight, | ||||||
|         navigation, |         navigation, | ||||||
|         mentions, |         mentions, | ||||||
|         tags, |         tags, | ||||||
| @@ -199,6 +219,7 @@ const ParseHTML: React.FC<Props> = ({ | |||||||
|           content={children.toString()} |           content={children.toString()} | ||||||
|           emojis={emojis} |           emojis={emojis} | ||||||
|           size={size} |           size={size} | ||||||
|  |           adaptiveSize={adaptiveSize} | ||||||
|         /> |         /> | ||||||
|       ) |       ) | ||||||
|     } else { |     } else { | ||||||
| @@ -208,7 +229,6 @@ const ParseHTML: React.FC<Props> = ({ | |||||||
|   const rootComponent = useCallback( |   const rootComponent = useCallback( | ||||||
|     ({ children }) => { |     ({ children }) => { | ||||||
|       const { t } = useTranslation('componentParse') |       const { t } = useTranslation('componentParse') | ||||||
|       const lineHeight = StyleConstants.Font.LineHeight[size] |  | ||||||
|  |  | ||||||
|       const [expandAllow, setExpandAllow] = useState(false) |       const [expandAllow, setExpandAllow] = useState(false) | ||||||
|       const [expanded, setExpanded] = useState(false) |       const [expanded, setExpanded] = useState(false) | ||||||
| @@ -234,10 +254,6 @@ const ParseHTML: React.FC<Props> = ({ | |||||||
|             children={children} |             children={children} | ||||||
|             onTextLayout={onTextLayout} |             onTextLayout={onTextLayout} | ||||||
|             numberOfLines={expanded ? 999 : numberOfLines + 1} |             numberOfLines={expanded ? 999 : numberOfLines + 1} | ||||||
|             style={{ |  | ||||||
|               ...StyleConstants.FontStyle[size], |  | ||||||
|               color: theme.primary |  | ||||||
|             }} |  | ||||||
|           /> |           /> | ||||||
|           {expandAllow ? ( |           {expandAllow ? ( | ||||||
|             <Pressable |             <Pressable | ||||||
| @@ -249,7 +265,7 @@ const ParseHTML: React.FC<Props> = ({ | |||||||
|               style={{ |               style={{ | ||||||
|                 marginTop: expanded |                 marginTop: expanded | ||||||
|                   ? 0 |                   ? 0 | ||||||
|                   : -lineHeight * (numberOfLines === 0 ? 1 : 2) |                   : -adaptedLineheight * (numberOfLines === 0 ? 1 : 2) | ||||||
|               }} |               }} | ||||||
|             > |             > | ||||||
|               <LinearGradient |               <LinearGradient | ||||||
| @@ -257,10 +273,7 @@ const ParseHTML: React.FC<Props> = ({ | |||||||
|                   theme.backgroundGradientStart, |                   theme.backgroundGradientStart, | ||||||
|                   theme.backgroundGradientEnd |                   theme.backgroundGradientEnd | ||||||
|                 ]} |                 ]} | ||||||
|                 locations={[ |                 locations={[0, adaptedLineheight / (adaptedFontsize * 5)]} | ||||||
|                   0, |  | ||||||
|                   lineHeight / (StyleConstants.Font.Size[size] * 5) |  | ||||||
|                 ]} |  | ||||||
|                 style={{ |                 style={{ | ||||||
|                   paddingTop: StyleConstants.Font.Size.S * 2, |                   paddingTop: StyleConstants.Font.Size.S * 2, | ||||||
|                   paddingBottom: StyleConstants.Font.Size.S |                   paddingBottom: StyleConstants.Font.Size.S | ||||||
|   | |||||||
| @@ -28,6 +28,7 @@ const TimelineContent = React.memo( | |||||||
|               <ParseHTML |               <ParseHTML | ||||||
|                 content={status.spoiler_text} |                 content={status.spoiler_text} | ||||||
|                 size={highlighted ? 'L' : 'M'} |                 size={highlighted ? 'L' : 'M'} | ||||||
|  |                 adaptiveSize | ||||||
|                 emojis={status.emojis} |                 emojis={status.emojis} | ||||||
|                 mentions={status.mentions} |                 mentions={status.mentions} | ||||||
|                 tags={status.tags} |                 tags={status.tags} | ||||||
| @@ -38,6 +39,7 @@ const TimelineContent = React.memo( | |||||||
|             <ParseHTML |             <ParseHTML | ||||||
|               content={status.content} |               content={status.content} | ||||||
|               size={highlighted ? 'L' : 'M'} |               size={highlighted ? 'L' : 'M'} | ||||||
|  |               adaptiveSize | ||||||
|               emojis={status.emojis} |               emojis={status.emojis} | ||||||
|               mentions={status.mentions} |               mentions={status.mentions} | ||||||
|               tags={status.tags} |               tags={status.tags} | ||||||
| @@ -50,6 +52,7 @@ const TimelineContent = React.memo( | |||||||
|           <ParseHTML |           <ParseHTML | ||||||
|             content={status.content} |             content={status.content} | ||||||
|             size={highlighted ? 'L' : 'M'} |             size={highlighted ? 'L' : 'M'} | ||||||
|  |             adaptiveSize | ||||||
|             emojis={status.emojis} |             emojis={status.emojis} | ||||||
|             mentions={status.mentions} |             mentions={status.mentions} | ||||||
|             tags={status.tags} |             tags={status.tags} | ||||||
|   | |||||||
| @@ -14,6 +14,7 @@ export default { | |||||||
|   meLists: require('./screens/meLists').default, |   meLists: require('./screens/meLists').default, | ||||||
|   meListsList: require('./screens/meListsList').default, |   meListsList: require('./screens/meListsList').default, | ||||||
|   meSettings: require('./screens/meSettings').default, |   meSettings: require('./screens/meSettings').default, | ||||||
|  |   meSettingsFontsize: require('./screens/meSettingsFontsize').default, | ||||||
|   meSettingsPush: require('./screens/meSettingsPush').default, |   meSettingsPush: require('./screens/meSettingsPush').default, | ||||||
|   meSwitch: require('./screens/meSwitch').default, |   meSwitch: require('./screens/meSwitch').default, | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,6 +8,16 @@ export default { | |||||||
|         disabled: 'Disabled' |         disabled: 'Disabled' | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     fontsize: { | ||||||
|  |       heading: '$t(meSettingsFontsize:heading)', | ||||||
|  |       content: { | ||||||
|  |         S: '$t(meSettingsFontsize:content.sizes.S)', | ||||||
|  |         M: '$t(meSettingsFontsize:content.sizes.M)', | ||||||
|  |         L: '$t(meSettingsFontsize:content.sizes.L)', | ||||||
|  |         XL: '$t(meSettingsFontsize:content.sizes.XL)', | ||||||
|  |         XXL: '$t(meSettingsFontsize:content.sizes.XXL)' | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     language: { |     language: { | ||||||
|       heading: 'Language', |       heading: 'Language', | ||||||
|       options: { |       options: { | ||||||
| @@ -50,6 +60,6 @@ export default { | |||||||
|       heading: 'Help us improve', |       heading: 'Help us improve', | ||||||
|       description: 'Collecting only non-user relative usage' |       description: 'Collecting only non-user relative usage' | ||||||
|     }, |     }, | ||||||
|     version: 'Version v{{version}}  ({{releaseChannel}})' |     version: 'Version v{{version}}' | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								src/i18n/en/screens/meSettingsFontsize.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/i18n/en/screens/meSettingsFontsize.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | export default { | ||||||
|  |   heading: 'Toot font size', | ||||||
|  |   content: { | ||||||
|  |     showcase: 'Example toot', | ||||||
|  |     availableSizes: 'Available sizes', | ||||||
|  |     sizes: { S: 'S', M: 'M - Default', L: 'L', XL: 'XL', XXL: 'XXL' } | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -14,6 +14,7 @@ export default { | |||||||
|   meLists: require('./screens/meLists').default, |   meLists: require('./screens/meLists').default, | ||||||
|   meListsList: require('./screens/meListsList').default, |   meListsList: require('./screens/meListsList').default, | ||||||
|   meSettings: require('./screens/meSettings').default, |   meSettings: require('./screens/meSettings').default, | ||||||
|  |   meSettingsFontsize: require('./screens/meSettingsFontsize').default, | ||||||
|   meSettingsPush: require('./screens/meSettingsPush').default, |   meSettingsPush: require('./screens/meSettingsPush').default, | ||||||
|   meSwitch: require('./screens/meSwitch').default, |   meSwitch: require('./screens/meSwitch').default, | ||||||
|  |  | ||||||
|   | |||||||
| @@ -8,6 +8,16 @@ export default { | |||||||
|         disabled: '已关闭' |         disabled: '已关闭' | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     fontsize: { | ||||||
|  |       heading: '$t(meSettingsFontsize:heading)', | ||||||
|  |       content: { | ||||||
|  |         S: '$t(meSettingsFontsize:content.sizes.S)', | ||||||
|  |         M: '$t(meSettingsFontsize:content.sizes.M)', | ||||||
|  |         L: '$t(meSettingsFontsize:content.sizes.L)', | ||||||
|  |         XL: '$t(meSettingsFontsize:content.sizes.XL)', | ||||||
|  |         XXL: '$t(meSettingsFontsize:content.sizes.XXL)' | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     language: { |     language: { | ||||||
|       heading: '切换语言', |       heading: '切换语言', | ||||||
|       options: { |       options: { | ||||||
| @@ -50,6 +60,6 @@ export default { | |||||||
|       heading: '帮助我们改进', |       heading: '帮助我们改进', | ||||||
|       description: '收集不与用户相关联的使用信息' |       description: '收集不与用户相关联的使用信息' | ||||||
|     }, |     }, | ||||||
|     version: '版本 v{{version}} ({{releaseChannel}})' |     version: '版本 v{{version}}' | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								src/i18n/zh-Hans/screens/meSettingsFontsize.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/i18n/zh-Hans/screens/meSettingsFontsize.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | |||||||
|  | export default { | ||||||
|  |   heading: '嘟文字号', | ||||||
|  |   content: { | ||||||
|  |     showcase: '嘟文示例', | ||||||
|  |     availableSizes: '可选字号', | ||||||
|  |     sizes: { S: '小号', M: '默认', L: '大号', XL: '特大号', XXL: '超大号' } | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -12,6 +12,7 @@ import React from 'react' | |||||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||||
| import { Platform } from 'react-native' | import { Platform } from 'react-native' | ||||||
| import { createNativeStackNavigator } from 'react-native-screens/native-stack' | import { createNativeStackNavigator } from 'react-native-screens/native-stack' | ||||||
|  | import ScreenMeSettingsFontsize from './Me/Fontsize' | ||||||
| import ScreenMeSettingsPush from './Me/Push' | import ScreenMeSettingsPush from './Me/Push' | ||||||
|  |  | ||||||
| const Stack = createNativeStackNavigator<Nav.TabMeStackParamList>() | const Stack = createNativeStackNavigator<Nav.TabMeStackParamList>() | ||||||
| @@ -115,6 +116,19 @@ const TabMe = React.memo( | |||||||
|             headerLeft: () => <HeaderLeft onPress={() => navigation.pop(1)} /> |             headerLeft: () => <HeaderLeft onPress={() => navigation.pop(1)} /> | ||||||
|           })} |           })} | ||||||
|         /> |         /> | ||||||
|  |         <Stack.Screen | ||||||
|  |           name='Tab-Me-Settings-Fontsize' | ||||||
|  |           component={ScreenMeSettingsFontsize} | ||||||
|  |           options={({ navigation }: any) => ({ | ||||||
|  |             headerTitle: t('meSettingsFontsize:heading'), | ||||||
|  |             ...(Platform.OS === 'android' && { | ||||||
|  |               headerCenter: () => ( | ||||||
|  |                 <HeaderCenter content={t('meSettingsFontsize:heading')} /> | ||||||
|  |               ) | ||||||
|  |             }), | ||||||
|  |             headerLeft: () => <HeaderLeft onPress={() => navigation.pop(1)} /> | ||||||
|  |           })} | ||||||
|  |         /> | ||||||
|         <Stack.Screen |         <Stack.Screen | ||||||
|           name='Tab-Me-Settings-Push' |           name='Tab-Me-Settings-Push' | ||||||
|           component={ScreenMeSettingsPush} |           component={ScreenMeSettingsPush} | ||||||
|   | |||||||
							
								
								
									
										184
									
								
								src/screens/Tabs/Me/Fontsize.tsx
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										184
									
								
								src/screens/Tabs/Me/Fontsize.tsx
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,184 @@ | |||||||
|  | import Button from '@components/Button' | ||||||
|  | import haptics from '@components/haptics' | ||||||
|  | import ComponentSeparator from '@components/Separator' | ||||||
|  | import TimelineDefault from '@components/Timeline/Default' | ||||||
|  | import { StackScreenProps } from '@react-navigation/stack' | ||||||
|  | import { | ||||||
|  |   changeFontsize, | ||||||
|  |   getSettingsFontsize, | ||||||
|  |   SettingsState | ||||||
|  | } from '@utils/slices/settingsSlice' | ||||||
|  | import { adaptiveScale, StyleConstants } from '@utils/styles/constants' | ||||||
|  | import { useTheme } from '@utils/styles/ThemeManager' | ||||||
|  | import React, { useMemo } from 'react' | ||||||
|  | import { useTranslation } from 'react-i18next' | ||||||
|  | import { StyleSheet, Text, View } from 'react-native' | ||||||
|  | import { ScrollView } from 'react-native-gesture-handler' | ||||||
|  | import { useDispatch, useSelector } from 'react-redux' | ||||||
|  |  | ||||||
|  | export const mapFontsizeToName = (size: SettingsState['fontsize']) => { | ||||||
|  |   switch (size) { | ||||||
|  |     case -1: | ||||||
|  |       return 'S' | ||||||
|  |     case 0: | ||||||
|  |       return 'M' | ||||||
|  |     case 1: | ||||||
|  |       return 'L' | ||||||
|  |     case 2: | ||||||
|  |       return 'XL' | ||||||
|  |     case 3: | ||||||
|  |       return 'XXL' | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const ScreenMeSettingsFontsize: React.FC<StackScreenProps< | ||||||
|  |   Nav.TabMeStackParamList, | ||||||
|  |   'Tab-Me-Settings-Fontsize' | ||||||
|  | >> = () => { | ||||||
|  |   const { mode, theme } = useTheme() | ||||||
|  |   const { t } = useTranslation('meSettingsFontsize') | ||||||
|  |   const initialSize = useSelector(getSettingsFontsize) | ||||||
|  |   const dispatch = useDispatch() | ||||||
|  |  | ||||||
|  |   const item = { | ||||||
|  |     id: 'demo', | ||||||
|  |     uri: 'https://tooot.app', | ||||||
|  |     created_at: new Date(), | ||||||
|  |     sensitive: false, | ||||||
|  |     visibility: 'public', | ||||||
|  |     replies_count: 0, | ||||||
|  |     reblogs_count: 0, | ||||||
|  |     favourites_count: 0, | ||||||
|  |     favourited: true, | ||||||
|  |     reblogged: false, | ||||||
|  |     muted: false, | ||||||
|  |     bookmarked: false, | ||||||
|  |     content: | ||||||
|  |       '<p>- tooot supports multiple accounts<br />- tooot supports browsing external instance<br />- tooot aims to support multiple languages</p>', | ||||||
|  |     reblog: null, | ||||||
|  |     application: { | ||||||
|  |       name: 'tooot', | ||||||
|  |       website: 'https://tooot.app' | ||||||
|  |     }, | ||||||
|  |     account: { | ||||||
|  |       id: 'demo', | ||||||
|  |       url: 'https://tooot.app', | ||||||
|  |       username: 'tooot📱', | ||||||
|  |       acct: 'tooot@xmflsct.com', | ||||||
|  |       display_name: 'tooot📱', | ||||||
|  |       avatar_static: 'https://avatars.githubusercontent.com/u/77554750?s=100' | ||||||
|  |     }, | ||||||
|  |     media_attachments: [], | ||||||
|  |     mentions: [] | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   const sizesDemo = useMemo(() => { | ||||||
|  |     return ( | ||||||
|  |       <> | ||||||
|  |         {([-1, 0, 1, 2, 3] as [-1, 0, 1, 2, 3]).map(size => ( | ||||||
|  |           <Text | ||||||
|  |             style={[ | ||||||
|  |               styles.size, | ||||||
|  |               { | ||||||
|  |                 fontSize: adaptiveScale(StyleConstants.Font.Size.M, size), | ||||||
|  |                 lineHeight: adaptiveScale( | ||||||
|  |                   StyleConstants.Font.LineHeight.M, | ||||||
|  |                   size | ||||||
|  |                 ), | ||||||
|  |                 fontWeight: | ||||||
|  |                   initialSize === size | ||||||
|  |                     ? StyleConstants.Font.Weight.Bold | ||||||
|  |                     : undefined, | ||||||
|  |                 color: initialSize === size ? theme.primary : theme.secondary, | ||||||
|  |                 borderWidth: StyleSheet.hairlineWidth, | ||||||
|  |                 borderColor: theme.border | ||||||
|  |               } | ||||||
|  |             ]} | ||||||
|  |           > | ||||||
|  |             {t(`content.sizes.${mapFontsizeToName(size)}`)} | ||||||
|  |           </Text> | ||||||
|  |         ))} | ||||||
|  |       </> | ||||||
|  |     ) | ||||||
|  |   }, [mode, initialSize]) | ||||||
|  |  | ||||||
|  |   return ( | ||||||
|  |     <ScrollView scrollEnabled={false}> | ||||||
|  |       <Text style={[styles.header, { color: theme.primary }]}> | ||||||
|  |         {t('content.showcase')} | ||||||
|  |       </Text> | ||||||
|  |       <View> | ||||||
|  |         <ComponentSeparator | ||||||
|  |           extraMarginLeft={-StyleConstants.Spacing.Global.PagePadding} | ||||||
|  |           extraMarginRight={-StyleConstants.Spacing.Global.PagePadding} | ||||||
|  |         /> | ||||||
|  |         <TimelineDefault item={item} disableDetails disableOnPress /> | ||||||
|  |         <ComponentSeparator | ||||||
|  |           extraMarginLeft={-StyleConstants.Spacing.Global.PagePadding} | ||||||
|  |           extraMarginRight={-StyleConstants.Spacing.Global.PagePadding} | ||||||
|  |         /> | ||||||
|  |       </View> | ||||||
|  |       <Text style={[styles.header, { color: theme.primary }]}> | ||||||
|  |         {t('content.availableSizes')} | ||||||
|  |       </Text> | ||||||
|  |       <View style={styles.sizesDemo}>{sizesDemo}</View> | ||||||
|  |       <View style={styles.controls}> | ||||||
|  |         <Button | ||||||
|  |           onPress={() => { | ||||||
|  |             if (initialSize > -1) { | ||||||
|  |               haptics('Light') | ||||||
|  |               dispatch(changeFontsize(initialSize - 1)) | ||||||
|  |             } | ||||||
|  |           }} | ||||||
|  |           type='icon' | ||||||
|  |           content='Minus' | ||||||
|  |           round | ||||||
|  |           disabled={initialSize <= -1} | ||||||
|  |           style={styles.control} | ||||||
|  |         /> | ||||||
|  |         <Button | ||||||
|  |           onPress={() => { | ||||||
|  |             if (initialSize < 3) { | ||||||
|  |               haptics('Light') | ||||||
|  |               dispatch(changeFontsize(initialSize + 1)) | ||||||
|  |             } | ||||||
|  |           }} | ||||||
|  |           type='icon' | ||||||
|  |           content='Plus' | ||||||
|  |           round | ||||||
|  |           disabled={initialSize >= 3} | ||||||
|  |           style={styles.control} | ||||||
|  |         /> | ||||||
|  |       </View> | ||||||
|  |     </ScrollView> | ||||||
|  |   ) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | const styles = StyleSheet.create({ | ||||||
|  |   header: { | ||||||
|  |     ...StyleConstants.FontStyle.M, | ||||||
|  |     textAlign: 'center', | ||||||
|  |     marginTop: StyleConstants.Spacing.M, | ||||||
|  |     marginBottom: StyleConstants.Spacing.M | ||||||
|  |   }, | ||||||
|  |   sizesDemo: { | ||||||
|  |     flexDirection: 'row', | ||||||
|  |     alignItems: 'center', | ||||||
|  |     justifyContent: 'center' | ||||||
|  |   }, | ||||||
|  |   size: { | ||||||
|  |     marginHorizontal: StyleConstants.Spacing.XS, | ||||||
|  |     paddingHorizontal: StyleConstants.Spacing.XS, | ||||||
|  |     marginBottom: StyleConstants.Spacing.M | ||||||
|  |   }, | ||||||
|  |   controls: { | ||||||
|  |     flexDirection: 'row', | ||||||
|  |     alignItems: 'center', | ||||||
|  |     justifyContent: 'center' | ||||||
|  |   }, | ||||||
|  |   control: { | ||||||
|  |     marginHorizontal: StyleConstants.Spacing.S | ||||||
|  |   } | ||||||
|  | }) | ||||||
|  |  | ||||||
|  | export default ScreenMeSettingsFontsize | ||||||
| @@ -71,7 +71,7 @@ const ScreenMeSettingsPush: React.FC = () => { | |||||||
|           /> |           /> | ||||||
|         )) |         )) | ||||||
|       : null |       : null | ||||||
|   }, [instancePush?.global, instancePush?.alerts, isLoading]) |   }, [pushEnabled, instancePush?.global, instancePush?.alerts, isLoading]) | ||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <ScrollView> |     <ScrollView> | ||||||
|   | |||||||
| @@ -6,7 +6,6 @@ import { | |||||||
| import { StyleConstants } from '@utils/styles/constants' | import { StyleConstants } from '@utils/styles/constants' | ||||||
| import { useTheme } from '@utils/styles/ThemeManager' | import { useTheme } from '@utils/styles/ThemeManager' | ||||||
| import Constants from 'expo-constants' | import Constants from 'expo-constants' | ||||||
| import * as Updates from 'expo-updates' |  | ||||||
| import React from 'react' | import React from 'react' | ||||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||||
| import { StyleSheet, Text } from 'react-native' | import { StyleSheet, Text } from 'react-native' | ||||||
| @@ -30,10 +29,7 @@ const SettingsAnalytics: React.FC = () => { | |||||||
|         } |         } | ||||||
|       /> |       /> | ||||||
|       <Text style={[styles.version, { color: theme.secondary }]}> |       <Text style={[styles.version, { color: theme.secondary }]}> | ||||||
|         {t('content.version', { |         {t('content.version', { version: Constants.manifest.version })} | ||||||
|           version: Constants.manifest.version, |  | ||||||
|           releaseChannel: Updates.releaseChannel |  | ||||||
|         })} |  | ||||||
|       </Text> |       </Text> | ||||||
|     </MenuContainer> |     </MenuContainer> | ||||||
|   ) |   ) | ||||||
|   | |||||||
| @@ -16,7 +16,8 @@ import { | |||||||
|   changeTheme, |   changeTheme, | ||||||
|   getSettingsLanguage, |   getSettingsLanguage, | ||||||
|   getSettingsTheme, |   getSettingsTheme, | ||||||
|   getSettingsBrowser |   getSettingsBrowser, | ||||||
|  |   getSettingsFontsize | ||||||
| } from '@utils/slices/settingsSlice' | } from '@utils/slices/settingsSlice' | ||||||
| import { useTheme } from '@utils/styles/ThemeManager' | import { useTheme } from '@utils/styles/ThemeManager' | ||||||
| import * as Notifications from 'expo-notifications' | import * as Notifications from 'expo-notifications' | ||||||
| @@ -24,6 +25,7 @@ import React from 'react' | |||||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||||
| import { Platform } from 'react-native' | import { Platform } from 'react-native' | ||||||
| import { useDispatch, useSelector } from 'react-redux' | import { useDispatch, useSelector } from 'react-redux' | ||||||
|  | import { mapFontsizeToName } from '../Fontsize' | ||||||
|  |  | ||||||
| const SettingsApp: React.FC = () => { | const SettingsApp: React.FC = () => { | ||||||
|   const navigation = useNavigation() |   const navigation = useNavigation() | ||||||
| @@ -34,6 +36,7 @@ const SettingsApp: React.FC = () => { | |||||||
|  |  | ||||||
|   const instances = useSelector(getInstances, () => true) |   const instances = useSelector(getInstances, () => true) | ||||||
|   const instanceActive = useSelector(getInstanceActive) |   const instanceActive = useSelector(getInstanceActive) | ||||||
|  |   const settingsFontsize = useSelector(getSettingsFontsize) | ||||||
|   const settingsLanguage = useSelector(getSettingsLanguage) |   const settingsLanguage = useSelector(getSettingsLanguage) | ||||||
|   const settingsTheme = useSelector(getSettingsTheme) |   const settingsTheme = useSelector(getSettingsTheme) | ||||||
|   const settingsBrowser = useSelector(getSettingsBrowser) |   const settingsBrowser = useSelector(getSettingsBrowser) | ||||||
| @@ -45,18 +48,30 @@ const SettingsApp: React.FC = () => { | |||||||
|   return ( |   return ( | ||||||
|     <MenuContainer> |     <MenuContainer> | ||||||
|       {instanceActive !== -1 ? ( |       {instanceActive !== -1 ? ( | ||||||
|         <MenuRow |         <> | ||||||
|           title={t('content.push.heading')} |           <MenuRow | ||||||
|           content={ |             title={t('content.push.heading')} | ||||||
|             instancePush?.global.value |             content={ | ||||||
|               ? t('content.push.content.enabled') |               instancePush?.global.value | ||||||
|               : t('content.push.content.disabled') |                 ? t('content.push.content.enabled') | ||||||
|           } |                 : t('content.push.content.disabled') | ||||||
|           iconBack='ChevronRight' |             } | ||||||
|           onPress={() => { |             iconBack='ChevronRight' | ||||||
|             navigation.navigate('Tab-Me-Settings-Push') |             onPress={() => { | ||||||
|           }} |               navigation.navigate('Tab-Me-Settings-Push') | ||||||
|         /> |             }} | ||||||
|  |           /> | ||||||
|  |           <MenuRow | ||||||
|  |             title={t('content.fontsize.heading')} | ||||||
|  |             content={t( | ||||||
|  |               `content.fontsize.content.${mapFontsizeToName(settingsFontsize)}` | ||||||
|  |             )} | ||||||
|  |             iconBack='ChevronRight' | ||||||
|  |             onPress={() => { | ||||||
|  |               navigation.navigate('Tab-Me-Settings-Fontsize') | ||||||
|  |             }} | ||||||
|  |           /> | ||||||
|  |         </> | ||||||
|       ) : null} |       ) : null} | ||||||
|       <MenuRow |       <MenuRow | ||||||
|         title={t('content.language.heading')} |         title={t('content.language.heading')} | ||||||
|   | |||||||
| @@ -46,7 +46,7 @@ const SettingsDev: React.FC = () => { | |||||||
|                 .concat(['Cancel']), |                 .concat(['Cancel']), | ||||||
|               cancelButtonIndex: instances.length |               cancelButtonIndex: instances.length | ||||||
|             }, |             }, | ||||||
|             buttonIndex => {} |             () => {} | ||||||
|           ) |           ) | ||||||
|         } |         } | ||||||
|       /> |       /> | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ import TimelineDefault from '@components/Timeline/Default' | |||||||
| import { useNavigation } from '@react-navigation/native' | import { useNavigation } from '@react-navigation/native' | ||||||
| import { QueryKeyTimeline } from '@utils/queryHooks/timeline' | import { QueryKeyTimeline } from '@utils/queryHooks/timeline' | ||||||
| import { findIndex } from 'lodash' | import { findIndex } from 'lodash' | ||||||
| import React, { useCallback, useEffect, useRef, useState } from 'react' | import React, { useCallback, useEffect, useRef } from 'react' | ||||||
| import { FlatList } from 'react-native' | import { FlatList } from 'react-native' | ||||||
| import { InfiniteQueryObserver, useQueryClient } from 'react-query' | import { InfiniteQueryObserver, useQueryClient } from 'react-query' | ||||||
| import { SharedTootProp } from './sharedScreens' | import { SharedTootProp } from './sharedScreens' | ||||||
| @@ -20,7 +20,6 @@ const TabSharedToot: React.FC<SharedTootProp> = ({ | |||||||
|  |  | ||||||
|   const flRef = useRef<FlatList>(null) |   const flRef = useRef<FlatList>(null) | ||||||
|  |  | ||||||
|   const [testState, setTestState] = useState(false) |  | ||||||
|   const scrolled = useRef(false) |   const scrolled = useRef(false) | ||||||
|   const navigation = useNavigation() |   const navigation = useNavigation() | ||||||
|   const queryClient = useQueryClient() |   const queryClient = useQueryClient() | ||||||
| @@ -28,7 +27,6 @@ const TabSharedToot: React.FC<SharedTootProp> = ({ | |||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     const unsubscribe = observer.subscribe(result => { |     const unsubscribe = observer.subscribe(result => { | ||||||
|       if (result.isSuccess) { |       if (result.isSuccess) { | ||||||
|         setTestState(true) |  | ||||||
|         const flattenData = result.data?.pages |         const flattenData = result.data?.pages | ||||||
|           ? // @ts-ignore |           ? // @ts-ignore | ||||||
|             result.data.pages.flatMap(d => [...d.body]) |             result.data.pages.flatMap(d => [...d.body]) | ||||||
| @@ -42,7 +40,7 @@ const TabSharedToot: React.FC<SharedTootProp> = ({ | |||||||
|           const pointer = findIndex(flattenData, ['id', toot.id]) |           const pointer = findIndex(flattenData, ['id', toot.id]) | ||||||
|           setTimeout(() => { |           setTimeout(() => { | ||||||
|             flRef.current?.scrollToIndex({ |             flRef.current?.scrollToIndex({ | ||||||
|               index: pointer, |               index: pointer === -1 ? 0 : pointer, | ||||||
|               viewOffset: 100 |               viewOffset: 100 | ||||||
|             }) |             }) | ||||||
|           }, 500) |           }, 500) | ||||||
| @@ -79,7 +77,7 @@ const TabSharedToot: React.FC<SharedTootProp> = ({ | |||||||
|     <Timeline |     <Timeline | ||||||
|       flRef={flRef} |       flRef={flRef} | ||||||
|       queryKey={queryKey} |       queryKey={queryKey} | ||||||
|       customProps={{ renderItem, ...(testState && onScrollToIndexFailed) }} |       customProps={{ renderItem, onScrollToIndexFailed }} | ||||||
|       disableRefresh |       disableRefresh | ||||||
|       disableInfinity |       disableInfinity | ||||||
|     /> |     /> | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ export const changeAnalytics = createAsyncThunk( | |||||||
| ) | ) | ||||||
|  |  | ||||||
| export type SettingsState = { | export type SettingsState = { | ||||||
|  |   fontsize: -1 | 0 | 1 | 2 | 3 | ||||||
|   language: keyof availableLanguages |   language: keyof availableLanguages | ||||||
|   theme: 'light' | 'dark' | 'auto' |   theme: 'light' | 'dark' | 'auto' | ||||||
|   browser: 'internal' | 'external' |   browser: 'internal' | 'external' | ||||||
| @@ -25,6 +26,7 @@ export type SettingsState = { | |||||||
| } | } | ||||||
|  |  | ||||||
| export const settingsInitialState = { | export const settingsInitialState = { | ||||||
|  |   fontsize: 0, | ||||||
|   notification: { |   notification: { | ||||||
|     enabled: false |     enabled: false | ||||||
|   }, |   }, | ||||||
| @@ -46,6 +48,12 @@ const settingsSlice = createSlice({ | |||||||
|   name: 'settings', |   name: 'settings', | ||||||
|   initialState: settingsInitialState as SettingsState, |   initialState: settingsInitialState as SettingsState, | ||||||
|   reducers: { |   reducers: { | ||||||
|  |     changeFontsize: ( | ||||||
|  |       state, | ||||||
|  |       action: PayloadAction<SettingsState['fontsize']> | ||||||
|  |     ) => { | ||||||
|  |       state.fontsize = action.payload | ||||||
|  |     }, | ||||||
|     changeLanguage: ( |     changeLanguage: ( | ||||||
|       state, |       state, | ||||||
|       action: PayloadAction<NonNullable<SettingsState['language']>> |       action: PayloadAction<NonNullable<SettingsState['language']>> | ||||||
| @@ -72,6 +80,8 @@ const settingsSlice = createSlice({ | |||||||
|   } |   } | ||||||
| }) | }) | ||||||
|  |  | ||||||
|  | export const getSettingsFontsize = (state: RootState) => | ||||||
|  |   state.settings.fontsize || 0 | ||||||
| export const getSettingsLanguage = (state: RootState) => state.settings.language | export const getSettingsLanguage = (state: RootState) => state.settings.language | ||||||
| export const getSettingsTheme = (state: RootState) => state.settings.theme | export const getSettingsTheme = (state: RootState) => state.settings.theme | ||||||
| export const getSettingsBrowser = (state: RootState) => state.settings.browser | export const getSettingsBrowser = (state: RootState) => state.settings.browser | ||||||
| @@ -79,6 +89,7 @@ export const getSettingsAnalytics = (state: RootState) => | |||||||
|   state.settings.analytics |   state.settings.analytics | ||||||
|  |  | ||||||
| export const { | export const { | ||||||
|  |   changeFontsize, | ||||||
|   changeLanguage, |   changeLanguage, | ||||||
|   changeTheme, |   changeTheme, | ||||||
|   changeBrowser |   changeBrowser | ||||||
|   | |||||||
| @@ -7,25 +7,25 @@ const guidelineBaseWidth = 375 | |||||||
|  |  | ||||||
| const scale = (size: number) => (width / guidelineBaseWidth) * size | const scale = (size: number) => (width / guidelineBaseWidth) * size | ||||||
| // const verticalScale = (size: number) => (height / guidelineBaseHeight) * size | // const verticalScale = (size: number) => (height / guidelineBaseHeight) * size | ||||||
| const moderateScale = (size: number, factor = 0.5) => | export const adaptiveScale = (size: number, factor: number = 0) => | ||||||
|   size + (scale(size) - size) * factor |   size + (scale(size) - size) * factor | ||||||
|  |  | ||||||
| const Base = 4 | const Base = 4 | ||||||
|  |  | ||||||
| export const StyleConstants = { | export const StyleConstants = { | ||||||
|   Font: { |   Font: { | ||||||
|     Size: { S: moderateScale(14), M: moderateScale(16), L: moderateScale(18) }, |     Size: { S: 14, M: 16, L: 18 }, | ||||||
|     LineHeight: { |     LineHeight: { | ||||||
|       S: moderateScale(20), |       S: 20, | ||||||
|       M: moderateScale(22), |       M: 22, | ||||||
|       L: moderateScale(30) |       L: 30 | ||||||
|     }, |     }, | ||||||
|     Weight: { Normal: '400' as '400', Bold: '600' as '600' } |     Weight: { Normal: '400' as '400', Bold: '600' as '600' } | ||||||
|   }, |   }, | ||||||
|   FontStyle: { |   FontStyle: { | ||||||
|     S: { fontSize: moderateScale(14), lineHeight: moderateScale(20) }, |     S: { fontSize: 14, lineHeight: 20 }, | ||||||
|     M: { fontSize: moderateScale(16), lineHeight: moderateScale(22) }, |     M: { fontSize: 16, lineHeight: 22 }, | ||||||
|     L: { fontSize: moderateScale(20), lineHeight: moderateScale(30) } |     L: { fontSize: 20, lineHeight: 30 } | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|   Spacing: { |   Spacing: { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user