Basic actions work, with some bugs

One bug: https://github.com/tootsuite/mastodon/issues/3166

Another bug, still seems `extraData` does not work that well for `FlatList`
This commit is contained in:
Zhiyuan Zheng 2020-11-01 01:57:53 +01:00
parent d2cc643b9c
commit c7a4129b82
No known key found for this signature in database
GPG Key ID: 078A93AB607D85E0
7 changed files with 141 additions and 45 deletions

View File

@ -1,8 +1,9 @@
import React from 'react'
import { Pressable, StyleSheet, Text, View } from 'react-native'
import React, { useState } from 'react'
import { Modal, Pressable, StyleSheet, Text, View } from 'react-native'
import { useDispatch } from 'react-redux'
import { Feather } from '@expo/vector-icons'
import action from 'src/components/action'
import action from './action'
export interface Props {
id: string
@ -11,6 +12,7 @@ export interface Props {
reblogged?: boolean
favourites_count: number
favourited?: boolean
bookmarked: boolean
}
const Actions: React.FC<Props> = ({
@ -19,51 +21,119 @@ const Actions: React.FC<Props> = ({
reblogs_count,
reblogged,
favourites_count,
favourited
favourited,
bookmarked
}) => {
const dispatch = useDispatch()
const [modalVisible, setModalVisible] = useState(false)
return (
<View style={styles.actions}>
<Pressable style={styles.action}>
<Feather name='message-circle' />
<Text>{replies_count}</Text>
</Pressable>
<Pressable style={styles.action}>
<Feather name='repeat' />
<Text>{reblogs_count}</Text>
</Pressable>
<Pressable
style={styles.action}
onPress={() =>
action({
id,
type: 'favourite',
stateKey: 'favourited',
statePrev: favourited || false
})
}
<>
<View style={styles.actions}>
<Pressable style={styles.action}>
<Feather name='message-circle' color='gray' />
{replies_count > 0 && <Text>{replies_count}</Text>}
</Pressable>
<Pressable
style={styles.action}
onPress={() =>
action({
dispatch,
id,
type: 'reblog',
stateKey: 'reblogged',
statePrev: reblogged || false
})
}
>
<Feather name='repeat' color={reblogged ? 'black' : 'gray'} />
</Pressable>
<Pressable
style={styles.action}
onPress={() =>
action({
dispatch,
id,
type: 'favourite',
stateKey: 'favourited',
statePrev: favourited || false
})
}
>
<Feather name='heart' color={favourited ? 'black' : 'gray'} />
</Pressable>
<Pressable
style={styles.action}
onPress={() =>
action({
dispatch,
id,
type: 'bookmark',
stateKey: 'bookmarked',
statePrev: bookmarked
})
}
>
<Feather name='bookmark' color={bookmarked ? 'black' : 'gray'} />
</Pressable>
<Pressable style={styles.action} onPress={() => setModalVisible(true)}>
<Feather name='more-horizontal' color='gray' />
</Pressable>
</View>
<Modal
animationType='fade'
presentationStyle='overFullScreen'
transparent
visible={modalVisible}
>
<Feather name='heart' />
<Text>{favourites_count}</Text>
</Pressable>
<Pressable style={styles.action}>
<Feather name='share' />
</Pressable>
</View>
<Pressable
style={styles.modalBackground}
onPress={() => setModalVisible(false)}
>
<View style={styles.modalSheet}>
<Text></Text>
<Text></Text>
<Text></Text>
</View>
</Pressable>
</Modal>
</>
)
}
const styles = StyleSheet.create({
actions: {
width: '100%',
flex: 1,
flexDirection: 'row',
marginTop: 4
marginTop: 8
},
action: {
width: '25%',
width: '20%',
flexDirection: 'row',
justifyContent: 'center',
paddingTop: 8,
paddingBottom: 8
},
modalBackground: {
width: '100%',
height: '100%',
backgroundColor: 'rgba(0, 0, 0, 0.75)',
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'flex-end'
},
modalSheet: {
width: '100%',
height: '50%',
backgroundColor: 'white',
flex: 1
}
})

View File

@ -1,36 +1,43 @@
import { Dispatch } from '@reduxjs/toolkit'
import { Alert } from 'react-native'
import client from 'src/api/client'
export interface params {
id: string
}
import { updateStatus } from 'src/stacks/common/timelineSlice'
const action = async ({
dispatch,
id,
type,
stateKey,
statePrev
}: {
dispatch: Dispatch
id: string
type: 'favourite' | 'reblog' | 'bookmark' | 'mute' | 'pin'
stateKey: 'favourited' | 'reblogged' | 'bookmarked' | 'muted' | 'pinned'
statePrev: boolean
}): Promise<void> => {
console.log(stateKey + ' --- ' + statePrev)
const alert = {
title: 'This is a title',
message: 'This is a message'
}
const res = await client({
// ISSUE: https://github.com/tootsuite/mastodon/issues/3166
let res = await client({
method: 'post',
instance: 'local',
endpoint: `statuses/${id}/${statePrev ? 'un' : ''}${type}`
})
res = await client({
method: 'post',
instance: 'local',
endpoint: `statuses/${id}/${statePrev ? 'un' : ''}${type}`
})
if (!res.body[stateKey] === statePrev) {
// Update redux
console.log('OK!!!')
dispatch(updateStatus(res.body))
console.log('------ ' + res.body[stateKey])
} else {
Alert.alert(alert.title, alert.message, [
{ text: 'OK', onPress: () => console.log('OK Pressed') }

View File

@ -75,6 +75,7 @@ const TootNotification: React.FC<Props> = ({ toot }) => {
reblogged={toot.status.reblogged}
favourites_count={toot.status.favourites_count}
favourited={toot.status.favourited}
bookmarked={toot.status.bookmarked}
/>
)}
</View>

View File

@ -20,7 +20,7 @@ const TootTimeline: React.FC<Props> = ({ toot }) => {
let actualContent = toot.reblog ? toot.reblog : toot
const tootView = useMemo(() => {
// const tootView = useMemo(() => {
return (
<View style={styles.tootTimeline}>
{toot.reblog && (
@ -81,14 +81,15 @@ const TootTimeline: React.FC<Props> = ({ toot }) => {
reblogged={actualContent.reblogged}
favourites_count={actualContent.favourites_count}
favourited={actualContent.favourited}
bookmarked={actualContent.bookmarked}
/>
</View>
</View>
</View>
)
}, [toot])
// }, [toot])
return tootView
// return tootView
}
const styles = StyleSheet.create({

View File

@ -19,6 +19,7 @@ const Timeline: React.FC<{
}> = ({ page, hashtag, list, toot, account, disableRefresh = false }) => {
const dispatch = useDispatch()
const state = useSelector((state: RootState) => state.timelines[page])
const [updateStatus, setUpdateStatus] = useState(false)
const [timelineReady, setTimelineReady] = useState(false)
useEffect(() => {
@ -27,6 +28,7 @@ const Timeline: React.FC<{
dispatch(fetch({ page, hashtag, list, toot, account }))
setTimelineReady(true)
}
setUpdateStatus(!updateStatus)
return () => {
mounted = false
}

View File

@ -4,6 +4,7 @@ import {
createSlice,
PayloadAction
} from '@reduxjs/toolkit'
import store from 'src'
import client from 'src/api/client'
@ -214,8 +215,21 @@ export const timelineSlice = createSlice({
Account_Media: timelineInitState
},
reducers: {
reset: (state, action: PayloadAction<store.TimelinePage>) => {
reset (state, action: PayloadAction<store.TimelinePage>) {
//@ts-ignore
state[action.payload] = timelineInitState
},
updateStatus (state, action) {
Object.keys(state).map((page: store.TimelinePage) => {
//@ts-ignore
const index: number = state[page].toots.findIndex(
(toot: mastodon.Status) => toot.id === action.payload.id
)
if (index !== -1) {
//@ts-ignore
state[page].toots[index] = action.payload
}
})
}
},
extraReducers: builder => {
@ -252,5 +266,5 @@ export const timelineSlice = createSlice({
}
})
export const { reset } = timelineSlice.actions
export const { reset, updateStatus } = timelineSlice.actions
export default timelineSlice.reducer

View File

@ -12,5 +12,6 @@
"paths": {
"src/*": ["src/*"]
}
}
},
"exclude": ["node_modules"]
}