mirror of
https://github.com/tooot-app/app
synced 2025-02-18 04:40:57 +01:00
Notifications working
This commit is contained in:
parent
c8b40017d8
commit
8f6c5af0fd
@ -5,6 +5,7 @@ import { enableScreens } from 'react-native-screens'
|
||||
enableScreens()
|
||||
|
||||
import React from 'react'
|
||||
import { Feather } from '@expo/vector-icons'
|
||||
import store from 'src/stacks/common/store'
|
||||
import { Provider } from 'react-redux'
|
||||
import { StatusBar } from 'expo-status-bar'
|
||||
@ -21,10 +22,39 @@ export default function Index () {
|
||||
<Provider store={store}>
|
||||
<StatusBar style='auto' />
|
||||
<NavigationContainer>
|
||||
<Tab.Navigator>
|
||||
<Tab.Navigator
|
||||
screenOptions={({ route }) => ({
|
||||
tabBarIcon: ({ focused, color, size }) => {
|
||||
let name
|
||||
switch (route.name) {
|
||||
case 'Local':
|
||||
name = 'home'
|
||||
break
|
||||
case 'Public':
|
||||
name = 'globe'
|
||||
break
|
||||
case 'Post':
|
||||
name = 'plus'
|
||||
break
|
||||
case 'Notifications':
|
||||
name = 'bell'
|
||||
break
|
||||
case 'Me':
|
||||
name = focused ? 'smile' : 'meh'
|
||||
break
|
||||
}
|
||||
return <Feather name={name} size={size} color={color} />
|
||||
}
|
||||
})}
|
||||
tabBarOptions={{
|
||||
activeTintColor: 'black',
|
||||
inactiveTintColor: 'gray',
|
||||
showLabel: false
|
||||
}}
|
||||
>
|
||||
<Tab.Screen name='Local' component={Local} />
|
||||
<Tab.Screen name='Public' component={Public} />
|
||||
{/* <Tab.Screen name='Notifications' component={Notifications} /> */}
|
||||
<Tab.Screen name='Notifications' component={Notifications} />
|
||||
<Tab.Screen name='Me' component={Me} />
|
||||
</Tab.Navigator>
|
||||
</NavigationContainer>
|
||||
|
@ -5,7 +5,7 @@ import HTML from 'react-native-render-html'
|
||||
|
||||
import relativeTime from 'src/utils/relativeTime'
|
||||
|
||||
export default function TootTimeline ({ item }) {
|
||||
export default function TootTimeline ({ item, notification }) {
|
||||
return (
|
||||
<View style={styles.tootTimeline}>
|
||||
<View style={styles.header}>
|
||||
@ -36,7 +36,13 @@ export default function TootTimeline ({ item }) {
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
{item.content ? <HTML html={item.content} /> : <></>}
|
||||
{notification ? (
|
||||
<HTML html={item.status.content} />
|
||||
) : item.content ? (
|
||||
<HTML html={item.content} />
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@ -54,7 +60,8 @@ TootTimeline.propTypes = {
|
||||
website: PropTypes.string
|
||||
}),
|
||||
content: PropTypes.string
|
||||
}).isRequired
|
||||
}).isRequired,
|
||||
notification: PropTypes.bool
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
|
@ -5,6 +5,7 @@ import TimelinesCombined from 'src/stacks/common/TimelinesCombined'
|
||||
export default function Local () {
|
||||
return (
|
||||
<TimelinesCombined
|
||||
page='Local'
|
||||
route={[
|
||||
{ title: '关注', timeline: { endpoint: 'home' } },
|
||||
{ title: '本站', timeline: { endpoint: 'public', local: true } }
|
||||
|
@ -1,9 +1,33 @@
|
||||
import React, { useEffect } from 'react'
|
||||
import { ActivityIndicator, FlatList, View } from 'react-native'
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { createNativeStackNavigator } from 'react-native-screens/native-stack'
|
||||
import { Feather } from '@expo/vector-icons'
|
||||
|
||||
import TootTimeline from 'src/components/TootTimeline'
|
||||
import Timeline from 'src/stacks/common/Timeline'
|
||||
|
||||
const Stack = createNativeStackNavigator()
|
||||
|
||||
export default function Notifications () {
|
||||
return <View></View>
|
||||
const [renderHeader, setRenderHeader] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
const nbr = setTimeout(() => setRenderHeader(true), 50)
|
||||
return
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Stack.Navigator
|
||||
screenOptions={{
|
||||
statusBarAnimation: 'none',
|
||||
headerRight: () =>
|
||||
renderHeader ? (
|
||||
<Feather name='search' size={24} color='black' />
|
||||
) : null,
|
||||
headerTitle: '通知'
|
||||
}}
|
||||
>
|
||||
<Stack.Screen name='Notifications'>
|
||||
{props => <Timeline endpoint='notifications' {...props} />}
|
||||
</Stack.Screen>
|
||||
</Stack.Navigator>
|
||||
)
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import TimelinesCombined from 'src/stacks/common/TimelinesCombined'
|
||||
export default function Public () {
|
||||
return (
|
||||
<TimelinesCombined
|
||||
page='Public'
|
||||
route={[
|
||||
{ title: '跨站', timeline: { endpoint: 'public' } },
|
||||
{ title: '他站', timeline: { remote: true } }
|
||||
|
@ -1,11 +1,61 @@
|
||||
import PropTypes from 'prop-types'
|
||||
import React, { useEffect } from 'react'
|
||||
import { ActivityIndicator, FlatList, View } from 'react-native'
|
||||
import { connect, useSelector, useDispatch } from 'react-redux'
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
|
||||
import TootTimeline from 'src/components/TootTimeline'
|
||||
import { fetch, getToots, getStatus } from './timelineSlice'
|
||||
|
||||
const Default = ({ toots, status, remote, endpoint, local }) => {
|
||||
return (
|
||||
<>
|
||||
<FlatList
|
||||
data={toots}
|
||||
keyExtractor={({ id }) => id}
|
||||
renderItem={TootTimeline}
|
||||
onRefresh={() =>
|
||||
dispatch(
|
||||
fetch({ remote, endpoint, local, id: toots[0].id, newer: true })
|
||||
)
|
||||
}
|
||||
refreshing={status === 'loading'}
|
||||
onEndReached={() =>
|
||||
dispatch(
|
||||
fetch({ remote, endpoint, local, id: toots[toots.length - 1].id })
|
||||
)
|
||||
}
|
||||
onEndReachedThreshold={0.5}
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
/>
|
||||
{status === 'loading' && <ActivityIndicator />}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const Notifications = ({ toots, status, endpoint }) => {
|
||||
return (
|
||||
<>
|
||||
<FlatList
|
||||
data={toots}
|
||||
keyExtractor={({ status: { id } }) => id}
|
||||
renderItem={({ item }) => (
|
||||
<TootTimeline item={item} notification={true} />
|
||||
)}
|
||||
// onRefresh={() =>
|
||||
// dispatch(fetch({ endpoint, id: toots[0].status.id, newer: true }))
|
||||
// }
|
||||
// refreshing={status === 'loading'}
|
||||
// onEndReached={() =>
|
||||
// dispatch(fetch({ endpoint, id: toots[toots.length - 1].status.id }))
|
||||
// }
|
||||
onEndReachedThreshold={0.5}
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
/>
|
||||
{status === 'loading' && <ActivityIndicator />}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default function Timeline ({ remote, endpoint, local }) {
|
||||
const dispatch = useDispatch()
|
||||
const toots = useSelector(state =>
|
||||
@ -20,34 +70,26 @@ export default function Timeline ({ remote, endpoint, local }) {
|
||||
dispatch(fetch({ remote, endpoint, local }))
|
||||
}
|
||||
}, [status, dispatch])
|
||||
let content
|
||||
|
||||
let content
|
||||
if (status === 'error') {
|
||||
content = <Text>Error message</Text>
|
||||
} else {
|
||||
content = (
|
||||
<>
|
||||
<FlatList
|
||||
data={toots}
|
||||
keyExtractor={({ id }) => id}
|
||||
renderItem={TootTimeline}
|
||||
onRefresh={() =>
|
||||
dispatch(
|
||||
fetch({ remote, endpoint, local, id: toots[0].id, newer: true })
|
||||
)
|
||||
}
|
||||
refreshing={status === 'loading'}
|
||||
onEndReached={() =>
|
||||
dispatch(
|
||||
fetch({ remote, endpoint, local, id: toots[toots.length - 1].id })
|
||||
)
|
||||
}
|
||||
onEndReachedThreshold={0.5}
|
||||
style={{ height: '100%', width: '100%' }}
|
||||
if (endpoint === 'notifications') {
|
||||
content = (
|
||||
<Notifications toots={toots} status={status} endpoint={endpoint} />
|
||||
)
|
||||
} else {
|
||||
content = (
|
||||
<Default
|
||||
toots={toots}
|
||||
status={status}
|
||||
remote={remote}
|
||||
endpoint={endpoint}
|
||||
local={local}
|
||||
/>
|
||||
{status === 'loading' && <ActivityIndicator />}
|
||||
</>
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return <View>{content}</View>
|
||||
|
@ -9,7 +9,7 @@ import Timeline from './Timeline'
|
||||
|
||||
const Stack = createNativeStackNavigator()
|
||||
|
||||
export default function TimelinesCombined ({ route }) {
|
||||
export default function TimelinesCombined ({ page, route }) {
|
||||
const [segment, setSegment] = useState(0)
|
||||
const [renderHeader, setRenderHeader] = useState(false)
|
||||
|
||||
@ -48,7 +48,7 @@ export default function TimelinesCombined ({ route }) {
|
||||
) : null
|
||||
}}
|
||||
>
|
||||
<Stack.Screen name='LocalView'>
|
||||
<Stack.Screen name={page}>
|
||||
{props => (
|
||||
<Animated.View
|
||||
style={{
|
||||
|
@ -6,8 +6,8 @@ import timelineSlice from 'src/stacks/common/timelineSlice'
|
||||
// get site information from local storage and pass to reducers
|
||||
const preloadedState = {
|
||||
instanceInfo: {
|
||||
current: 'social.xmflsct.com',
|
||||
currentToken: 'qjzJ0IjvZ1apsn0_wBkGcdjKgX7Dao9KEPhGwggPwAo',
|
||||
current: 'm.cmx.im',
|
||||
currentToken: 'Cxx19XX2VNHnPy_dr_HCHMh4HvwHEvYwWrrU3r3BNzQ',
|
||||
remote: 'mastodon.social'
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import { client } from 'src/api/client'
|
||||
// Local: public/local
|
||||
// CurrentPublic: public
|
||||
// RemotePublic: remote
|
||||
// Notifications: notifications
|
||||
|
||||
const checkInstance = ({ remote, endpoint, local }) =>
|
||||
remote ? 'remote' : `${endpoint}${local ? '/local' : ''}`
|
||||
@ -16,6 +17,8 @@ export const fetch = createAsyncThunk(
|
||||
async ({ remote, endpoint, local, id, newer }, { getState }) => {
|
||||
const instance = remote
|
||||
? `${getState().instanceInfo.remote}/api/v1/timelines/public`
|
||||
: endpoint === 'notifications'
|
||||
? `${getState().instanceInfo.current}/api/v1/${endpoint}`
|
||||
: `${getState().instanceInfo.current}/api/v1/timelines/${endpoint}`
|
||||
|
||||
const query = {
|
||||
@ -58,6 +61,10 @@ export const timelineSlice = createSlice({
|
||||
remote: {
|
||||
toots: [],
|
||||
status: 'idle'
|
||||
},
|
||||
notifications: {
|
||||
toots: [],
|
||||
status: 'idle'
|
||||
}
|
||||
},
|
||||
extraReducers: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user