1
0
mirror of https://github.com/tooot-app/app synced 2025-06-05 22:19:13 +02:00

Lots of updates

This commit is contained in:
Zhiyuan Zheng
2020-11-24 00:18:47 +01:00
parent fba1d0d531
commit 8200375c92
23 changed files with 378 additions and 152 deletions

View File

@ -0,0 +1,74 @@
import React from 'react'
import {
Alert,
AlertButton,
AlertOptions,
Pressable,
StyleSheet,
Text,
View
} from 'react-native'
import { useTheme } from 'src/utils/styles/ThemeManager'
import constants from 'src/utils/styles/constants'
export interface Props {
text: string
destructive?: boolean
alertOption?: {
title: string
message?: string | undefined
buttons?: AlertButton[] | undefined
options?: AlertOptions | undefined
}
}
const Core: React.FC<Props> = ({ text, destructive = false }) => {
const { theme } = useTheme()
return (
<View style={styles.core}>
<Text style={{ color: destructive ? theme.dangerous : theme.primary }}>
{text}
</Text>
</View>
)
}
const MenuButton: React.FC<Props> = ({ ...props }) => {
const { theme } = useTheme()
return (
<Pressable
style={[styles.base, { borderBottomColor: theme.separator }]}
onPress={() =>
props.alertOption &&
Alert.alert(
props.alertOption.title,
props.alertOption.message,
props.alertOption.buttons,
props.alertOption.options
)
}
>
<Core {...props} />
</Pressable>
)
}
const styles = StyleSheet.create({
base: {
height: 50,
borderBottomWidth: 1
},
core: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
paddingLeft: constants.GLOBAL_PAGE_PADDING,
paddingRight: constants.GLOBAL_PAGE_PADDING
}
})
export default MenuButton

View File

@ -1,8 +1,24 @@
import React from 'react'
import { View } from 'react-native'
import { StyleSheet, View } from 'react-native'
import { useTheme } from 'src/utils/styles/ThemeManager'
import constants from 'src/utils/styles/constants'
const MenuContainer: React.FC = ({ ...props }) => {
return <View>{props.children}</View>
const { theme } = useTheme()
return (
<View style={[styles.base, { borderTopColor: theme.separator }]}>
{props.children}
</View>
)
}
const styles = StyleSheet.create({
base: {
borderTopWidth: 1,
marginBottom: constants.SPACING_M
}
})
export default MenuContainer

View File

@ -4,6 +4,8 @@ import { useNavigation } from '@react-navigation/native'
import { Feather } from '@expo/vector-icons'
import { useTheme } from 'src/utils/styles/ThemeManager'
import constants from 'src/utils/styles/constants'
export interface Props {
icon?: string
title: string
@ -16,8 +18,17 @@ const Core: React.FC<Props> = ({ icon, title, navigateTo }) => {
return (
<View style={styles.core}>
{icon && <Feather name={icon} size={24} style={styles.iconLeading} />}
<Text>{title}</Text>
{icon && (
<Feather
name={icon}
size={constants.FONT_SIZE_M + 2}
style={styles.iconLeading}
color={theme.primary}
/>
)}
<Text style={{ color: theme.primary, fontSize: constants.FONT_SIZE_M }}>
{title}
</Text>
{navigateTo && (
<Feather
name='chevron-right'
@ -31,11 +42,12 @@ const Core: React.FC<Props> = ({ icon, title, navigateTo }) => {
}
const MenuItem: React.FC<Props> = ({ ...props }) => {
const { theme } = useTheme()
const navigation = useNavigation()
return props.navigateTo ? (
<Pressable
style={styles.base}
style={[styles.base, { borderBottomColor: theme.separator }]}
onPress={() => {
navigation.navigate(props.navigateTo!, props.navigateToParams)
}}
@ -52,15 +64,14 @@ const MenuItem: React.FC<Props> = ({ ...props }) => {
const styles = StyleSheet.create({
base: {
height: 50,
borderBottomColor: 'lightgray',
borderBottomWidth: 1
},
core: {
flex: 1,
flexDirection: 'row',
alignItems: 'center',
paddingLeft: 12,
paddingRight: 12
paddingLeft: constants.GLOBAL_PAGE_PADDING,
paddingRight: constants.GLOBAL_PAGE_PADDING
},
iconLeading: {
marginRight: 8

View File

@ -0,0 +1,8 @@
import React from 'react'
import { Text } from 'react-native'
const PleaseLogin = () => {
return <Text></Text>
}
export default PleaseLogin

View File

@ -7,9 +7,12 @@ import { Feather } from '@expo/vector-icons'
import Timeline from './Timelines/Timeline'
import sharedScreens from 'src/screens/Shared/sharedScreens'
import { InstancesState } from 'src/utils/slices/instancesSlice'
import { RootState } from 'src/store'
import { getRemoteUrl, InstancesState } from 'src/utils/slices/instancesSlice'
import { RootState, store } from 'src/store'
import { useTheme } from 'src/utils/styles/ThemeManager'
import { useNavigation } from '@react-navigation/native'
import getCurrentTab from 'src/utils/getCurrentTab'
import PleaseLogin from './PleaseLogin'
const Stack = createNativeStackNavigator()
@ -25,22 +28,24 @@ const Page = ({
{localRegistered || page === 'RemotePublic' ? (
<Timeline page={page} />
) : (
<Text></Text>
<PleaseLogin />
)}
</View>
)
}
export interface Props {
name: string
name: 'Screen-Local-Root' | 'Screen-Public-Root'
content: { title: string; page: App.Pages }[]
}
const Timelines: React.FC<Props> = ({ name, content }) => {
const navigation = useNavigation()
const { theme } = useTheme()
const localRegistered = useSelector(
(state: RootState) => state.instances.local.url
)
const publicDomain = getRemoteUrl(store.getState())
const [segment, setSegment] = useState(0)
const [renderHeader, setRenderHeader] = useState(false)
const [segmentManuallyTriggered, setSegmentManuallyTriggered] = useState(
@ -59,58 +64,80 @@ const Timelines: React.FC<Props> = ({ name, content }) => {
<Stack.Screen
name={name}
options={{
headerRight: () =>
renderHeader ? (
<Feather name='search' size={24} color={theme.secondary} />
) : null,
headerCenter: () =>
renderHeader ? (
<SegmentedControl
values={[content[0].title, content[1].title]}
selectedIndex={segment}
onChange={({ nativeEvent }) => {
setSegmentManuallyTriggered(true)
setSegment(nativeEvent.selectedSegmentIndex)
horizontalPaging.current.scrollToIndex({
index: nativeEvent.selectedSegmentIndex
})
}}
style={{ width: 150, height: 30 }}
/>
) : null
headerTitle: name === 'Screen-Public-Root' ? publicDomain : '',
...(renderHeader &&
localRegistered && {
headerCenter: () => (
<SegmentedControl
values={[content[0].title, content[1].title]}
selectedIndex={segment}
onChange={({ nativeEvent }) => {
setSegmentManuallyTriggered(true)
setSegment(nativeEvent.selectedSegmentIndex)
horizontalPaging.current.scrollToIndex({
index: nativeEvent.selectedSegmentIndex
})
}}
style={{ width: 150, height: 30 }}
/>
),
headerRight: () => (
<Feather
name='search'
size={24}
color={theme.secondary}
onPress={() => {
navigation.navigate(getCurrentTab(navigation), {
screen: 'Screen-Shared-Search'
})
}}
/>
)
})
}}
>
{() => (
<FlatList
style={{ width: Dimensions.get('window').width, height: '100%' }}
data={content}
extraData={localRegistered}
keyExtractor={({ page }) => page}
renderItem={({ item, index }) => (
<Page key={index} item={item} localRegistered={localRegistered} />
)}
ref={horizontalPaging}
bounces={false}
getItemLayout={(data, index) => ({
length: Dimensions.get('window').width,
offset: Dimensions.get('window').width * index,
index
})}
horizontal
onMomentumScrollEnd={() => setSegmentManuallyTriggered(false)}
onScroll={({ nativeEvent }) =>
!segmentManuallyTriggered &&
setSegment(
nativeEvent.contentOffset.x <=
Dimensions.get('window').width / 2
? 0
: 1
)
}
pagingEnabled
showsHorizontalScrollIndicator={false}
/>
)}
{() => {
return (
<FlatList
style={{ width: Dimensions.get('window').width, height: '100%' }}
data={content}
extraData={localRegistered}
keyExtractor={({ page }) => page}
renderItem={({ item, index }) => {
if (!localRegistered && index === 0) {
return null
}
return (
<Page
key={index}
item={item}
localRegistered={localRegistered}
/>
)
}}
ref={horizontalPaging}
bounces={false}
getItemLayout={(data, index) => ({
length: Dimensions.get('window').width,
offset: Dimensions.get('window').width * index,
index
})}
horizontal
onMomentumScrollEnd={() => setSegmentManuallyTriggered(false)}
onScroll={({ nativeEvent }) =>
!segmentManuallyTriggered &&
setSegment(
nativeEvent.contentOffset.x <=
Dimensions.get('window').width / 2
? 0
: 1
)
}
pagingEnabled
showsHorizontalScrollIndicator={false}
/>
)
}}
</Stack.Screen>
{sharedScreens(Stack)}

View File

@ -13,7 +13,8 @@ const TimelineSeparator = () => {
const styles = StyleSheet.create({
base: {
borderTopWidth: 1,
marginLeft: constants.SPACING_M + constants.AVATAR_S + constants.SPACING_S
marginLeft: constants.SPACING_M + constants.AVATAR_S + constants.SPACING_S,
marginRight: constants.SPACING_M
}
})

View File

@ -2,6 +2,8 @@ import React from 'react'
import { Image, StyleSheet, Text } from 'react-native'
import { useTheme } from 'src/utils/styles/ThemeManager'
import constants from 'src/utils/styles/constants'
const regexEmoji = new RegExp(/(:[a-z0-9_]+:)/)
export interface Props {
@ -23,7 +25,7 @@ const Emojis: React.FC<Props> = ({
fontSize: size,
lineHeight: size + 2,
color: theme.primary,
...(fontBold && { fontWeight: 'bold' })
...(fontBold && { fontWeight: constants.FONT_WEIGHT_BOLD })
},
image: {
width: size,