mirror of
				https://github.com/tooot-app/app
				synced 2025-06-05 22:19:13 +02:00 
			
		
		
		
	Theme done
This commit is contained in:
		
							
								
								
									
										116
									
								
								src/Index.tsx
									
									
									
									
									
								
							
							
						
						
									
										116
									
								
								src/Index.tsx
									
									
									
									
									
								
							@@ -4,6 +4,7 @@ import { NavigationContainer } from '@react-navigation/native'
 | 
			
		||||
import { enableScreens } from 'react-native-screens'
 | 
			
		||||
 | 
			
		||||
import React from 'react'
 | 
			
		||||
import { StatusBar } from 'react-native'
 | 
			
		||||
import Toast from 'react-native-toast-message'
 | 
			
		||||
import { Feather } from '@expo/vector-icons'
 | 
			
		||||
 | 
			
		||||
@@ -30,65 +31,72 @@ export type RootStackParamList = {
 | 
			
		||||
 | 
			
		||||
export const Index: React.FC = () => {
 | 
			
		||||
  const { mode, theme } = useTheme()
 | 
			
		||||
  enum barStyle {
 | 
			
		||||
    light = 'dark-content',
 | 
			
		||||
    dark = 'light-content'
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <NavigationContainer theme={themes[mode]}>
 | 
			
		||||
      <Tab.Navigator
 | 
			
		||||
        screenOptions={({ route }) => ({
 | 
			
		||||
          tabBarIcon: ({ focused, color, size }) => {
 | 
			
		||||
            let name: string
 | 
			
		||||
            switch (route.name) {
 | 
			
		||||
              case 'Screen-Local':
 | 
			
		||||
                name = 'home'
 | 
			
		||||
                break
 | 
			
		||||
              case 'Screen-Public':
 | 
			
		||||
                name = 'globe'
 | 
			
		||||
                break
 | 
			
		||||
              case 'Screen-Post':
 | 
			
		||||
                name = 'plus'
 | 
			
		||||
                break
 | 
			
		||||
              case 'Screen-Notifications':
 | 
			
		||||
                name = 'bell'
 | 
			
		||||
                break
 | 
			
		||||
              case 'Screen-Me':
 | 
			
		||||
                name = focused ? 'smile' : 'meh'
 | 
			
		||||
                break
 | 
			
		||||
              default:
 | 
			
		||||
                name = 'alert-octagon'
 | 
			
		||||
                break
 | 
			
		||||
            }
 | 
			
		||||
            return <Feather name={name} size={size} color={color} />
 | 
			
		||||
          }
 | 
			
		||||
        })}
 | 
			
		||||
        tabBarOptions={{
 | 
			
		||||
          activeTintColor: theme.primary,
 | 
			
		||||
          inactiveTintColor: theme.secondary,
 | 
			
		||||
          showLabel: false
 | 
			
		||||
        }}
 | 
			
		||||
      >
 | 
			
		||||
        <Tab.Screen name='Screen-Local' component={ScreenLocal} />
 | 
			
		||||
        <Tab.Screen name='Screen-Public' component={ScreenPublic} />
 | 
			
		||||
        <Tab.Screen
 | 
			
		||||
          name='Screen-Post'
 | 
			
		||||
          listeners={({ navigation, route }) => ({
 | 
			
		||||
            tabPress: e => {
 | 
			
		||||
              e.preventDefault()
 | 
			
		||||
              navigation.navigate(getCurrentTab(navigation), {
 | 
			
		||||
                screen: 'Screen-Shared-Compose'
 | 
			
		||||
              })
 | 
			
		||||
    <>
 | 
			
		||||
      <StatusBar barStyle={barStyle[mode]} />
 | 
			
		||||
      <NavigationContainer theme={themes[mode]}>
 | 
			
		||||
        <Tab.Navigator
 | 
			
		||||
          screenOptions={({ route }) => ({
 | 
			
		||||
            tabBarIcon: ({ focused, color, size }) => {
 | 
			
		||||
              let name: string
 | 
			
		||||
              switch (route.name) {
 | 
			
		||||
                case 'Screen-Local':
 | 
			
		||||
                  name = 'home'
 | 
			
		||||
                  break
 | 
			
		||||
                case 'Screen-Public':
 | 
			
		||||
                  name = 'globe'
 | 
			
		||||
                  break
 | 
			
		||||
                case 'Screen-Post':
 | 
			
		||||
                  name = 'plus'
 | 
			
		||||
                  break
 | 
			
		||||
                case 'Screen-Notifications':
 | 
			
		||||
                  name = 'bell'
 | 
			
		||||
                  break
 | 
			
		||||
                case 'Screen-Me':
 | 
			
		||||
                  name = focused ? 'smile' : 'meh'
 | 
			
		||||
                  break
 | 
			
		||||
                default:
 | 
			
		||||
                  name = 'alert-octagon'
 | 
			
		||||
                  break
 | 
			
		||||
              }
 | 
			
		||||
              return <Feather name={name} size={size} color={color} />
 | 
			
		||||
            }
 | 
			
		||||
          })}
 | 
			
		||||
          tabBarOptions={{
 | 
			
		||||
            activeTintColor: theme.primary,
 | 
			
		||||
            inactiveTintColor: theme.secondary,
 | 
			
		||||
            showLabel: false
 | 
			
		||||
          }}
 | 
			
		||||
        >
 | 
			
		||||
          {() => <></>}
 | 
			
		||||
        </Tab.Screen>
 | 
			
		||||
        <Tab.Screen
 | 
			
		||||
          name='Screen-Notifications'
 | 
			
		||||
          component={ScreenNotifications}
 | 
			
		||||
        />
 | 
			
		||||
        <Tab.Screen name='Screen-Me' component={ScreenMe} />
 | 
			
		||||
      </Tab.Navigator>
 | 
			
		||||
          <Tab.Screen name='Screen-Local' component={ScreenLocal} />
 | 
			
		||||
          <Tab.Screen name='Screen-Public' component={ScreenPublic} />
 | 
			
		||||
          <Tab.Screen
 | 
			
		||||
            name='Screen-Post'
 | 
			
		||||
            listeners={({ navigation, route }) => ({
 | 
			
		||||
              tabPress: e => {
 | 
			
		||||
                e.preventDefault()
 | 
			
		||||
                navigation.navigate(getCurrentTab(navigation), {
 | 
			
		||||
                  screen: 'Screen-Shared-Compose'
 | 
			
		||||
                })
 | 
			
		||||
              }
 | 
			
		||||
            })}
 | 
			
		||||
          >
 | 
			
		||||
            {() => <></>}
 | 
			
		||||
          </Tab.Screen>
 | 
			
		||||
          <Tab.Screen
 | 
			
		||||
            name='Screen-Notifications'
 | 
			
		||||
            component={ScreenNotifications}
 | 
			
		||||
          />
 | 
			
		||||
          <Tab.Screen name='Screen-Me' component={ScreenMe} />
 | 
			
		||||
        </Tab.Navigator>
 | 
			
		||||
 | 
			
		||||
      <Toast ref={(ref: any) => Toast.setRef(ref)} config={toastConfig} />
 | 
			
		||||
    </NavigationContainer>
 | 
			
		||||
        <Toast ref={(ref: any) => Toast.setRef(ref)} config={toastConfig} />
 | 
			
		||||
      </NavigationContainer>
 | 
			
		||||
    </>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,7 @@ export interface Props {
 | 
			
		||||
 | 
			
		||||
const Timelines: React.FC<Props> = ({ name, content }) => {
 | 
			
		||||
  const navigation = useNavigation()
 | 
			
		||||
  const { theme } = useTheme()
 | 
			
		||||
  const { mode, theme } = useTheme()
 | 
			
		||||
  const localRegistered = useSelector(getLocalUrl)
 | 
			
		||||
  const publicDomain = useSelector(getRemoteUrl)
 | 
			
		||||
  const [segment, setSegment] = useState(0)
 | 
			
		||||
@@ -107,6 +107,7 @@ const Timelines: React.FC<Props> = ({ name, content }) => {
 | 
			
		||||
              headerCenter: () => (
 | 
			
		||||
                <View style={styles.segmentsContainer}>
 | 
			
		||||
                  <SegmentedControl
 | 
			
		||||
                    appearance={mode}
 | 
			
		||||
                    values={[content[0].title, content[1].title]}
 | 
			
		||||
                    selectedIndex={segment}
 | 
			
		||||
                    onChange={onChangeSegment}
 | 
			
		||||
 
 | 
			
		||||
@@ -88,6 +88,7 @@ const TimelineDefault: React.FC<Props> = ({ item, queryKey }) => {
 | 
			
		||||
              emojis={actualStatus.account.emojis}
 | 
			
		||||
              account={actualStatus.account.acct}
 | 
			
		||||
              created_at={item.created_at}
 | 
			
		||||
              visibility={item.visibility}
 | 
			
		||||
              application={item.application}
 | 
			
		||||
            />
 | 
			
		||||
            {/* Can pass toot info to next page to speed up performance */}
 | 
			
		||||
 
 | 
			
		||||
@@ -98,6 +98,7 @@ export interface Props {
 | 
			
		||||
  emojis?: Mastodon.Emoji[]
 | 
			
		||||
  account: string
 | 
			
		||||
  created_at: string
 | 
			
		||||
  visibility: Mastodon.Status['visibility']
 | 
			
		||||
  application?: Mastodon.Application
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -109,6 +110,7 @@ const HeaderDefault: React.FC<Props> = ({
 | 
			
		||||
  emojis,
 | 
			
		||||
  account,
 | 
			
		||||
  created_at,
 | 
			
		||||
  visibility,
 | 
			
		||||
  application
 | 
			
		||||
}) => {
 | 
			
		||||
  const { theme } = useTheme()
 | 
			
		||||
@@ -197,6 +199,14 @@ const HeaderDefault: React.FC<Props> = ({
 | 
			
		||||
            {since}
 | 
			
		||||
          </Text>
 | 
			
		||||
        </View>
 | 
			
		||||
        {visibility === 'private' && (
 | 
			
		||||
          <Feather
 | 
			
		||||
            name='lock'
 | 
			
		||||
            size={constants.FONT_SIZE_S}
 | 
			
		||||
            color={theme.secondary}
 | 
			
		||||
            style={styles.visibility}
 | 
			
		||||
          />
 | 
			
		||||
        )}
 | 
			
		||||
        {application && application.name !== 'Web' && (
 | 
			
		||||
          <View>
 | 
			
		||||
            <Text
 | 
			
		||||
@@ -292,12 +302,16 @@ const styles = StyleSheet.create({
 | 
			
		||||
  },
 | 
			
		||||
  meta: {
 | 
			
		||||
    flexDirection: 'row',
 | 
			
		||||
    alignItems: 'center',
 | 
			
		||||
    marginTop: constants.SPACING_XS,
 | 
			
		||||
    marginBottom: constants.SPACING_S
 | 
			
		||||
  },
 | 
			
		||||
  created_at: {
 | 
			
		||||
    fontSize: constants.FONT_SIZE_S
 | 
			
		||||
  },
 | 
			
		||||
  visibility: {
 | 
			
		||||
    marginLeft: constants.SPACING_S
 | 
			
		||||
  },
 | 
			
		||||
  application: {
 | 
			
		||||
    fontSize: constants.FONT_SIZE_S,
 | 
			
		||||
    marginLeft: constants.SPACING_S
 | 
			
		||||
 
 | 
			
		||||
@@ -9,9 +9,8 @@ import {
 | 
			
		||||
  getSettingsLanguage
 | 
			
		||||
} from 'src/utils/slices/settingsSlice'
 | 
			
		||||
import { store } from 'src/store'
 | 
			
		||||
  console.log(store.getState())
 | 
			
		||||
 | 
			
		||||
if (!getSettingsLanguage(store.getState())) {
 | 
			
		||||
  console.log('No default locale of app')
 | 
			
		||||
  const deviceLocal = Localization.locale
 | 
			
		||||
  if (deviceLocal.startsWith('zh')) {
 | 
			
		||||
    store.dispatch(changeLanguage('zh'))
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,11 @@
 | 
			
		||||
export default {
 | 
			
		||||
  common: require('./common').default,
 | 
			
		||||
  settings: require('./settings').default
 | 
			
		||||
 | 
			
		||||
  meRoot: require('./screens/meRoot').default,
 | 
			
		||||
  meConversations: require('./screens/meConversations').default,
 | 
			
		||||
  meBookmarks: require('./screens/meBookmarks').default,
 | 
			
		||||
  meFavourites: require('./screens/meFavourites').default,
 | 
			
		||||
  meLists: require('./screens/meLists').default,
 | 
			
		||||
  meListsList: require('./screens/meListsList').default,
 | 
			
		||||
  meSettings: require('./screens/meSettings').default
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,7 @@
 | 
			
		||||
export default {
 | 
			
		||||
  buttons: {
 | 
			
		||||
    cancel: '取消'
 | 
			
		||||
  },
 | 
			
		||||
  headers: {
 | 
			
		||||
    local: {
 | 
			
		||||
      segments: {
 | 
			
		||||
@@ -12,20 +15,6 @@ export default {
 | 
			
		||||
        right: '外站嘟嘟'
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    notifications: '我的通知',
 | 
			
		||||
    me: {
 | 
			
		||||
      root: '我的长毛象',
 | 
			
		||||
      conversations: '私信',
 | 
			
		||||
      bookmarks: '书签',
 | 
			
		||||
      favourites: '喜欢',
 | 
			
		||||
      lists: {
 | 
			
		||||
        root: '列表',
 | 
			
		||||
        list: '列表 {{list}}'
 | 
			
		||||
      },
 | 
			
		||||
      settings: {
 | 
			
		||||
        root: '设置',
 | 
			
		||||
        language: '语言'
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    notifications: '我的通知'
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								src/i18n/zh/screens/meBookmarks.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/i18n/zh/screens/meBookmarks.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
export default {
 | 
			
		||||
  heading: '书签',
 | 
			
		||||
  content: {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								src/i18n/zh/screens/meConversations.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/i18n/zh/screens/meConversations.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
export default {
 | 
			
		||||
  heading: '私信',
 | 
			
		||||
  content: {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								src/i18n/zh/screens/meFavourites.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/i18n/zh/screens/meFavourites.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
export default {
 | 
			
		||||
  heading: '收藏',
 | 
			
		||||
  content: {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								src/i18n/zh/screens/meLists.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/i18n/zh/screens/meLists.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
export default {
 | 
			
		||||
  heading: '列表',
 | 
			
		||||
  content: {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										4
									
								
								src/i18n/zh/screens/meListsList.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/i18n/zh/screens/meListsList.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,4 @@
 | 
			
		||||
export default {
 | 
			
		||||
  heading: '列表 {{list}}',
 | 
			
		||||
  content: {}
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										24
									
								
								src/i18n/zh/screens/meRoot.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/i18n/zh/screens/meRoot.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
			
		||||
export default {
 | 
			
		||||
  heading: '我的长毛象',
 | 
			
		||||
  content: {
 | 
			
		||||
    login: {},
 | 
			
		||||
    collections: {
 | 
			
		||||
      conversations: '$t(meConversations:heading)',
 | 
			
		||||
      bookmarks: '$t(meBookmarks:heading)',
 | 
			
		||||
      favourites: '$t(meFavourites:heading)',
 | 
			
		||||
      lists: '$t(meLists:heading)'
 | 
			
		||||
    },
 | 
			
		||||
    settings: '$t(meSettings:heading)',
 | 
			
		||||
    logout: {
 | 
			
		||||
      button: '退出当前账号',
 | 
			
		||||
      alert: {
 | 
			
		||||
        title: '确认退出登录?',
 | 
			
		||||
        message: '退出登录后,需要重新认证账号',
 | 
			
		||||
        buttons: {
 | 
			
		||||
          logout: '退出登录',
 | 
			
		||||
          cancel: '$t(common:buttons.cancel)'
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										22
									
								
								src/i18n/zh/screens/meSettings.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/i18n/zh/screens/meSettings.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
			
		||||
export default {
 | 
			
		||||
  heading: '设置',
 | 
			
		||||
  content: {
 | 
			
		||||
    language: {
 | 
			
		||||
      heading: '切换语言',
 | 
			
		||||
      options: {
 | 
			
		||||
        zh: '简体中文',
 | 
			
		||||
        en: 'English',
 | 
			
		||||
        cancel: '$t(common:buttons.cancel)'
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    theme: {
 | 
			
		||||
      heading: '颜色模式',
 | 
			
		||||
      options: {
 | 
			
		||||
        auto: '跟随系统',
 | 
			
		||||
        light: '浅色模式',
 | 
			
		||||
        dark: '深色模式',
 | 
			
		||||
        cancel: '$t(common:buttons.cancel)'
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
export default {
 | 
			
		||||
  content: {
 | 
			
		||||
    language: {
 | 
			
		||||
      title: '切换语言',
 | 
			
		||||
      options: {
 | 
			
		||||
        zh: '简体中文',
 | 
			
		||||
        en: 'English'
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -41,42 +41,42 @@ const ScreenMe: React.FC = () => {
 | 
			
		||||
        name='Screen-Me-Conversations'
 | 
			
		||||
        component={ScreenMeConversations}
 | 
			
		||||
        options={{
 | 
			
		||||
          headerTitle: t('headers.me.conversations')
 | 
			
		||||
          headerTitle: t('meConversations:heading')
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
      <Stack.Screen
 | 
			
		||||
        name='Screen-Me-Bookmarks'
 | 
			
		||||
        component={ScreenMeBookmarks}
 | 
			
		||||
        options={{
 | 
			
		||||
          headerTitle: t('headers.me.bookmarks')
 | 
			
		||||
          headerTitle: t('meBookmarks:heading')
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
      <Stack.Screen
 | 
			
		||||
        name='Screen-Me-Favourites'
 | 
			
		||||
        component={ScreenMeFavourites}
 | 
			
		||||
        options={{
 | 
			
		||||
          headerTitle: t('headers.me.favourites')
 | 
			
		||||
          headerTitle: t('meFavourites:heading')
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
      <Stack.Screen
 | 
			
		||||
        name='Screen-Me-Lists'
 | 
			
		||||
        component={ScreenMeLists}
 | 
			
		||||
        options={{
 | 
			
		||||
          headerTitle: t('headers.me.lists.root')
 | 
			
		||||
          headerTitle: t('meLists:heading')
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
      <Stack.Screen
 | 
			
		||||
        name='Screen-Me-Lists-List'
 | 
			
		||||
        component={ScreenMeListsList}
 | 
			
		||||
        options={({ route }: any) => ({
 | 
			
		||||
          headerTitle: t('headers.me.lists.list', { list: route.params.title })
 | 
			
		||||
          headerTitle: t('meListsList:heading', { list: route.params.title })
 | 
			
		||||
        })}
 | 
			
		||||
      />
 | 
			
		||||
      <Stack.Screen
 | 
			
		||||
        name='Screen-Me-Settings'
 | 
			
		||||
        component={ScreenMeSettings}
 | 
			
		||||
        options={{
 | 
			
		||||
          headerTitle: t('headers.me.settings.root')
 | 
			
		||||
          headerTitle: t('meSettings:heading')
 | 
			
		||||
        }}
 | 
			
		||||
      />
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,7 @@ import { getLocalUrl } from 'src/utils/slices/instancesSlice'
 | 
			
		||||
 | 
			
		||||
import Login from './Root/Login'
 | 
			
		||||
import MyInfo from './Root/MyInfo'
 | 
			
		||||
import MyCollections from './Root/MyCollections'
 | 
			
		||||
import Collections from './Root/Collections'
 | 
			
		||||
import Settings from './Root/Settings'
 | 
			
		||||
import Logout from './Root/Logout'
 | 
			
		||||
 | 
			
		||||
@@ -16,7 +16,7 @@ const ScreenMeRoot: React.FC = () => {
 | 
			
		||||
  return (
 | 
			
		||||
    <ScrollView>
 | 
			
		||||
      {localRegistered ? <MyInfo /> : <Login />}
 | 
			
		||||
      {localRegistered && <MyCollections />}
 | 
			
		||||
      {localRegistered && <Collections />}
 | 
			
		||||
      <Settings />
 | 
			
		||||
      {localRegistered && <Logout />}
 | 
			
		||||
    </ScrollView>
 | 
			
		||||
 
 | 
			
		||||
@@ -4,34 +4,34 @@ import { useTranslation } from 'react-i18next'
 | 
			
		||||
 | 
			
		||||
import { MenuContainer, MenuItem } from 'src/components/Menu'
 | 
			
		||||
 | 
			
		||||
const MyInfo: React.FC = () => {
 | 
			
		||||
  const { t } = useTranslation()
 | 
			
		||||
const Collections: React.FC = () => {
 | 
			
		||||
  const { t } = useTranslation('meRoot')
 | 
			
		||||
  const navigation = useNavigation()
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <MenuContainer>
 | 
			
		||||
      <MenuItem
 | 
			
		||||
        iconFront='mail'
 | 
			
		||||
        title={t('headers.me.conversations')}
 | 
			
		||||
        title={t('content.collections.conversations')}
 | 
			
		||||
        onPress={() => navigation.navigate('Screen-Me-Conversations')}
 | 
			
		||||
      />
 | 
			
		||||
      <MenuItem
 | 
			
		||||
        iconFront='bookmark'
 | 
			
		||||
        title={t('headers.me.bookmarks')}
 | 
			
		||||
        title={t('content.collections.bookmarks')}
 | 
			
		||||
        onPress={() => navigation.navigate('Screen-Me-Bookmarks')}
 | 
			
		||||
      />
 | 
			
		||||
      <MenuItem
 | 
			
		||||
        iconFront='star'
 | 
			
		||||
        title={t('headers.me.favourites')}
 | 
			
		||||
        title={t('content.collections.favourites')}
 | 
			
		||||
        onPress={() => navigation.navigate('Screen-Me-Favourites')}
 | 
			
		||||
      />
 | 
			
		||||
      <MenuItem
 | 
			
		||||
        iconFront='list'
 | 
			
		||||
        title={t('headers.me.lists.root')}
 | 
			
		||||
        title={t('content.collections.lists')}
 | 
			
		||||
        onPress={() => navigation.navigate('Screen-Me-Lists')}
 | 
			
		||||
      />
 | 
			
		||||
    </MenuContainer>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default MyInfo
 | 
			
		||||
export default Collections
 | 
			
		||||
@@ -5,17 +5,19 @@ import { updateLocal } from 'src/utils/slices/instancesSlice'
 | 
			
		||||
import MenuButton from 'src/components/Menu/Button'
 | 
			
		||||
import { MenuContainer } from 'src/components/Menu'
 | 
			
		||||
import { useNavigation } from '@react-navigation/native'
 | 
			
		||||
import { useTranslation } from 'react-i18next'
 | 
			
		||||
 | 
			
		||||
const Logout: React.FC = () => {
 | 
			
		||||
  const { t } = useTranslation('meRoot')
 | 
			
		||||
  const dispatch = useDispatch()
 | 
			
		||||
  const navigation = useNavigation()
 | 
			
		||||
 | 
			
		||||
  const alertOption = {
 | 
			
		||||
    title: '确认退出登录?',
 | 
			
		||||
    message: '退出登录后,需要重新认证账号',
 | 
			
		||||
    title: t('content.logout.alert.title'),
 | 
			
		||||
    message: t('content.logout.alert.message'),
 | 
			
		||||
    buttons: [
 | 
			
		||||
      {
 | 
			
		||||
        text: '退出登录',
 | 
			
		||||
        text: t('content.logout.alert.buttons.logout'),
 | 
			
		||||
        style: 'destructive' as const,
 | 
			
		||||
        onPress: () => {
 | 
			
		||||
          dispatch(updateLocal({}))
 | 
			
		||||
@@ -26,7 +28,7 @@ const Logout: React.FC = () => {
 | 
			
		||||
        }
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        text: '取消',
 | 
			
		||||
        text: t('content.logout.alert.buttons.cancel'),
 | 
			
		||||
        style: 'cancel' as const
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
@@ -35,7 +37,7 @@ const Logout: React.FC = () => {
 | 
			
		||||
  return (
 | 
			
		||||
    <MenuContainer>
 | 
			
		||||
      <MenuButton
 | 
			
		||||
        text='退出当前账号'
 | 
			
		||||
        text={t('content.logout.button')}
 | 
			
		||||
        destructive={true}
 | 
			
		||||
        alertOption={alertOption}
 | 
			
		||||
      />
 | 
			
		||||
 
 | 
			
		||||
@@ -5,14 +5,14 @@ import { useTranslation } from 'react-i18next'
 | 
			
		||||
import { MenuContainer, MenuItem } from 'src/components/Menu'
 | 
			
		||||
 | 
			
		||||
const Settings: React.FC = () => {
 | 
			
		||||
  const { t } = useTranslation()
 | 
			
		||||
  const { t } = useTranslation('meRoot')
 | 
			
		||||
  const navigation = useNavigation()
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <MenuContainer>
 | 
			
		||||
      <MenuItem
 | 
			
		||||
        iconFront='settings'
 | 
			
		||||
        title={t('headers.me.settings.root')}
 | 
			
		||||
        title={t('content.settings')}
 | 
			
		||||
        onPress={() => navigation.navigate('Screen-Me-Settings')}
 | 
			
		||||
      />
 | 
			
		||||
    </MenuContainer>
 | 
			
		||||
 
 | 
			
		||||
@@ -6,28 +6,32 @@ import { useDispatch, useSelector } from 'react-redux'
 | 
			
		||||
import { MenuContainer, MenuItem } from 'src/components/Menu'
 | 
			
		||||
import {
 | 
			
		||||
  changeLanguage,
 | 
			
		||||
  getSettingsLanguage
 | 
			
		||||
  changeTheme,
 | 
			
		||||
  getSettingsLanguage,
 | 
			
		||||
  getSettingsTheme
 | 
			
		||||
} from 'src/utils/slices/settingsSlice'
 | 
			
		||||
import { useTheme } from 'src/utils/styles/ThemeManager'
 | 
			
		||||
 | 
			
		||||
const ScreenMeSettings: React.FC = () => {
 | 
			
		||||
  const { t, i18n } = useTranslation('settings')
 | 
			
		||||
  const language = useSelector(getSettingsLanguage)
 | 
			
		||||
  const { t, i18n } = useTranslation('meSettings')
 | 
			
		||||
  const { setTheme } = useTheme()
 | 
			
		||||
  const settingsLanguage = useSelector(getSettingsLanguage)
 | 
			
		||||
  const settingsTheme = useSelector(getSettingsTheme)
 | 
			
		||||
  const dispatch = useDispatch()
 | 
			
		||||
  console.log(i18n.language)
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <MenuContainer marginTop={true}>
 | 
			
		||||
      <MenuItem
 | 
			
		||||
        title={t('content.language.title')}
 | 
			
		||||
        content={t(`settings:content.language.options.${language}`)}
 | 
			
		||||
        title={t('content.language.heading')}
 | 
			
		||||
        content={t(`content.language.options.${settingsLanguage}`)}
 | 
			
		||||
        iconBack='chevron-right'
 | 
			
		||||
        onPress={() =>
 | 
			
		||||
          ActionSheetIOS.showActionSheetWithOptions(
 | 
			
		||||
            {
 | 
			
		||||
              options: [
 | 
			
		||||
                t('settings:content.language.options.zh'),
 | 
			
		||||
                t('settings:content.language.options.en'),
 | 
			
		||||
                '取消'
 | 
			
		||||
                t('content.language.options.zh'),
 | 
			
		||||
                t('content.language.options.en'),
 | 
			
		||||
                t('content.language.options.cancel')
 | 
			
		||||
              ],
 | 
			
		||||
              cancelButtonIndex: 2
 | 
			
		||||
            },
 | 
			
		||||
@@ -46,6 +50,39 @@ const ScreenMeSettings: React.FC = () => {
 | 
			
		||||
          )
 | 
			
		||||
        }
 | 
			
		||||
      />
 | 
			
		||||
      <MenuItem
 | 
			
		||||
        title={t('content.theme.heading')}
 | 
			
		||||
        content={t(`content.theme.options.${settingsTheme}`)}
 | 
			
		||||
        iconBack='chevron-right'
 | 
			
		||||
        onPress={() =>
 | 
			
		||||
          ActionSheetIOS.showActionSheetWithOptions(
 | 
			
		||||
            {
 | 
			
		||||
              options: [
 | 
			
		||||
                t('content.theme.options.auto'),
 | 
			
		||||
                t('content.theme.options.light'),
 | 
			
		||||
                t('content.theme.options.dark'),
 | 
			
		||||
                t('content.theme.options.cancel')
 | 
			
		||||
              ],
 | 
			
		||||
              cancelButtonIndex: 3
 | 
			
		||||
            },
 | 
			
		||||
            buttonIndex => {
 | 
			
		||||
              switch (buttonIndex) {
 | 
			
		||||
                case 0:
 | 
			
		||||
                  dispatch(changeTheme('auto'))
 | 
			
		||||
                  break
 | 
			
		||||
                case 1:
 | 
			
		||||
                  dispatch(changeTheme('light'))
 | 
			
		||||
                  setTheme('light')
 | 
			
		||||
                  break
 | 
			
		||||
                case 2:
 | 
			
		||||
                  dispatch(changeTheme('dark'))
 | 
			
		||||
                  setTheme('dark')
 | 
			
		||||
                  break
 | 
			
		||||
              }
 | 
			
		||||
            }
 | 
			
		||||
          )
 | 
			
		||||
        }
 | 
			
		||||
      />
 | 
			
		||||
    </MenuContainer>
 | 
			
		||||
  )
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -5,10 +5,12 @@ import { RootState } from 'src/store'
 | 
			
		||||
 | 
			
		||||
export type SettingsState = {
 | 
			
		||||
  language: 'zh' | 'en' | undefined
 | 
			
		||||
  theme: 'light' | 'dark' | 'auto'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const initialState = {
 | 
			
		||||
  language: undefined
 | 
			
		||||
  language: undefined,
 | 
			
		||||
  theme: 'auto'
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// export const updateLocal = createAsyncThunk(
 | 
			
		||||
@@ -62,6 +64,12 @@ const settingsSlice = createSlice({
 | 
			
		||||
      action: PayloadAction<NonNullable<SettingsState['language']>>
 | 
			
		||||
    ) => {
 | 
			
		||||
      state.language = action.payload
 | 
			
		||||
    },
 | 
			
		||||
    changeTheme: (
 | 
			
		||||
      state,
 | 
			
		||||
      action: PayloadAction<NonNullable<SettingsState['theme']>>
 | 
			
		||||
    ) => {
 | 
			
		||||
      state.theme = action.payload
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  // extraReducers: builder => {
 | 
			
		||||
@@ -72,6 +80,7 @@ const settingsSlice = createSlice({
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
export const getSettingsLanguage = (state: RootState) => state.settings.language
 | 
			
		||||
export const getSettingsTheme = (state: RootState) => state.settings.theme
 | 
			
		||||
 | 
			
		||||
export const { changeLanguage } = settingsSlice.actions
 | 
			
		||||
export const { changeLanguage, changeTheme } = settingsSlice.actions
 | 
			
		||||
export default settingsSlice.reducer
 | 
			
		||||
 
 | 
			
		||||
@@ -1,39 +1,44 @@
 | 
			
		||||
import React, { createContext, useContext, useEffect, useState } from 'react'
 | 
			
		||||
import { Appearance, useColorScheme } from 'react-native-appearance'
 | 
			
		||||
import { Appearance } from 'react-native-appearance'
 | 
			
		||||
import { useSelector } from 'react-redux'
 | 
			
		||||
import { ColorDefinitions, getTheme } from 'src/utils/styles/themes'
 | 
			
		||||
import { getSettingsTheme } from '../slices/settingsSlice'
 | 
			
		||||
 | 
			
		||||
const osTheme = Appearance.getColorScheme() as 'light' | 'dark'
 | 
			
		||||
 | 
			
		||||
export const ManageThemeContext: React.Context<{
 | 
			
		||||
type ContextType = {
 | 
			
		||||
  mode: 'light' | 'dark'
 | 
			
		||||
  theme: { [key in ColorDefinitions]: string }
 | 
			
		||||
  toggle: () => void
 | 
			
		||||
}> = createContext({
 | 
			
		||||
  mode: osTheme,
 | 
			
		||||
  theme: getTheme(osTheme),
 | 
			
		||||
  toggle: () => {}
 | 
			
		||||
  setTheme: (theme: 'light' | 'dark') => void
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const ManageThemeContext = createContext<ContextType>({
 | 
			
		||||
  mode: 'light',
 | 
			
		||||
  theme: getTheme('light'),
 | 
			
		||||
  setTheme: () => {}
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
export const useTheme = () => useContext(ManageThemeContext)
 | 
			
		||||
 | 
			
		||||
const ThemeManager: React.FC = ({ children }) => {
 | 
			
		||||
  const [mode, setMode] = useState(osTheme)
 | 
			
		||||
  const systemTheme = useColorScheme()
 | 
			
		||||
  const userTheme = useSelector(getSettingsTheme)
 | 
			
		||||
  const currentMode =
 | 
			
		||||
    userTheme === 'auto'
 | 
			
		||||
      ? (Appearance.getColorScheme() as 'light' | 'dark')
 | 
			
		||||
      : userTheme
 | 
			
		||||
 | 
			
		||||
  const toggleTheme = () => {
 | 
			
		||||
    mode === 'light' ? setMode('dark') : setMode('light')
 | 
			
		||||
  }
 | 
			
		||||
  const [mode, setMode] = useState(currentMode)
 | 
			
		||||
 | 
			
		||||
  const setTheme = (theme: 'light' | 'dark') => setMode(theme)
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    setMode(systemTheme === 'no-preference' ? 'light' : systemTheme)
 | 
			
		||||
  }, [systemTheme])
 | 
			
		||||
    setMode(currentMode)
 | 
			
		||||
  }, [currentMode])
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <ManageThemeContext.Provider
 | 
			
		||||
      value={{
 | 
			
		||||
        mode: mode,
 | 
			
		||||
        theme: getTheme(mode),
 | 
			
		||||
        toggle: toggleTheme
 | 
			
		||||
        setTheme: setTheme
 | 
			
		||||
      }}
 | 
			
		||||
    >
 | 
			
		||||
      {children}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user