mirror of
https://github.com/tooot-app/app
synced 2025-03-28 09:20:12 +01:00
Status actions done, awaiting account actions
This commit is contained in:
parent
04b7b0a7b9
commit
c08c25e3b5
@ -36,6 +36,7 @@
|
||||
"react-native-render-html": "^4.2.4",
|
||||
"react-native-safe-area-context": "3.1.4",
|
||||
"react-native-screens": "~2.10.1",
|
||||
"react-native-toast-message": "^1.3.4",
|
||||
"react-native-web": "~0.13.7",
|
||||
"react-native-webview": "10.7.0",
|
||||
"react-navigation": "^4.4.3",
|
||||
|
2
src/@types/mastodon.d.ts
vendored
2
src/@types/mastodon.d.ts
vendored
@ -187,7 +187,7 @@ declare namespace mastodon {
|
||||
type Status = {
|
||||
// Base
|
||||
id: string
|
||||
url: string
|
||||
uri: string
|
||||
created_at: string
|
||||
account: Account
|
||||
content: string
|
||||
|
@ -7,6 +7,7 @@ import React from 'react'
|
||||
import { Feather } from '@expo/vector-icons'
|
||||
import store from 'src/stacks/common/store'
|
||||
import { Provider } from 'react-redux'
|
||||
import Toast from 'react-native-toast-message'
|
||||
import { StatusBar } from 'expo-status-bar'
|
||||
|
||||
import Local from 'src/stacks/Local'
|
||||
@ -22,6 +23,7 @@ export const Index: React.FC = () => {
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<StatusBar style='auto' />
|
||||
|
||||
<NavigationContainer>
|
||||
<Tab.Navigator
|
||||
screenOptions={({ route }) => ({
|
||||
@ -62,6 +64,8 @@ export const Index: React.FC = () => {
|
||||
<Tab.Screen name='Notifications' component={Notifications} />
|
||||
<Tab.Screen name='Me' component={Me} />
|
||||
</Tab.Navigator>
|
||||
|
||||
<Toast ref={(ref: any) => Toast.setRef(ref)} />
|
||||
</NavigationContainer>
|
||||
</Provider>
|
||||
)
|
||||
|
@ -8,7 +8,7 @@ const client = async ({
|
||||
query,
|
||||
body
|
||||
}: {
|
||||
method: 'get' | 'post'
|
||||
method: 'get' | 'post' | 'delete'
|
||||
instance: 'local' | 'remote'
|
||||
endpoint: string
|
||||
query?: {
|
||||
@ -16,7 +16,7 @@ const client = async ({
|
||||
}
|
||||
body?: object
|
||||
}): Promise<any> => {
|
||||
const state: RootState['instanceInfo'] = store.getState().instanceInfo
|
||||
const state: RootState["instanceInfo"] = store.getState().instanceInfo
|
||||
|
||||
let response
|
||||
try {
|
||||
@ -42,8 +42,8 @@ const client = async ({
|
||||
body: await response.json()
|
||||
})
|
||||
} else {
|
||||
console.error(response.error)
|
||||
return Promise.reject({ body: response.error_message })
|
||||
console.error(response.status + ': ' + response.statusText)
|
||||
return Promise.reject({ body: response.statusText })
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,255 +0,0 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import {
|
||||
ActionSheetIOS,
|
||||
Alert,
|
||||
Clipboard,
|
||||
Modal,
|
||||
Pressable,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View
|
||||
} from 'react-native'
|
||||
import { useMutation, useQueryCache } from 'react-query'
|
||||
import { Feather } from '@expo/vector-icons'
|
||||
|
||||
import client from 'src/api/client'
|
||||
|
||||
import Success from './Responses/Success'
|
||||
|
||||
const fireMutation = async ({
|
||||
id,
|
||||
type,
|
||||
stateKey,
|
||||
prevState
|
||||
}: {
|
||||
id: string
|
||||
type: 'favourite' | 'reblog' | 'bookmark' | 'mute' | 'pin'
|
||||
stateKey: 'favourited' | 'reblogged' | 'bookmarked' | 'muted' | 'pinned'
|
||||
prevState: boolean
|
||||
}) => {
|
||||
let res = await client({
|
||||
method: 'post',
|
||||
instance: 'local',
|
||||
endpoint: `statuses/${id}/${prevState ? 'un' : ''}${type}`
|
||||
})
|
||||
|
||||
if (!res.body[stateKey] === prevState) {
|
||||
return Promise.resolve(res.body)
|
||||
} else {
|
||||
const alert = {
|
||||
title: 'This is a title',
|
||||
message: 'This is a message'
|
||||
}
|
||||
Alert.alert(alert.title, alert.message, [
|
||||
{ text: 'OK', onPress: () => console.log('OK Pressed') }
|
||||
])
|
||||
return Promise.reject()
|
||||
}
|
||||
}
|
||||
|
||||
export interface Props {
|
||||
queryKey: store.QueryKey
|
||||
id: string
|
||||
url: string
|
||||
replies_count: number
|
||||
reblogs_count: number
|
||||
reblogged?: boolean
|
||||
favourites_count: number
|
||||
favourited?: boolean
|
||||
bookmarked?: boolean
|
||||
}
|
||||
|
||||
const Actions: React.FC<Props> = ({
|
||||
queryKey,
|
||||
id,
|
||||
url,
|
||||
replies_count,
|
||||
reblogs_count,
|
||||
reblogged,
|
||||
favourites_count,
|
||||
favourited,
|
||||
bookmarked
|
||||
}) => {
|
||||
const [modalVisible, setModalVisible] = useState(false)
|
||||
|
||||
const [successMessage, setSuccessMessage] = useState()
|
||||
useEffect(() => {
|
||||
setTimeout(() => {
|
||||
setSuccessMessage(undefined)
|
||||
}, 2000)
|
||||
return () => {}
|
||||
}, [successMessage])
|
||||
|
||||
const queryCache = useQueryCache()
|
||||
const [mutateAction] = useMutation(fireMutation, {
|
||||
onMutate: () => {
|
||||
queryCache.cancelQueries(queryKey)
|
||||
const prevData = queryCache.getQueryData(queryKey)
|
||||
return prevData
|
||||
},
|
||||
onSuccess: (newData, params) => {
|
||||
if (params.type === 'reblog') {
|
||||
queryCache.invalidateQueries(['Following', { page: 'Following' }])
|
||||
}
|
||||
// queryCache.setQueryData(queryKey, (oldData: any) => {
|
||||
// oldData &&
|
||||
// oldData.map((paging: any) => {
|
||||
// paging.toots.map(
|
||||
// (status: mastodon.Status | mastodon.Notification, i: number) => {
|
||||
// if (status.id === newData.id) {
|
||||
// paging.toots[i] = newData
|
||||
// }
|
||||
// }
|
||||
// )
|
||||
// })
|
||||
// return oldData
|
||||
// })
|
||||
return Promise.resolve()
|
||||
},
|
||||
onError: (err, variables, prevData) => {
|
||||
queryCache.setQueryData(queryKey, prevData)
|
||||
},
|
||||
onSettled: () => {
|
||||
queryCache.invalidateQueries(queryKey)
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<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={() =>
|
||||
mutateAction({
|
||||
id,
|
||||
type: 'reblog',
|
||||
stateKey: 'reblogged',
|
||||
prevState: reblogged || false
|
||||
})
|
||||
}
|
||||
>
|
||||
<Feather name='repeat' color={reblogged ? 'black' : 'gray'} />
|
||||
</Pressable>
|
||||
|
||||
<Pressable
|
||||
style={styles.action}
|
||||
onPress={() =>
|
||||
mutateAction({
|
||||
id,
|
||||
type: 'favourite',
|
||||
stateKey: 'favourited',
|
||||
prevState: favourited || false
|
||||
})
|
||||
}
|
||||
>
|
||||
<Feather name='heart' color={favourited ? 'black' : 'gray'} />
|
||||
</Pressable>
|
||||
|
||||
<Pressable
|
||||
style={styles.action}
|
||||
onPress={() =>
|
||||
mutateAction({
|
||||
id,
|
||||
type: 'bookmark',
|
||||
stateKey: 'bookmarked',
|
||||
prevState: bookmarked || false
|
||||
})
|
||||
}
|
||||
>
|
||||
<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}
|
||||
>
|
||||
<Pressable
|
||||
style={styles.modalBackground}
|
||||
onPress={() => setModalVisible(false)}
|
||||
>
|
||||
<View style={styles.modalSheet}>
|
||||
<Pressable
|
||||
onPress={() =>
|
||||
ActionSheetIOS.showShareActionSheetWithOptions(
|
||||
{
|
||||
url,
|
||||
excludedActivityTypes: [
|
||||
'com.apple.UIKit.activity.Mail',
|
||||
'com.apple.UIKit.activity.Print',
|
||||
'com.apple.UIKit.activity.SaveToCameraRoll',
|
||||
'com.apple.UIKit.activity.OpenInIBooks'
|
||||
]
|
||||
},
|
||||
() => {},
|
||||
() => {
|
||||
setModalVisible(false)
|
||||
setSuccessMessage('分享成功!')
|
||||
}
|
||||
)
|
||||
}
|
||||
>
|
||||
<Text>分享</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
onPress={() => {
|
||||
Clipboard.setString(url)
|
||||
// Success message
|
||||
setModalVisible(false)
|
||||
}}
|
||||
>
|
||||
<Text>复制链接</Text>
|
||||
</Pressable>
|
||||
<Text>(删除)</Text>
|
||||
<Text>(静音),(置顶)</Text>
|
||||
<Text>静音用户,屏蔽用户,屏蔽域名,举报用户</Text>
|
||||
</View>
|
||||
</Pressable>
|
||||
</Modal>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
actions: {
|
||||
width: '100%',
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
marginTop: 8
|
||||
},
|
||||
action: {
|
||||
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
|
||||
}
|
||||
})
|
||||
|
||||
export default Actions
|
347
src/components/Status/ActionsStatus.tsx
Normal file
347
src/components/Status/ActionsStatus.tsx
Normal file
@ -0,0 +1,347 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import {
|
||||
ActionSheetIOS,
|
||||
Clipboard,
|
||||
Modal,
|
||||
Pressable,
|
||||
StyleSheet,
|
||||
Text,
|
||||
View
|
||||
} from 'react-native'
|
||||
import Toast from 'react-native-toast-message'
|
||||
import { useMutation, useQueryCache } from 'react-query'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { Feather } from '@expo/vector-icons'
|
||||
|
||||
import client from 'src/api/client'
|
||||
|
||||
const fireMutation = async ({
|
||||
id,
|
||||
type,
|
||||
stateKey,
|
||||
prevState
|
||||
}: {
|
||||
id: string
|
||||
type:
|
||||
| 'favourite'
|
||||
| 'reblog'
|
||||
| 'bookmark'
|
||||
| 'mute'
|
||||
| 'pin'
|
||||
| 'delete'
|
||||
| 'account/mute'
|
||||
stateKey:
|
||||
| 'favourited'
|
||||
| 'reblogged'
|
||||
| 'bookmarked'
|
||||
| 'muted'
|
||||
| 'pinned'
|
||||
| 'id'
|
||||
prevState?: boolean
|
||||
}) => {
|
||||
let res
|
||||
switch (type) {
|
||||
case 'favourite':
|
||||
case 'reblog':
|
||||
case 'bookmark':
|
||||
case 'mute':
|
||||
case 'pin':
|
||||
res = await client({
|
||||
method: 'post',
|
||||
instance: 'local',
|
||||
endpoint: `statuses/${id}/${prevState ? 'un' : ''}${type}`
|
||||
})
|
||||
|
||||
if (!res.body[stateKey] === prevState) {
|
||||
if (type === 'bookmark' || 'mute' || 'pin')
|
||||
Toast.show({
|
||||
type: 'success',
|
||||
position: 'bottom',
|
||||
text1: '功能成功',
|
||||
visibilityTime: 2000,
|
||||
autoHide: true,
|
||||
bottomOffset: 65
|
||||
})
|
||||
return Promise.resolve(res.body)
|
||||
} else {
|
||||
Toast.show({
|
||||
type: 'error',
|
||||
position: 'bottom',
|
||||
text1: '请重试',
|
||||
autoHide: false,
|
||||
bottomOffset: 65
|
||||
})
|
||||
return Promise.reject()
|
||||
}
|
||||
break
|
||||
case 'delete':
|
||||
res = await client({
|
||||
method: 'delete',
|
||||
instance: 'local',
|
||||
endpoint: `statuses/${id}`
|
||||
})
|
||||
|
||||
if (res.body[stateKey] === id) {
|
||||
Toast.show({
|
||||
type: 'success',
|
||||
position: 'bottom',
|
||||
text1: '删除成功',
|
||||
visibilityTime: 2000,
|
||||
autoHide: true,
|
||||
bottomOffset: 65
|
||||
})
|
||||
return Promise.resolve(res.body)
|
||||
} else {
|
||||
Toast.show({
|
||||
type: 'error',
|
||||
position: 'bottom',
|
||||
text1: '请重试',
|
||||
autoHide: false,
|
||||
bottomOffset: 65
|
||||
})
|
||||
return Promise.reject()
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
export interface Props {
|
||||
queryKey: store.QueryKey
|
||||
status: mastodon.Status
|
||||
}
|
||||
|
||||
const ActionsStatus: React.FC<Props> = ({ queryKey, status }) => {
|
||||
const localAccountId = useSelector(state => state.instanceInfo.localAccountId)
|
||||
const [modalVisible, setModalVisible] = useState(false)
|
||||
|
||||
const queryCache = useQueryCache()
|
||||
const [mutateAction] = useMutation(fireMutation, {
|
||||
onMutate: () => {
|
||||
queryCache.cancelQueries(queryKey)
|
||||
const prevData = queryCache.getQueryData(queryKey)
|
||||
return prevData
|
||||
},
|
||||
onSuccess: (newData, params) => {
|
||||
if (params.type === 'reblog') {
|
||||
queryCache.invalidateQueries(['Following', { page: 'Following' }])
|
||||
}
|
||||
// queryCache.setQueryData(queryKey, (oldData: any) => {
|
||||
// oldData &&
|
||||
// oldData.map((paging: any) => {
|
||||
// paging.toots.map(
|
||||
// (status: mastodon.Status | mastodon.Notification, i: number) => {
|
||||
// if (status.id === newData.id) {
|
||||
// paging.toots[i] = newData
|
||||
// }
|
||||
// }
|
||||
// )
|
||||
// })
|
||||
// return oldData
|
||||
// })
|
||||
return Promise.resolve()
|
||||
},
|
||||
onError: (err, variables, prevData) => {
|
||||
queryCache.setQueryData(queryKey, prevData)
|
||||
},
|
||||
onSettled: () => {
|
||||
queryCache.invalidateQueries(queryKey)
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<View style={styles.actions}>
|
||||
<Pressable style={styles.action}>
|
||||
<Feather name='message-circle' color='gray' />
|
||||
{status.replies_count > 0 && <Text>{status.replies_count}</Text>}
|
||||
</Pressable>
|
||||
|
||||
<Pressable
|
||||
style={styles.action}
|
||||
onPress={() =>
|
||||
mutateAction({
|
||||
id: status.id,
|
||||
type: 'reblog',
|
||||
stateKey: 'reblogged',
|
||||
prevState: status.reblogged
|
||||
})
|
||||
}
|
||||
>
|
||||
<Feather name='repeat' color={status.reblogged ? 'black' : 'gray'} />
|
||||
</Pressable>
|
||||
|
||||
<Pressable
|
||||
style={styles.action}
|
||||
onPress={() =>
|
||||
mutateAction({
|
||||
id: status.id,
|
||||
type: 'favourite',
|
||||
stateKey: 'favourited',
|
||||
prevState: status.favourited
|
||||
})
|
||||
}
|
||||
>
|
||||
<Feather name='heart' color={status.favourited ? 'black' : 'gray'} />
|
||||
</Pressable>
|
||||
|
||||
<Pressable
|
||||
style={styles.action}
|
||||
onPress={() =>
|
||||
mutateAction({
|
||||
id: status.id,
|
||||
type: 'bookmark',
|
||||
stateKey: 'bookmarked',
|
||||
prevState: status.bookmarked
|
||||
})
|
||||
}
|
||||
>
|
||||
<Feather
|
||||
name='bookmark'
|
||||
color={status.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}
|
||||
>
|
||||
<Pressable
|
||||
style={styles.modalBackground}
|
||||
onPress={() => setModalVisible(false)}
|
||||
>
|
||||
<View style={styles.modalSheet}>
|
||||
<Pressable
|
||||
onPress={() =>
|
||||
ActionSheetIOS.showShareActionSheetWithOptions(
|
||||
{
|
||||
url: status.uri,
|
||||
excludedActivityTypes: [
|
||||
'com.apple.UIKit.activity.Mail',
|
||||
'com.apple.UIKit.activity.Print',
|
||||
'com.apple.UIKit.activity.SaveToCameraRoll',
|
||||
'com.apple.UIKit.activity.OpenInIBooks'
|
||||
]
|
||||
},
|
||||
() => {},
|
||||
() => {
|
||||
setModalVisible(false)
|
||||
Toast.show({
|
||||
type: 'success',
|
||||
position: 'bottom',
|
||||
text1: '分享成功',
|
||||
visibilityTime: 2000,
|
||||
autoHide: true,
|
||||
bottomOffset: 65
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
>
|
||||
<Text>分享</Text>
|
||||
</Pressable>
|
||||
<Pressable
|
||||
onPress={() => {
|
||||
Clipboard.setString(status.uri)
|
||||
setModalVisible(false)
|
||||
Toast.show({
|
||||
type: 'success',
|
||||
position: 'bottom',
|
||||
text1: '链接复制成功',
|
||||
visibilityTime: 2000,
|
||||
autoHide: true,
|
||||
bottomOffset: 65
|
||||
})
|
||||
}}
|
||||
>
|
||||
<Text>复制链接</Text>
|
||||
</Pressable>
|
||||
{status.account.id === localAccountId && (
|
||||
<Pressable
|
||||
onPress={() => {
|
||||
setModalVisible(false)
|
||||
mutateAction({
|
||||
id: status.id,
|
||||
type: 'delete',
|
||||
stateKey: 'id'
|
||||
})
|
||||
}}
|
||||
>
|
||||
<Text>删除</Text>
|
||||
</Pressable>
|
||||
)}
|
||||
<Text>(删除并重发)</Text>
|
||||
<Pressable
|
||||
onPress={() => {
|
||||
setModalVisible(false)
|
||||
mutateAction({
|
||||
id: status.id,
|
||||
type: 'mute',
|
||||
stateKey: 'muted',
|
||||
prevState: status.muted
|
||||
})
|
||||
}}
|
||||
>
|
||||
<Text>{status.muted ? '取消静音' : '静音'}</Text>
|
||||
</Pressable>
|
||||
{status.account.id === localAccountId && (
|
||||
<Pressable
|
||||
onPress={() => {
|
||||
setModalVisible(false)
|
||||
mutateAction({
|
||||
id: status.id,
|
||||
type: 'pin',
|
||||
stateKey: 'pinned',
|
||||
prevState: status.pinned
|
||||
})
|
||||
}}
|
||||
>
|
||||
<Text>{status.pinned ? '取消置顶' : '置顶'}</Text>
|
||||
</Pressable>
|
||||
)}
|
||||
<Text>静音用户,屏蔽用户,屏蔽域名,举报用户</Text>
|
||||
</View>
|
||||
</Pressable>
|
||||
</Modal>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
actions: {
|
||||
width: '100%',
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
marginTop: 8
|
||||
},
|
||||
action: {
|
||||
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
|
||||
}
|
||||
})
|
||||
|
||||
export default ActionsStatus
|
@ -1,62 +0,0 @@
|
||||
import React, { useEffect, useRef } from 'react'
|
||||
import { Animated, StyleSheet, Text, View } from 'react-native'
|
||||
|
||||
export interface Props {
|
||||
message?: string
|
||||
}
|
||||
|
||||
const Success: React.FC<Props> = ({ message }) => {
|
||||
const fadeAnim = useRef(new Animated.Value(0)).current
|
||||
useEffect(() => {
|
||||
// console.log(message)
|
||||
if (message !== undefined) {
|
||||
fadeIn()
|
||||
} else {
|
||||
fadeOut()
|
||||
}
|
||||
}, [message])
|
||||
|
||||
const fadeIn = () => {
|
||||
// Will change fadeAnim value to 1 in 5 seconds
|
||||
Animated.timing(fadeAnim, {
|
||||
useNativeDriver: false,
|
||||
toValue: 300,
|
||||
duration: 1000
|
||||
}).start()
|
||||
}
|
||||
|
||||
const fadeOut = () => {
|
||||
// Will change fadeAnim value to 0 in 5 seconds
|
||||
Animated.timing(fadeAnim, {
|
||||
useNativeDriver: false,
|
||||
toValue: 400,
|
||||
duration: 1000
|
||||
}).start()
|
||||
}
|
||||
|
||||
return (
|
||||
<Animated.View
|
||||
style={[
|
||||
styles.success,
|
||||
{
|
||||
top: fadeAnim
|
||||
}
|
||||
]}
|
||||
>
|
||||
<Text>{message}</Text>
|
||||
</Animated.View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
success: {
|
||||
width: '80%',
|
||||
height: 25,
|
||||
position: 'absolute',
|
||||
top: 400,
|
||||
backgroundColor: 'red',
|
||||
zIndex: 50
|
||||
}
|
||||
})
|
||||
|
||||
export default Success
|
@ -9,92 +9,94 @@ import Content from './Status/Content'
|
||||
import Poll from './Status/Poll'
|
||||
import Attachment from './Status/Attachment'
|
||||
import Card from './Status/Card'
|
||||
import Actions from './Status/Actions'
|
||||
import ActionsStatus from './Status/ActionsStatus'
|
||||
|
||||
export interface Props {
|
||||
status: mastodon.Notification
|
||||
notification: mastodon.Notification
|
||||
queryKey: store.QueryKey
|
||||
}
|
||||
|
||||
const TootNotification: React.FC<Props> = ({ status }) => {
|
||||
const TootNotification: React.FC<Props> = ({ notification, queryKey }) => {
|
||||
const navigation = useNavigation()
|
||||
const actualAccount = status.status ? status.status.account : status.account
|
||||
const actualAccount = notification.status
|
||||
? notification.status.account
|
||||
: notification.account
|
||||
|
||||
const statusView = useMemo(() => {
|
||||
return (
|
||||
<View style={styles.statusView}>
|
||||
<View style={styles.notificationView}>
|
||||
<Actioned
|
||||
action={status.type}
|
||||
name={status.account.display_name || status.account.username}
|
||||
emojis={status.account.emojis}
|
||||
action={notification.type}
|
||||
name={
|
||||
notification.account.display_name || notification.account.username
|
||||
}
|
||||
emojis={notification.account.emojis}
|
||||
notification
|
||||
/>
|
||||
|
||||
<View style={styles.status}>
|
||||
<View style={styles.notification}>
|
||||
<Avatar uri={actualAccount.avatar} id={actualAccount.id} />
|
||||
<View style={styles.details}>
|
||||
<Header
|
||||
name={actualAccount.display_name || actualAccount.username}
|
||||
emojis={actualAccount.emojis}
|
||||
account={actualAccount.acct}
|
||||
created_at={status.created_at}
|
||||
created_at={notification.created_at}
|
||||
/>
|
||||
<Pressable
|
||||
onPress={() => navigation.navigate('Toot', { toot: status.id })}
|
||||
onPress={() =>
|
||||
navigation.navigate('Toot', { toot: notification.id })
|
||||
}
|
||||
>
|
||||
{status.status ? (
|
||||
{notification.status ? (
|
||||
<>
|
||||
{status.status.content && (
|
||||
{notification.status.content && (
|
||||
<Content
|
||||
content={status.status.content}
|
||||
emojis={status.status.emojis}
|
||||
mentions={status.status.mentions}
|
||||
spoiler_text={status.status.spoiler_text}
|
||||
// tags={status.status.tags}
|
||||
content={notification.status.content}
|
||||
emojis={notification.status.emojis}
|
||||
mentions={notification.status.mentions}
|
||||
spoiler_text={notification.status.spoiler_text}
|
||||
// tags={notification.notification.tags}
|
||||
// style={{ flex: 1 }}
|
||||
/>
|
||||
)}
|
||||
{status.status.poll && <Poll poll={status.status.poll} />}
|
||||
{status.status.media_attachments.length > 0 && (
|
||||
{notification.status.poll && (
|
||||
<Poll poll={notification.status.poll} />
|
||||
)}
|
||||
{notification.status.media_attachments.length > 0 && (
|
||||
<Attachment
|
||||
media_attachments={status.status.media_attachments}
|
||||
sensitive={status.status.sensitive}
|
||||
media_attachments={notification.status.media_attachments}
|
||||
sensitive={notification.status.sensitive}
|
||||
width={Dimensions.get('window').width - 24 - 50 - 8}
|
||||
/>
|
||||
)}
|
||||
{status.status.card && <Card card={status.status.card} />}
|
||||
{notification.status.card && (
|
||||
<Card card={notification.status.card} />
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</Pressable>
|
||||
{status.status && (
|
||||
<Actions
|
||||
id={status.status.id}
|
||||
url={status.status.url}
|
||||
replies_count={status.status.replies_count}
|
||||
reblogs_count={status.status.reblogs_count}
|
||||
reblogged={status.status.reblogged}
|
||||
favourites_count={status.status.favourites_count}
|
||||
favourited={status.status.favourited}
|
||||
bookmarked={status.status.bookmarked}
|
||||
/>
|
||||
{notification.status && (
|
||||
<ActionsStatus queryKey={queryKey} status={notification.status} />
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}, [status])
|
||||
}, [notification])
|
||||
|
||||
return statusView
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
statusView: {
|
||||
notificationView: {
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
padding: 12
|
||||
},
|
||||
status: {
|
||||
notification: {
|
||||
flex: 1,
|
||||
flexDirection: 'row'
|
||||
},
|
||||
|
@ -9,7 +9,7 @@ import Content from './Status/Content'
|
||||
import Poll from './Status/Poll'
|
||||
import Attachment from './Status/Attachment'
|
||||
import Card from './Status/Card'
|
||||
import Actions from './Status/Actions'
|
||||
import ActionsStatus from './Status/ActionsStatus'
|
||||
|
||||
export interface Props {
|
||||
status: mastodon.Status
|
||||
@ -19,7 +19,7 @@ export interface Props {
|
||||
const StatusInTimeline: React.FC<Props> = ({ status, queryKey }) => {
|
||||
const navigation = useNavigation()
|
||||
|
||||
let actualContent = status.reblog ? status.reblog : status
|
||||
let actualStatus = status.reblog ? status.reblog : status
|
||||
|
||||
const statusView = useMemo(() => {
|
||||
return (
|
||||
@ -33,59 +33,49 @@ const StatusInTimeline: React.FC<Props> = ({ status, queryKey }) => {
|
||||
)}
|
||||
<View style={styles.status}>
|
||||
<Avatar
|
||||
uri={actualContent.account.avatar}
|
||||
id={actualContent.account.id}
|
||||
uri={actualStatus.account.avatar}
|
||||
id={actualStatus.account.id}
|
||||
/>
|
||||
<View style={styles.details}>
|
||||
<Header
|
||||
name={
|
||||
actualContent.account.display_name ||
|
||||
actualContent.account.username
|
||||
actualStatus.account.display_name ||
|
||||
actualStatus.account.username
|
||||
}
|
||||
emojis={actualContent.account.emojis}
|
||||
account={actualContent.account.acct}
|
||||
emojis={actualStatus.account.emojis}
|
||||
account={actualStatus.account.acct}
|
||||
created_at={status.created_at}
|
||||
application={status.application}
|
||||
/>
|
||||
{/* Can pass toot info to next page to speed up performance */}
|
||||
<Pressable
|
||||
onPress={() =>
|
||||
navigation.navigate('Toot', { toot: actualContent.id })
|
||||
navigation.navigate('Toot', { toot: actualStatus.id })
|
||||
}
|
||||
>
|
||||
{actualContent.content ? (
|
||||
{actualStatus.content ? (
|
||||
<Content
|
||||
content={actualContent.content}
|
||||
emojis={actualContent.emojis}
|
||||
mentions={actualContent.mentions}
|
||||
spoiler_text={actualContent.spoiler_text}
|
||||
// tags={actualContent.tags}
|
||||
content={actualStatus.content}
|
||||
emojis={actualStatus.emojis}
|
||||
mentions={actualStatus.mentions}
|
||||
spoiler_text={actualStatus.spoiler_text}
|
||||
// tags={actualStatus.tags}
|
||||
// style={{ flex: 1 }}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
{actualContent.poll && <Poll poll={actualContent.poll} />}
|
||||
{actualContent.media_attachments.length > 0 && (
|
||||
{actualStatus.poll && <Poll poll={actualStatus.poll} />}
|
||||
{actualStatus.media_attachments.length > 0 && (
|
||||
<Attachment
|
||||
media_attachments={actualContent.media_attachments}
|
||||
sensitive={actualContent.sensitive}
|
||||
media_attachments={actualStatus.media_attachments}
|
||||
sensitive={actualStatus.sensitive}
|
||||
width={Dimensions.get('window').width - 24 - 50 - 8}
|
||||
/>
|
||||
)}
|
||||
{actualContent.card && <Card card={actualContent.card} />}
|
||||
{actualStatus.card && <Card card={actualStatus.card} />}
|
||||
</Pressable>
|
||||
<Actions
|
||||
queryKey={queryKey}
|
||||
id={actualContent.id}
|
||||
url={actualContent.url}
|
||||
replies_count={actualContent.replies_count}
|
||||
reblogs_count={actualContent.reblogs_count}
|
||||
reblogged={actualContent.reblogged}
|
||||
favourites_count={actualContent.favourites_count}
|
||||
favourited={actualContent.favourited}
|
||||
bookmarked={actualContent.bookmarked}
|
||||
/>
|
||||
<ActionsStatus queryKey={queryKey} status={actualStatus} />
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
@ -70,7 +70,11 @@ const Timeline: React.FC<Props> = ({
|
||||
keyExtractor={({ id }) => id}
|
||||
renderItem={({ item, index, separators }) =>
|
||||
page === 'Notifications' ? (
|
||||
<StatusInNotifications key={index} status={item} />
|
||||
<StatusInNotifications
|
||||
key={index}
|
||||
notification={item}
|
||||
queryKey={queryKey}
|
||||
/>
|
||||
) : (
|
||||
<StatusInTimeline key={index} status={item} queryKey={queryKey} />
|
||||
)
|
||||
|
@ -7,6 +7,7 @@ const preloadedState = {
|
||||
instanceInfo: {
|
||||
local: 'social.xmflsct.com',
|
||||
localToken: 'qjzJ0IjvZ1apsn0_wBkGcdjKgX7Dao9KEPhGwggPwAo',
|
||||
localAccountId: '1',
|
||||
remote: 'mastodon.social'
|
||||
}
|
||||
}
|
||||
|
6315
yarn-error.log
Normal file
6315
yarn-error.log
Normal file
File diff suppressed because it is too large
Load Diff
@ -4949,6 +4949,11 @@ react-native-screens@~2.10.1:
|
||||
resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-2.10.1.tgz#06d22fae87ef0ce51c616c34a199726db1403b95"
|
||||
integrity sha512-Z2kKSk4AwWRQNCBmTjViuBQK0/Lx0jc25TZptn/2gKYUCOuVRvCekoA26u0Tsb3BIQ8tWDsZW14OwDlFUXW1aw==
|
||||
|
||||
react-native-toast-message@^1.3.4:
|
||||
version "1.3.4"
|
||||
resolved "https://registry.yarnpkg.com/react-native-toast-message/-/react-native-toast-message-1.3.4.tgz#19ea1c5d3ad8e9d12f7550c4719a9e0258dca6bd"
|
||||
integrity sha512-83rKaLNC8/JPEPlrONVTurVepIlXKuHnFnxm7mJ58CA3XN4fT6ayRBubs/pd8u980mDFHqo8ysJOSHF3dwPg4g==
|
||||
|
||||
react-native-web@~0.13.7:
|
||||
version "0.13.18"
|
||||
resolved "https://registry.yarnpkg.com/react-native-web/-/react-native-web-0.13.18.tgz#964f058a16521a3b9a31b091415edfef5b6ef305"
|
||||
|
Loading…
x
Reference in New Issue
Block a user