diff --git a/App.tsx b/App.tsx
index 8ccbd27c..5117eb6a 100644
--- a/App.tsx
+++ b/App.tsx
@@ -28,22 +28,25 @@ setConsole({
const App: React.FC = () => {
return (
-
-
-
-
- {bootstrapped => {
- if (bootstrapped) {
- require('src/i18n/i18n')
- return
- } else {
- return <>>
- }
- }}
-
-
-
-
+
+
+
+ {bootstrapped => {
+ if (bootstrapped) {
+ console.log('Bootstrapped!')
+ require('src/i18n/i18n')
+ return (
+
+
+
+ )
+ } else {
+ return <>>
+ }
+ }}
+
+
+
)
}
diff --git a/src/Index.tsx b/src/Index.tsx
index 0a5f1a3f..9a1b6f22 100644
--- a/src/Index.tsx
+++ b/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 (
-
- ({
- 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
- }
- })}
- tabBarOptions={{
- activeTintColor: theme.primary,
- inactiveTintColor: theme.secondary,
- showLabel: false
- }}
- >
-
-
- ({
- tabPress: e => {
- e.preventDefault()
- navigation.navigate(getCurrentTab(navigation), {
- screen: 'Screen-Shared-Compose'
- })
+ <>
+
+
+ ({
+ 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
}
})}
+ tabBarOptions={{
+ activeTintColor: theme.primary,
+ inactiveTintColor: theme.secondary,
+ showLabel: false
+ }}
>
- {() => <>>}
-
-
-
-
+
+
+ ({
+ tabPress: e => {
+ e.preventDefault()
+ navigation.navigate(getCurrentTab(navigation), {
+ screen: 'Screen-Shared-Compose'
+ })
+ }
+ })}
+ >
+ {() => <>>}
+
+
+
+
- Toast.setRef(ref)} config={toastConfig} />
-
+ Toast.setRef(ref)} config={toastConfig} />
+
+ >
)
}
diff --git a/src/components/Timelines.tsx b/src/components/Timelines.tsx
index c6a84963..70f71a2d 100644
--- a/src/components/Timelines.tsx
+++ b/src/components/Timelines.tsx
@@ -44,7 +44,7 @@ export interface Props {
const Timelines: React.FC = ({ 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 = ({ name, content }) => {
headerCenter: () => (
= ({ 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 */}
diff --git a/src/components/Timelines/Timeline/Shared/HeaderDefault.tsx b/src/components/Timelines/Timeline/Shared/HeaderDefault.tsx
index 4f414491..ca0dcdee 100644
--- a/src/components/Timelines/Timeline/Shared/HeaderDefault.tsx
+++ b/src/components/Timelines/Timeline/Shared/HeaderDefault.tsx
@@ -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 = ({
emojis,
account,
created_at,
+ visibility,
application
}) => {
const { theme } = useTheme()
@@ -197,6 +199,14 @@ const HeaderDefault: React.FC = ({
{since}
+ {visibility === 'private' && (
+
+ )}
{application && application.name !== 'Web' && (
{
name='Screen-Me-Conversations'
component={ScreenMeConversations}
options={{
- headerTitle: t('headers.me.conversations')
+ headerTitle: t('meConversations:heading')
}}
/>
({
- headerTitle: t('headers.me.lists.list', { list: route.params.title })
+ headerTitle: t('meListsList:heading', { list: route.params.title })
})}
/>
diff --git a/src/screens/Me/Root.tsx b/src/screens/Me/Root.tsx
index acee40e6..bafd6340 100644
--- a/src/screens/Me/Root.tsx
+++ b/src/screens/Me/Root.tsx
@@ -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 (
{localRegistered ? : }
- {localRegistered && }
+ {localRegistered && }
{localRegistered && }
diff --git a/src/screens/Me/Root/MyCollections.tsx b/src/screens/Me/Root/Collections.tsx
similarity index 71%
rename from src/screens/Me/Root/MyCollections.tsx
rename to src/screens/Me/Root/Collections.tsx
index 59c4cdf5..506a0ad1 100644
--- a/src/screens/Me/Root/MyCollections.tsx
+++ b/src/screens/Me/Root/Collections.tsx
@@ -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 (
)
}
-export default MyInfo
+export default Collections
diff --git a/src/screens/Me/Root/Logout.tsx b/src/screens/Me/Root/Logout.tsx
index c247a34b..70b63ace 100644
--- a/src/screens/Me/Root/Logout.tsx
+++ b/src/screens/Me/Root/Logout.tsx
@@ -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 (
diff --git a/src/screens/Me/Root/Settings.tsx b/src/screens/Me/Root/Settings.tsx
index 37cc1f79..38d8232c 100644
--- a/src/screens/Me/Root/Settings.tsx
+++ b/src/screens/Me/Root/Settings.tsx
@@ -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 (
navigation.navigate('Screen-Me-Settings')}
/>
diff --git a/src/screens/Me/Settings.tsx b/src/screens/Me/Settings.tsx
index 95c8fed4..f84df789 100644
--- a/src/screens/Me/Settings.tsx
+++ b/src/screens/Me/Settings.tsx
@@ -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 (
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 = () => {
)
}
/>
+
+ 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
+ }
+ }
+ )
+ }
+ />
)
}
diff --git a/src/utils/slices/settingsSlice.ts b/src/utils/slices/settingsSlice.ts
index 047fddc1..ff821578 100644
--- a/src/utils/slices/settingsSlice.ts
+++ b/src/utils/slices/settingsSlice.ts
@@ -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>
) => {
state.language = action.payload
+ },
+ changeTheme: (
+ state,
+ action: PayloadAction>
+ ) => {
+ 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
diff --git a/src/utils/styles/ThemeManager.tsx b/src/utils/styles/ThemeManager.tsx
index b1d67293..13727a57 100644
--- a/src/utils/styles/ThemeManager.tsx
+++ b/src/utils/styles/ThemeManager.tsx
@@ -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({
+ 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 (
{children}