All timelines working

This commit is contained in:
Zhiyuan Zheng 2020-10-24 16:44:32 +02:00
parent cda67d23f6
commit c8b40017d8
No known key found for this signature in database
GPG Key ID: 078A93AB607D85E0
13 changed files with 132 additions and 60 deletions

5
package-lock.json generated
View File

@ -1687,6 +1687,11 @@
"resolved": "https://registry.npmjs.org/@react-native-community/masked-view/-/masked-view-0.1.10.tgz",
"integrity": "sha512-rk4sWFsmtOw8oyx8SD3KSvawwaK7gRBSEIy2TAwURyGt+3TizssXP1r8nx3zY+R7v2vYYHXZ+k2/GULAT/bcaQ=="
},
"@react-native-community/segmented-control": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@react-native-community/segmented-control/-/segmented-control-2.1.1.tgz",
"integrity": "sha512-vSrg+DIqX0zGeOb1o6oFLoWFFW8l1UEX/f7/9dXXzWHChF3rIqEpNHC4ONmsLJqWePN4E/n+k+q29z+GbqrqsQ=="
},
"@react-navigation/bottom-tabs": {
"version": "5.9.2",
"resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-5.9.2.tgz",

View File

@ -28,7 +28,9 @@
"react-native-screens": "~2.10.1",
"react-native-web": "~0.13.7",
"react-native-webview": "10.7.0",
"react-redux": "^7.2.1"
"react-redux": "^7.2.1",
"@react-native-community/segmented-control": "2.1.1",
"@expo/vector-icons": "^10.0.0"
},
"devDependencies": {
"@babel/core": "~7.9.0",

View File

@ -9,7 +9,7 @@ import store from 'src/stacks/common/store'
import { Provider } from 'react-redux'
import { StatusBar } from 'expo-status-bar'
import Main from 'src/stacks/Main'
import Local from 'src/stacks/Local'
import Public from 'src/stacks/Public'
import Notifications from 'src/stacks/Notifications'
import Me from 'src/stacks/Me'
@ -22,7 +22,7 @@ export default function Index () {
<StatusBar style='auto' />
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name='Main' component={Main} />
<Tab.Screen name='Local' component={Local} />
<Tab.Screen name='Public' component={Public} />
{/* <Tab.Screen name='Notifications' component={Notifications} /> */}
<Tab.Screen name='Me' component={Me} />

14
src/stacks/Local.jsx Normal file
View File

@ -0,0 +1,14 @@
import React from 'react'
import TimelinesCombined from 'src/stacks/common/TimelinesCombined'
export default function Local () {
return (
<TimelinesCombined
route={[
{ title: '关注', timeline: { endpoint: 'home' } },
{ title: '本站', timeline: { endpoint: 'public', local: true } }
]}
/>
)
}

View File

@ -1,14 +0,0 @@
import React from 'react'
import { createNativeStackNavigator } from 'react-native-screens/native-stack'
import Following from 'src/stacks/Main/Following'
const MainStack = createNativeStackNavigator()
export default function Main () {
return (
<MainStack.Navigator>
<MainStack.Screen name='Following' component={Following} />
</MainStack.Navigator>
)
}

View File

@ -1,7 +0,0 @@
import React from 'react'
import Timeline from 'src/stacks/common/Timeline'
export default function Following () {
return <Timeline endpoint='home' />
}

View File

@ -1,14 +1,14 @@
import React from 'react'
import { createNativeStackNavigator } from 'react-native-screens/native-stack'
import CurrentPublic from 'src/stacks/Public/CurrentPublic'
import TimelinesCombined from 'src/stacks/common/TimelinesCombined'
const PublicStack = createNativeStackNavigator()
export default function PublicTimeline () {
export default function Public () {
return (
<PublicStack.Navigator>
<PublicStack.Screen name='CurrentPublic' component={CurrentPublic} />
</PublicStack.Navigator>
<TimelinesCombined
route={[
{ title: '跨站', timeline: { endpoint: 'public' } },
{ title: '他站', timeline: { remote: true } }
]}
/>
)
}

View File

@ -1,7 +0,0 @@
import React from 'react'
import Timeline from 'src/stacks/common/Timeline'
export default function CurrentPublic () {
return <Timeline endpoint='public' local />
}

View File

@ -0,0 +1,7 @@
import React from 'react'
import Timeline from 'src/stacks/common/Timeline'
export default function LocalPublic () {
return <Timeline endpoint='public' />
}

View File

@ -55,6 +55,6 @@ export default function Timeline ({ remote, endpoint, local }) {
Timeline.propTypes = {
remote: PropTypes.bool,
endpoint: PropTypes.string.isRequired,
endpoint: PropTypes.string,
local: PropTypes.bool
}

View File

@ -0,0 +1,81 @@
import React, { useEffect, useRef, useState } from 'react'
import PropTypes from 'prop-types'
import { Animated, Dimensions, View } from 'react-native'
import { createNativeStackNavigator } from 'react-native-screens/native-stack'
import SegmentedControl from '@react-native-community/segmented-control'
import { Feather } from '@expo/vector-icons'
import Timeline from './Timeline'
const Stack = createNativeStackNavigator()
export default function TimelinesCombined ({ route }) {
const [segment, setSegment] = useState(0)
const [renderHeader, setRenderHeader] = useState(false)
useEffect(() => {
const nbr = setTimeout(() => setRenderHeader(true), 50)
return
}, [])
const moveAnimation = useRef(new Animated.Value(0)).current
return (
<Stack.Navigator
screenOptions={{
statusBarAnimation: 'none',
headerRight: () =>
renderHeader ? (
<Feather name='search' size={24} color='black' />
) : null,
headerCenter: () =>
renderHeader ? (
<SegmentedControl
values={[route[0].title, route[1].title]}
selectedIndex={segment}
onChange={e => {
setSegment(e.nativeEvent.selectedSegmentIndex)
Animated.timing(moveAnimation, {
toValue:
-e.nativeEvent.selectedSegmentIndex *
Dimensions.get('window').width,
duration: 250,
useNativeDriver: false
}).start()
}}
style={{ width: 150, height: 30 }}
/>
) : null
}}
>
<Stack.Screen name='LocalView'>
{props => (
<Animated.View
style={{
flexDirection: 'row',
width: Dimensions.get('window').width * 2,
left: moveAnimation
}}
{...props}
>
<View style={{ width: Dimensions.get('window').width }}>
<Timeline {...route[0].timeline} />
</View>
<View style={{ width: Dimensions.get('window').width }}>
<Timeline {...route[1].timeline} />
</View>
</Animated.View>
)}
</Stack.Screen>
</Stack.Navigator>
)
}
TimelinesCombined.propTypes = {
route: PropTypes.arrayOf(
PropTypes.exact({
title: PropTypes.string.isRequired,
timeline: PropTypes.exact(Timeline.propTypes).isRequired
})
).isRequired
}

View File

@ -8,7 +8,7 @@ const preloadedState = {
instanceInfo: {
current: 'social.xmflsct.com',
currentToken: 'qjzJ0IjvZ1apsn0_wBkGcdjKgX7Dao9KEPhGwggPwAo',
remote: 'm.cmx.im'
remote: 'mastodon.social'
}
}
@ -17,14 +17,7 @@ const reducer = {
timelines: timelineSlice
}
// const middleware = getDefaultMiddleware =>
// getDefaultMiddleware({
// immutableCheck: false,
// serializableCheck: false
// })
export default configureStore({
preloadedState,
reducer,
// middleware
reducer
})

View File

@ -4,8 +4,8 @@ import { client } from 'src/api/client'
// Naming convention
// Following: home
// Local: home/local
// CurrentPublic: public/local
// Local: public/local
// CurrentPublic: public
// RemotePublic: remote
const checkInstance = ({ remote, endpoint, local }) =>
@ -14,8 +14,6 @@ const checkInstance = ({ remote, endpoint, local }) =>
export const fetch = createAsyncThunk(
'timeline/fetch',
async ({ remote, endpoint, local, id, newer }, { getState }) => {
if (!endpoint) console.error('Missing endpoint')
const instance = remote
? `${getState().instanceInfo.remote}/api/v1/timelines/public`
: `${getState().instanceInfo.current}/api/v1/timelines/${endpoint}`
@ -37,6 +35,11 @@ export const fetch = createAsyncThunk(
}
)
export const getToots = state => instance =>
state.timelines[checkInstance(instance)].toots
export const getStatus = state => instance =>
state.timelines[checkInstance(instance)].status
export const timelineSlice = createSlice({
name: 'timeline',
initialState: {
@ -44,11 +47,11 @@ export const timelineSlice = createSlice({
toots: [],
status: 'idle'
},
'home/local': {
'public/local': {
toots: [],
status: 'idle'
},
'public/local': {
public: {
toots: [],
status: 'idle'
},
@ -74,9 +77,4 @@ export const timelineSlice = createSlice({
}
})
export const getToots = state => instance =>
state.timelines[checkInstance(instance)].toots
export const getStatus = state => instance =>
state.timelines[checkInstance(instance)].status
export default timelineSlice.reducer