mirror of
https://github.com/tooot-app/app
synced 2025-02-20 22:00:49 +01:00
Now can scroll to top
This commit is contained in:
parent
ce7563ecbc
commit
c1076b8e94
6
App.tsx
6
App.tsx
@ -55,10 +55,12 @@ const App: React.FC = () => {
|
|||||||
<AppearanceProvider>
|
<AppearanceProvider>
|
||||||
<ReactQueryCacheProvider queryCache={queryCache}>
|
<ReactQueryCacheProvider queryCache={queryCache}>
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<PersistGate persistor={persistor}>
|
<PersistGate
|
||||||
|
persistor={persistor}
|
||||||
|
onBeforeLift={() => setAppLoaded(true)}
|
||||||
|
>
|
||||||
{bootstrapped => {
|
{bootstrapped => {
|
||||||
if (bootstrapped) {
|
if (bootstrapped) {
|
||||||
setAppLoaded(true)
|
|
||||||
require('@root/i18n/i18n')
|
require('@root/i18n/i18n')
|
||||||
return (
|
return (
|
||||||
<ThemeManager>
|
<ThemeManager>
|
||||||
|
@ -9,6 +9,7 @@ import { timelineFetch } from '@utils/fetches/timelineFetch'
|
|||||||
import TimelineSeparator from '@components/Timelines/Timeline/Separator'
|
import TimelineSeparator from '@components/Timelines/Timeline/Separator'
|
||||||
import TimelineEmpty from '@components/Timelines/Timeline/Empty'
|
import TimelineEmpty from '@components/Timelines/Timeline/Empty'
|
||||||
import TimelineEnd from '@components/Timelines/Timeline/Shared/End'
|
import TimelineEnd from '@components/Timelines/Timeline/Shared/End'
|
||||||
|
import { useScrollToTop } from '@react-navigation/native'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
page: App.Pages
|
page: App.Pages
|
||||||
@ -148,6 +149,8 @@ const Timeline: React.FC<Props> = ({
|
|||||||
)
|
)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
useScrollToTop(flRef)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FlatList
|
<FlatList
|
||||||
ref={flRef}
|
ref={flRef}
|
||||||
|
@ -31,27 +31,42 @@ const TimelineConversation: React.FC<Props> = ({
|
|||||||
)
|
)
|
||||||
|
|
||||||
const conversationChildren = useMemo(() => {
|
const conversationChildren = useMemo(() => {
|
||||||
return item.last_status && <TimelineContent status={item.last_status} />
|
return (
|
||||||
|
item.last_status && (
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
paddingTop: highlighted ? StyleConstants.Spacing.S : 0,
|
||||||
|
paddingLeft: highlighted
|
||||||
|
? 0
|
||||||
|
: StyleConstants.Avatar.S + StyleConstants.Spacing.S
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TimelineContent
|
||||||
|
status={item.last_status}
|
||||||
|
highlighted={highlighted}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.statusView}>
|
<View style={styles.conversationView}>
|
||||||
<View style={styles.status}>
|
<View style={styles.header}>
|
||||||
<TimelineAvatar account={item.accounts[0]} />
|
<TimelineAvatar account={item.accounts[0]} />
|
||||||
<View style={styles.details}>
|
<TimelineHeaderConversation
|
||||||
<TimelineHeaderConversation
|
queryKey={queryKey}
|
||||||
queryKey={queryKey}
|
id={item.id}
|
||||||
id={item.id}
|
account={item.accounts[0]}
|
||||||
account={item.accounts[0]}
|
created_at={item.last_status?.created_at}
|
||||||
created_at={item.last_status?.created_at}
|
/>
|
||||||
/>
|
|
||||||
<Pressable
|
|
||||||
onPress={conversationOnPress}
|
|
||||||
children={conversationChildren}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
<Pressable
|
||||||
|
onPress={conversationOnPress}
|
||||||
|
children={conversationChildren}
|
||||||
|
/>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
paddingLeft: highlighted
|
paddingLeft: highlighted
|
||||||
@ -66,18 +81,15 @@ const TimelineConversation: React.FC<Props> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
statusView: {
|
conversationView: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
flexDirection: 'column',
|
flexDirection: 'column',
|
||||||
padding: StyleConstants.Spacing.Global.PagePadding
|
padding: StyleConstants.Spacing.Global.PagePadding
|
||||||
},
|
},
|
||||||
status: {
|
header: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
width: '100%',
|
||||||
flexDirection: 'row'
|
flexDirection: 'row'
|
||||||
},
|
|
||||||
details: {
|
|
||||||
flex: 1,
|
|
||||||
flexGrow: 1
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -46,14 +46,12 @@ const TimelineDefault: React.FC<Props> = ({
|
|||||||
const tootChildren = useMemo(
|
const tootChildren = useMemo(
|
||||||
() => (
|
() => (
|
||||||
<View
|
<View
|
||||||
style={[
|
style={{
|
||||||
styles.content,
|
paddingTop: highlighted ? StyleConstants.Spacing.S : 0,
|
||||||
{
|
paddingLeft: highlighted
|
||||||
paddingLeft: highlighted
|
? 0
|
||||||
? 0
|
: StyleConstants.Avatar.S + StyleConstants.Spacing.S
|
||||||
: StyleConstants.Avatar.S + StyleConstants.Spacing.S
|
}}
|
||||||
}
|
|
||||||
]}
|
|
||||||
>
|
>
|
||||||
{actualStatus.content.length > 0 && (
|
{actualStatus.content.length > 0 && (
|
||||||
<TimelineContent status={actualStatus} highlighted={highlighted} />
|
<TimelineContent status={actualStatus} highlighted={highlighted} />
|
||||||
@ -75,10 +73,12 @@ const TimelineDefault: React.FC<Props> = ({
|
|||||||
{item.reblog && (
|
{item.reblog && (
|
||||||
<TimelineActioned action='reblog' account={item.account} />
|
<TimelineActioned action='reblog' account={item.account} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<View style={styles.header}>
|
<View style={styles.header}>
|
||||||
<TimelineAvatar account={actualStatus.account} />
|
<TimelineAvatar account={actualStatus.account} />
|
||||||
<TimelineHeaderDefault queryKey={queryKey} status={actualStatus} />
|
<TimelineHeaderDefault queryKey={queryKey} status={actualStatus} />
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
<Pressable onPress={tootOnPress} children={tootChildren} />
|
<Pressable onPress={tootOnPress} children={tootChildren} />
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
@ -102,9 +102,6 @@ const styles = StyleSheet.create({
|
|||||||
flex: 1,
|
flex: 1,
|
||||||
width: '100%',
|
width: '100%',
|
||||||
flexDirection: 'row'
|
flexDirection: 'row'
|
||||||
},
|
|
||||||
content: {
|
|
||||||
paddingTop: StyleConstants.Spacing.S
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -16,32 +16,49 @@ import { StyleConstants } from '@utils/styles/constants'
|
|||||||
export interface Props {
|
export interface Props {
|
||||||
notification: Mastodon.Notification
|
notification: Mastodon.Notification
|
||||||
queryKey: App.QueryKey
|
queryKey: App.QueryKey
|
||||||
|
highlighted?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const TimelineNotifications: React.FC<Props> = ({ notification, queryKey }) => {
|
const TimelineNotifications: React.FC<Props> = ({
|
||||||
|
notification,
|
||||||
|
queryKey,
|
||||||
|
highlighted = false
|
||||||
|
}) => {
|
||||||
const navigation = useNavigation()
|
const navigation = useNavigation()
|
||||||
const actualAccount = notification.status
|
const actualAccount = notification.status
|
||||||
? notification.status.account
|
? notification.status.account
|
||||||
: notification.account
|
: notification.account
|
||||||
const contentWidth =
|
const contentWidth = highlighted
|
||||||
Dimensions.get('window').width -
|
? Dimensions.get('window').width -
|
||||||
StyleConstants.Spacing.Global.PagePadding * 2 - // Global page padding on both sides
|
StyleConstants.Spacing.Global.PagePadding * 2 // Global page padding on both sides
|
||||||
StyleConstants.Avatar.S - // Avatar width
|
: Dimensions.get('window').width -
|
||||||
StyleConstants.Spacing.S // Avatar margin to the right
|
StyleConstants.Spacing.Global.PagePadding * 2 - // Global page padding on both sides
|
||||||
|
StyleConstants.Avatar.S - // Avatar width
|
||||||
|
StyleConstants.Spacing.S // Avatar margin to the right
|
||||||
|
|
||||||
const tootOnPress = useCallback(
|
const tootOnPress = useCallback(
|
||||||
() =>
|
() =>
|
||||||
navigation.navigate('Screen-Shared-Toot', {
|
navigation.navigate('Screen-Shared-Toot', {
|
||||||
toot: notification
|
toot: notification.status
|
||||||
}),
|
}),
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
const tootChildren = useMemo(
|
const tootChildren = useMemo(
|
||||||
() =>
|
() =>
|
||||||
notification.status ? (
|
notification.status ? (
|
||||||
<>
|
<View
|
||||||
|
style={{
|
||||||
|
paddingTop: highlighted ? StyleConstants.Spacing.S : 0,
|
||||||
|
paddingLeft: highlighted
|
||||||
|
? 0
|
||||||
|
: StyleConstants.Avatar.S + StyleConstants.Spacing.S
|
||||||
|
}}
|
||||||
|
>
|
||||||
{notification.status.content.length > 0 && (
|
{notification.status.content.length > 0 && (
|
||||||
<TimelineContent status={notification.status} />
|
<TimelineContent
|
||||||
|
status={notification.status}
|
||||||
|
highlighted={highlighted}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
{notification.status.poll && (
|
{notification.status.poll && (
|
||||||
<TimelinePoll queryKey={queryKey} status={notification.status} />
|
<TimelinePoll queryKey={queryKey} status={notification.status} />
|
||||||
@ -55,7 +72,7 @@ const TimelineNotifications: React.FC<Props> = ({ notification, queryKey }) => {
|
|||||||
{notification.status.card && (
|
{notification.status.card && (
|
||||||
<TimelineCard card={notification.status.card} />
|
<TimelineCard card={notification.status.card} />
|
||||||
)}
|
)}
|
||||||
</>
|
</View>
|
||||||
) : null,
|
) : null,
|
||||||
[notification.status?.poll?.voted]
|
[notification.status?.poll?.voted]
|
||||||
)
|
)
|
||||||
@ -68,33 +85,37 @@ const TimelineNotifications: React.FC<Props> = ({ notification, queryKey }) => {
|
|||||||
notification
|
notification
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<View style={styles.notification}>
|
<View style={styles.header}>
|
||||||
<TimelineAvatar account={actualAccount} />
|
<TimelineAvatar account={actualAccount} />
|
||||||
<View style={styles.details}>
|
<TimelineHeaderNotification notification={notification} />
|
||||||
<TimelineHeaderNotification notification={notification} />
|
|
||||||
<Pressable onPress={tootOnPress} children={tootChildren} />
|
|
||||||
{notification.status && (
|
|
||||||
<TimelineActions queryKey={queryKey} status={notification.status} />
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
<Pressable onPress={tootOnPress} children={tootChildren} />
|
||||||
|
|
||||||
|
{notification.status && (
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
paddingLeft: highlighted
|
||||||
|
? 0
|
||||||
|
: StyleConstants.Avatar.S + StyleConstants.Spacing.S
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TimelineActions queryKey={queryKey} status={notification.status} />
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
notificationView: {
|
notificationView: {
|
||||||
flex: 1,
|
padding: StyleConstants.Spacing.Global.PagePadding,
|
||||||
flexDirection: 'column',
|
paddingBottom: StyleConstants.Spacing.M
|
||||||
padding: StyleConstants.Spacing.Global.PagePadding
|
|
||||||
},
|
},
|
||||||
notification: {
|
header: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
|
width: '100%',
|
||||||
flexDirection: 'row'
|
flexDirection: 'row'
|
||||||
},
|
|
||||||
details: {
|
|
||||||
flex: 1,
|
|
||||||
flexGrow: 1
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from 'react'
|
import React, { useRef } from 'react'
|
||||||
import { ScrollView } from 'react-native'
|
import { ScrollView } from 'react-native'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
|
|
||||||
@ -9,12 +9,16 @@ import MyInfo from '@screens/Me/Root/MyInfo'
|
|||||||
import Collections from '@screens/Me/Root/Collections'
|
import Collections from '@screens/Me/Root/Collections'
|
||||||
import Settings from '@screens/Me/Root/Settings'
|
import Settings from '@screens/Me/Root/Settings'
|
||||||
import Logout from '@screens/Me/Root/Logout'
|
import Logout from '@screens/Me/Root/Logout'
|
||||||
|
import { useScrollToTop } from '@react-navigation/native'
|
||||||
|
|
||||||
const ScreenMeRoot: React.FC = () => {
|
const ScreenMeRoot: React.FC = () => {
|
||||||
const localRegistered = useSelector(getLocalUrl)
|
const localRegistered = useSelector(getLocalUrl)
|
||||||
|
|
||||||
|
const scrollRef = useRef<ScrollView>(null)
|
||||||
|
useScrollToTop(scrollRef)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollView keyboardShouldPersistTaps='handled'>
|
<ScrollView ref={scrollRef} keyboardShouldPersistTaps='handled'>
|
||||||
{localRegistered ? <MyInfo /> : <Login />}
|
{localRegistered ? <MyInfo /> : <Login />}
|
||||||
{localRegistered && <Collections />}
|
{localRegistered && <Collections />}
|
||||||
<Settings />
|
<Settings />
|
||||||
|
Loading…
x
Reference in New Issue
Block a user