mirror of
https://github.com/tooot-app/app
synced 2025-03-13 18:10:12 +01:00
All timelines working
This commit is contained in:
parent
cda67d23f6
commit
c8b40017d8
5
package-lock.json
generated
5
package-lock.json
generated
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -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
14
src/stacks/Local.jsx
Normal 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 } }
|
||||
]}
|
||||
/>
|
||||
)
|
||||
}
|
@ -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>
|
||||
)
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
import React from 'react'
|
||||
|
||||
import Timeline from 'src/stacks/common/Timeline'
|
||||
|
||||
export default function Following () {
|
||||
return <Timeline endpoint='home' />
|
||||
}
|
@ -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 } }
|
||||
]}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
@ -1,7 +0,0 @@
|
||||
import React from 'react'
|
||||
|
||||
import Timeline from 'src/stacks/common/Timeline'
|
||||
|
||||
export default function CurrentPublic () {
|
||||
return <Timeline endpoint='public' local />
|
||||
}
|
7
src/stacks/Public/LocalPublic.jsx
Normal file
7
src/stacks/Public/LocalPublic.jsx
Normal file
@ -0,0 +1,7 @@
|
||||
import React from 'react'
|
||||
|
||||
import Timeline from 'src/stacks/common/Timeline'
|
||||
|
||||
export default function LocalPublic () {
|
||||
return <Timeline endpoint='public' />
|
||||
}
|
@ -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
|
||||
}
|
||||
|
81
src/stacks/common/TimelinesCombined.jsx
Normal file
81
src/stacks/common/TimelinesCombined.jsx
Normal 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
|
||||
}
|
@ -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
|
||||
})
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user