1
0
mirror of https://github.com/tooot-app/app synced 2025-06-05 22:19:13 +02:00
This commit is contained in:
Zhiyuan Zheng
2021-02-01 02:16:53 +01:00
parent 1072d88191
commit b8aa402c99
20 changed files with 179 additions and 252 deletions

View File

@ -13,61 +13,59 @@ export interface Props {
fontBold?: boolean
}
const ParseEmojis: React.FC<Props> = ({
content,
emojis,
size = 'M',
fontBold = false
}) => {
const { mode, theme } = useTheme()
const styles = useMemo(() => {
return StyleSheet.create({
text: {
color: theme.primary,
...StyleConstants.FontStyle[size],
...(fontBold && { fontWeight: StyleConstants.Font.Weight.Bold })
},
image: {
width: StyleConstants.Font.Size[size],
height: StyleConstants.Font.Size[size],
transform: [{ translateY: size === 'L' ? -3 : -1 }]
}
})
}, [mode])
const ParseEmojis = React.memo(
({ content, emojis, size = 'M', fontBold = false }: Props) => {
const { mode, theme } = useTheme()
const styles = useMemo(() => {
return StyleSheet.create({
text: {
color: theme.primary,
...StyleConstants.FontStyle[size],
...(fontBold && { fontWeight: StyleConstants.Font.Weight.Bold })
},
image: {
width: StyleConstants.Font.Size[size],
height: StyleConstants.Font.Size[size],
transform: [{ translateY: size === 'L' ? -3 : -1 }]
}
})
}, [mode])
return (
<Text style={styles.text}>
{emojis ? (
content
.split(regexEmoji)
.filter(f => f)
.map((str, i) => {
if (str.match(regexEmoji)) {
const emojiShortcode = str.split(regexEmoji)[1]
const emojiIndex = emojis.findIndex(emoji => {
return emojiShortcode === `:${emoji.shortcode}:`
})
return emojiIndex === -1 ? (
<Text key={i}>{emojiShortcode}</Text>
) : (
<Text key={i}>
{/* When emoji starts a paragraph, lineHeight will break */}
{i === 0 ? <Text> </Text> : null}
<FastImage
source={{ uri: emojis[emojiIndex].url }}
style={styles.image}
/>
</Text>
)
} else {
return <Text key={i}>{str}</Text>
}
})
) : (
<Text>{content}</Text>
)}
</Text>
)
}
return (
<Text style={styles.text}>
{emojis ? (
content
.split(regexEmoji)
.filter(f => f)
.map((str, i) => {
if (str.match(regexEmoji)) {
const emojiShortcode = str.split(regexEmoji)[1]
const emojiIndex = emojis.findIndex(emoji => {
return emojiShortcode === `:${emoji.shortcode}:`
})
return emojiIndex === -1 ? (
<Text key={i}>{emojiShortcode}</Text>
) : (
<Text key={i}>
{/* When emoji starts a paragraph, lineHeight will break */}
{i === 0 ? <Text> </Text> : null}
<FastImage
source={{ uri: emojis[emojiIndex].url }}
style={styles.image}
/>
</Text>
)
} else {
return <Text key={i}>{str}</Text>
}
})
) : (
<Text>{content}</Text>
)}
</Text>
)
},
(prev, next) => prev.content === next.content
)
export default React.memo(ParseEmojis, () => true)
export default ParseEmojis

View File

@ -30,8 +30,8 @@ const renderNode = ({
theme: any
node: any
index: number
size: 'M' | 'L'
navigation: StackNavigationProp<Nav.LocalStackParamList>
size: 'S' | 'M' | 'L'
navigation: StackNavigationProp<Nav.TabLocalStackParamList>
mentions?: Mastodon.Mention[]
tags?: Mastodon.Tag[]
showFullLink: boolean
@ -145,7 +145,7 @@ const renderNode = ({
export interface Props {
content: string
size?: 'M' | 'L'
size?: 'S' | 'M' | 'L'
emojis?: Mastodon.Emoji[]
mentions?: Mastodon.Mention[]
tags?: Mastodon.Tag[]
@ -167,7 +167,7 @@ const ParseHTML: React.FC<Props> = ({
disableDetails = false
}) => {
const navigation = useNavigation<
StackNavigationProp<Nav.LocalStackParamList>
StackNavigationProp<Nav.TabLocalStackParamList>
>()
const route = useRoute()
const { theme } = useTheme()

View File

@ -82,11 +82,10 @@ const Timeline: React.FC<Props> = ({
const navigation = useNavigation()
useEffect(() => {
const unsubscribe = navigation.addListener('focus', props => {
if (props.target && props.target.includes('Screen-Notifications-Root')) {
if (props.target && props.target.includes('Tab-Notifications-Root')) {
if (flattenData.length) {
dispatch(
localUpdateNotification({
unread: false,
latestTime: (flattenData[0] as Mastodon.Notification).created_at
})
)

View File

@ -47,6 +47,6 @@ export default {
heading: 'Help us improve',
description: 'Collecting only non-user relative usage'
},
version: 'Version v{{version}}'
version: 'Version v{{version}} ({{releaseChannel}})'
}
}

View File

@ -47,6 +47,6 @@ export default {
heading: '帮助我们改进',
description: '收集不与用户相关联的使用信息'
},
version: '版本 v{{version}}'
version: '版本 v{{version}} ({{releaseChannel}})'
}
}

View File

@ -90,7 +90,7 @@ const ScreenTabs: React.FC<ScreenTabsProp> = ({ navigation }) => {
}),
[localActiveIndex, localAccount]
)
const tabNavigatorTabBarOptions = useMemo(
const tabBarOptions = useMemo(
() => ({
activeTintColor: theme.primary,
inactiveTintColor:
@ -100,7 +100,7 @@ const ScreenTabs: React.FC<ScreenTabsProp> = ({ navigation }) => {
}),
[theme, localActiveIndex]
)
const tabScreenLocalListeners = useCallback(
const localListeners = useCallback(
() => ({
tabPress: (e: any) => {
if (!(localActiveIndex !== null)) {
@ -110,7 +110,7 @@ const ScreenTabs: React.FC<ScreenTabsProp> = ({ navigation }) => {
}),
[localActiveIndex]
)
const tabScreenComposeListeners = useMemo(
const composeListeners = useMemo(
() => ({
tabPress: (e: any) => {
e.preventDefault()
@ -122,8 +122,8 @@ const ScreenTabs: React.FC<ScreenTabsProp> = ({ navigation }) => {
}),
[localActiveIndex]
)
const tabScreenComposeComponent = useCallback(() => null, [])
const tabScreenNotificationsListeners = useCallback(
const composeComponent = useCallback(() => null, [])
const notificationsListeners = useCallback(
() => ({
tabPress: (e: any) => {
if (!(localActiveIndex !== null)) {
@ -144,66 +144,67 @@ const ScreenTabs: React.FC<ScreenTabsProp> = ({ navigation }) => {
}
})
const prevNotification = useSelector(getLocalNotification)
useEffect(() => {
if (queryNotification.data?.pages) {
const flattenData = queryNotification.data.pages.flatMap(d => [...d])
const latestNotificationTime = flattenData.length
? (flattenData[0] as Mastodon.Notification).created_at
: undefined
const notificationsOptions = useMemo(() => {
const badge = {
show: {
tabBarBadge: '',
tabBarBadgeStyle: {
transform: [{ scale: 0.5 }],
backgroundColor: theme.red
}
},
hide: {
tabBarBadgeStyle: {
transform: [{ scale: 0.5 }],
backgroundColor: theme.red
}
}
}
const flattenData = queryNotification.data?.pages.flatMap(d => [...d])
const latestNotificationTime = flattenData?.length
? (flattenData[0] as Mastodon.Notification).created_at
: undefined
if (!prevNotification || !prevNotification.latestTime) {
dispatch(localUpdateNotification({ unread: false }))
} else if (
if (prevNotification?.latestTime) {
if (
latestNotificationTime &&
new Date(prevNotification.latestTime) < new Date(latestNotificationTime)
) {
dispatch(
localUpdateNotification({
unread: true,
latestTime: latestNotificationTime
})
)
return badge.show
} else {
return badge.hide
}
} else {
if (latestNotificationTime) {
return badge.show
} else {
return badge.hide
}
}
}, [queryNotification.data?.pages])
}, [prevNotification, queryNotification.data?.pages])
return (
<Tab.Navigator
initialRouteName={localActiveIndex !== null ? 'Tab-Local' : 'Tab-Me'}
screenOptions={screenOptions}
tabBarOptions={tabNavigatorTabBarOptions}
tabBarOptions={tabBarOptions}
>
<Tab.Screen
name='Tab-Local'
component={TabLocal}
listeners={tabScreenLocalListeners}
listeners={localListeners}
/>
<Tab.Screen name='Tab-Public' component={TabPublic} />
<Tab.Screen
name='Tab-Compose'
component={tabScreenComposeComponent}
listeners={tabScreenComposeListeners}
component={composeComponent}
listeners={composeListeners}
/>
<Tab.Screen
name='Tab-Notifications'
component={TabNotifications}
listeners={tabScreenNotificationsListeners}
options={
prevNotification && prevNotification.unread
? {
tabBarBadge: '',
tabBarBadgeStyle: {
transform: [{ scale: 0.5 }],
backgroundColor: theme.red
}
}
: {
tabBarBadgeStyle: {
transform: [{ scale: 0.5 }],
backgroundColor: theme.red
}
}
}
listeners={notificationsListeners}
options={notificationsOptions}
/>
<Tab.Screen name='Tab-Me' component={TabMe} />
</Tab.Navigator>

View File

@ -29,7 +29,10 @@ const SettingsAnalytics: React.FC = () => {
}
/>
<Text style={[styles.version, { color: theme.secondary }]}>
{t('content.version', { version: Constants.manifest.version })}
{t('content.version', {
version: Constants.manifest.version,
releaseChannel: Constants.manifest.releaseChannel || 'dev'
})}
</Text>
</MenuContainer>
)

View File

@ -75,7 +75,7 @@ const AccountInformation: React.FC<Props> = ({ account, myInfo = false }) => {
const styles = StyleSheet.create({
base: {
marginTop: -StyleConstants.Spacing.Global.PagePadding * 3,
marginTop: -StyleConstants.Avatar.L / 2,
padding: StyleConstants.Spacing.Global.PagePadding
},
avatarAndActions: {

View File

@ -25,7 +25,7 @@ const AccountInformationFields = React.memo(
>
<ParseHTML
content={field.name}
size={'M'}
size={'S'}
emojis={account.emojis}
showFullLink
numberOfLines={5}
@ -42,7 +42,7 @@ const AccountInformationFields = React.memo(
<View style={styles.fieldRight}>
<ParseHTML
content={field.value}
size={'M'}
size={'S'}
emojis={account.emojis}
showFullLink
numberOfLines={5}

View File

@ -20,7 +20,6 @@ export type InstanceLocal = {
preferences: Mastodon.Preferences
}
notification: {
unread: boolean
latestTime?: Mastodon.Notification['created_at']
}
}
@ -115,7 +114,7 @@ export const localAddInstance = createAsyncThunk(
preferences
},
notification: {
unread: false
latestTime: undefined
}
}
})
@ -203,10 +202,8 @@ const instancesSlice = createSlice({
state,
action: PayloadAction<Partial<InstanceLocal['notification']>>
) => {
state.local.instances[state.local.activeIndex!].notification = {
...state.local.instances[state.local.activeIndex!].notification,
...action.payload
}
state.local.instances[state.local.activeIndex!].notification =
action.payload
},
remoteUpdate: (
state,