mirror of
https://github.com/tooot-app/app
synced 2025-02-09 00:18:38 +01:00
Video working
This commit is contained in:
parent
2fae98cb9e
commit
aa53533534
@ -75,7 +75,8 @@ const styles = StyleSheet.create({
|
|||||||
})
|
})
|
||||||
|
|
||||||
Actioned.propTypes = {
|
Actioned.propTypes = {
|
||||||
action: PropTypes.oneOf(['favourite', 'follow', 'poll', 'reblog']).isRequired,
|
action: PropTypes.oneOf(['favourite', 'follow', 'mention', 'poll', 'reblog'])
|
||||||
|
.isRequired,
|
||||||
name: PropTypes.string,
|
name: PropTypes.string,
|
||||||
emojis: PropTypes.arrayOf(propTypesEmoji),
|
emojis: PropTypes.arrayOf(propTypesEmoji),
|
||||||
notification: PropTypes.bool
|
notification: PropTypes.bool
|
||||||
|
81
src/components/Toot/Attachment.jsx
Normal file
81
src/components/Toot/Attachment.jsx
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import propTypesAttachment from 'src/prop-types/attachment'
|
||||||
|
import { Text, View } from 'react-native'
|
||||||
|
|
||||||
|
import AttachmentImage from './Attachment/AttachmentImage'
|
||||||
|
import AttachmentVideo from './Attachment/AttachmentVideo'
|
||||||
|
|
||||||
|
export default function Attachment ({ media_attachments, sensitive, width }) {
|
||||||
|
let attachment
|
||||||
|
let attachmentHeight
|
||||||
|
// if (width) {}
|
||||||
|
switch (media_attachments[0].type) {
|
||||||
|
case 'unknown':
|
||||||
|
attachment = <Text>文件不支持</Text>
|
||||||
|
attachmentHeight = 25
|
||||||
|
break
|
||||||
|
case 'image':
|
||||||
|
attachment = (
|
||||||
|
<AttachmentImage
|
||||||
|
media_attachments={media_attachments}
|
||||||
|
sensitive={sensitive}
|
||||||
|
width={width}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
attachmentHeight = width / 2
|
||||||
|
break
|
||||||
|
case 'gifv':
|
||||||
|
attachment = (
|
||||||
|
<AttachmentVideo
|
||||||
|
media_attachments={media_attachments}
|
||||||
|
sensitive={sensitive}
|
||||||
|
width={width}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
attachmentHeight =
|
||||||
|
(width / media_attachments[0].meta.original.width) *
|
||||||
|
media_attachments[0].meta.original.height
|
||||||
|
break
|
||||||
|
case 'video':
|
||||||
|
attachment = (
|
||||||
|
<AttachmentVideo
|
||||||
|
media_attachments={media_attachments}
|
||||||
|
sensitive={sensitive}
|
||||||
|
width={width}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
attachmentHeight =
|
||||||
|
(width / media_attachments[0].meta.original.width) *
|
||||||
|
media_attachments[0].meta.original.height
|
||||||
|
break
|
||||||
|
// case 'audio':
|
||||||
|
// attachment = (
|
||||||
|
// <AttachmentAudio
|
||||||
|
// media_attachments={media_attachments}
|
||||||
|
// sensitive={sensitive}
|
||||||
|
// width={width}
|
||||||
|
// />
|
||||||
|
// )
|
||||||
|
// break
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
width: width + 8,
|
||||||
|
height: attachmentHeight,
|
||||||
|
marginTop: 4,
|
||||||
|
marginLeft: -4
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{attachment}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Attachment.propTypes = {
|
||||||
|
media_attachments: PropTypes.arrayOf(propTypesAttachment),
|
||||||
|
sensitive: PropTypes.bool.isRequired,
|
||||||
|
width: PropTypes.number.isRequired
|
||||||
|
}
|
102
src/components/Toot/Attachment/AttachmentImage.jsx
Normal file
102
src/components/Toot/Attachment/AttachmentImage.jsx
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import propTypesAttachment from 'src/prop-types/attachment'
|
||||||
|
import { Button, Image, Modal, StyleSheet, Pressable, View } from 'react-native'
|
||||||
|
import ImageViewer from 'react-native-image-zoom-viewer'
|
||||||
|
|
||||||
|
export default function AttachmentImage ({ media_attachments, sensitive, width }) {
|
||||||
|
const [mediaSensitive, setMediaSensitive] = useState(sensitive)
|
||||||
|
const [imageModalVisible, setImageModalVisible] = useState(false)
|
||||||
|
const [imageModalIndex, setImageModalIndex] = useState(0)
|
||||||
|
useEffect(() => {
|
||||||
|
if (sensitive && mediaSensitive === false) {
|
||||||
|
setTimeout(() => {
|
||||||
|
setMediaSensitive(true)
|
||||||
|
}, 10000)
|
||||||
|
}
|
||||||
|
}, [mediaSensitive])
|
||||||
|
|
||||||
|
let images = []
|
||||||
|
media_attachments = media_attachments.map((m, i) => {
|
||||||
|
images.push({
|
||||||
|
url: m.url,
|
||||||
|
width: m.meta.original.width,
|
||||||
|
height: m.meta.original.height
|
||||||
|
})
|
||||||
|
return (
|
||||||
|
<Pressable
|
||||||
|
key={i}
|
||||||
|
style={{ flexGrow: 1, height: width / 2, margin: 4 }}
|
||||||
|
onPress={() => {
|
||||||
|
setImageModalIndex(i)
|
||||||
|
setImageModalVisible(true)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
source={{ uri: m.preview_url }}
|
||||||
|
style={styles.image}
|
||||||
|
blurRadius={mediaSensitive ? width / 5 : 0}
|
||||||
|
/>
|
||||||
|
</Pressable>
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<View style={styles.media}>
|
||||||
|
{media_attachments}
|
||||||
|
{mediaSensitive && (
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
width: '100%',
|
||||||
|
height: '100%'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
title='Press me'
|
||||||
|
onPress={() => {
|
||||||
|
setMediaSensitive(false)
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
<Modal
|
||||||
|
visible={imageModalVisible}
|
||||||
|
transparent={true}
|
||||||
|
animationType='fade'
|
||||||
|
>
|
||||||
|
<ImageViewer
|
||||||
|
imageUrls={images}
|
||||||
|
index={imageModalIndex}
|
||||||
|
onSwipeDown={() => setImageModalVisible(false)}
|
||||||
|
enableSwipeDown={true}
|
||||||
|
swipeDownThreshold={100}
|
||||||
|
useNativeDriver={true}
|
||||||
|
/>
|
||||||
|
</Modal>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
media: {
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: 'column',
|
||||||
|
flexWrap: 'wrap',
|
||||||
|
justifyContent: 'space-between',
|
||||||
|
alignItems: 'stretch',
|
||||||
|
alignContent: 'stretch'
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
width: '100%',
|
||||||
|
height: '100%'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
AttachmentImage.propTypes = {
|
||||||
|
media_attachments: PropTypes.arrayOf(propTypesAttachment),
|
||||||
|
sensitive: PropTypes.bool.isRequired,
|
||||||
|
width: PropTypes.number.isRequired
|
||||||
|
}
|
72
src/components/Toot/Attachment/AttachmentVideo.jsx
Normal file
72
src/components/Toot/Attachment/AttachmentVideo.jsx
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import React, { useRef, useState } from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import propTypesAttachment from 'src/prop-types/attachment'
|
||||||
|
import { Pressable, View } from 'react-native'
|
||||||
|
import { Video } from 'expo-av'
|
||||||
|
import { Feather } from '@expo/vector-icons'
|
||||||
|
|
||||||
|
export default function AttachmentVideo ({
|
||||||
|
media_attachments,
|
||||||
|
sensitive,
|
||||||
|
width
|
||||||
|
}) {
|
||||||
|
const videoPlayer = useRef()
|
||||||
|
const [mediaSensitive, setMediaSensitive] = useState(sensitive)
|
||||||
|
const [videoPlay, setVideoPlay] = useState(false)
|
||||||
|
|
||||||
|
const video = media_attachments[0]
|
||||||
|
const videoWidth = width
|
||||||
|
const videoHeight =
|
||||||
|
(width / video.meta.original.width) * video.meta.original.height
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
width: videoWidth,
|
||||||
|
height: videoHeight
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Video
|
||||||
|
ref={videoPlayer}
|
||||||
|
source={{ uri: video.remote_url }}
|
||||||
|
style={{
|
||||||
|
width: videoWidth,
|
||||||
|
height: videoHeight
|
||||||
|
}}
|
||||||
|
resizeMode='cover'
|
||||||
|
usePoster
|
||||||
|
posterSourceThe={{ uri: video.preview_url }}
|
||||||
|
useNativeControls
|
||||||
|
shouldPlay={videoPlay}
|
||||||
|
/>
|
||||||
|
{!videoPlay && (
|
||||||
|
<Pressable
|
||||||
|
onPress={() => {
|
||||||
|
setMediaSensitive(false)
|
||||||
|
videoPlayer.current.presentFullscreenPlayer()
|
||||||
|
setVideoPlay(true)
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
backgroundColor: 'rgba(0, 0, 0, 0.25)'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Feather name='play' size={36} color='black' />
|
||||||
|
</Pressable>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
AttachmentVideo.propTypes = {
|
||||||
|
media_attachments: PropTypes.arrayOf(propTypesAttachment),
|
||||||
|
sensitive: PropTypes.bool.isRequired,
|
||||||
|
width: PropTypes.number.isRequired
|
||||||
|
}
|
@ -1,138 +0,0 @@
|
|||||||
import React, { useEffect, useState } from 'react'
|
|
||||||
import PropTypes from 'prop-types'
|
|
||||||
import propTypesAttachment from 'src/prop-types/attachment'
|
|
||||||
import {
|
|
||||||
Button,
|
|
||||||
Image,
|
|
||||||
Modal,
|
|
||||||
StyleSheet,
|
|
||||||
Text,
|
|
||||||
Pressable,
|
|
||||||
View
|
|
||||||
} from 'react-native'
|
|
||||||
import ImageViewer from 'react-native-image-zoom-viewer'
|
|
||||||
|
|
||||||
export default function Media ({ media_attachments, sensitive, width }) {
|
|
||||||
const [mediaSensitive, setMediaSensitive] = useState(sensitive)
|
|
||||||
const [imageModalVisible, setImageModalVisible] = useState(false)
|
|
||||||
const [imageModalIndex, setImageModalIndex] = useState(0)
|
|
||||||
useEffect(() => {
|
|
||||||
if (sensitive && mediaSensitive === false) {
|
|
||||||
setTimeout(() => {
|
|
||||||
setMediaSensitive(true)
|
|
||||||
}, 10000)
|
|
||||||
}
|
|
||||||
}, [mediaSensitive])
|
|
||||||
|
|
||||||
let media
|
|
||||||
let images = []
|
|
||||||
if (width) {
|
|
||||||
media_attachments = media_attachments.map((m, i) => {
|
|
||||||
switch (m.type) {
|
|
||||||
case 'unknown':
|
|
||||||
return <Text key={i}>文件不支持</Text>
|
|
||||||
case 'image':
|
|
||||||
images.push({
|
|
||||||
url: m.url,
|
|
||||||
width: m.meta.original.width,
|
|
||||||
height: m.meta.original.height
|
|
||||||
})
|
|
||||||
return (
|
|
||||||
<Pressable
|
|
||||||
key={i}
|
|
||||||
style={{ flexGrow: 1, height: width / 2, margin: 4 }}
|
|
||||||
onPress={() => {
|
|
||||||
setImageModalIndex(i)
|
|
||||||
setImageModalVisible(true)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Image
|
|
||||||
source={{ uri: m.preview_url }}
|
|
||||||
style={styles.image}
|
|
||||||
blurRadius={mediaSensitive ? width / 5 : 0}
|
|
||||||
/>
|
|
||||||
</Pressable>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
if (images) {
|
|
||||||
media = (
|
|
||||||
<>
|
|
||||||
<View style={styles.media}>
|
|
||||||
{media_attachments}
|
|
||||||
{mediaSensitive && (
|
|
||||||
<View
|
|
||||||
style={{
|
|
||||||
position: 'absolute',
|
|
||||||
width: '100%',
|
|
||||||
height: '100%'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Button
|
|
||||||
title='Press me'
|
|
||||||
onPress={() => {
|
|
||||||
setMediaSensitive(false)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
<Modal
|
|
||||||
visible={imageModalVisible}
|
|
||||||
transparent={true}
|
|
||||||
animationType='fade'
|
|
||||||
>
|
|
||||||
<ImageViewer
|
|
||||||
imageUrls={images}
|
|
||||||
index={imageModalIndex}
|
|
||||||
onSwipeDown={() => setImageModalVisible(false)}
|
|
||||||
enableSwipeDown={true}
|
|
||||||
swipeDownThreshold={100}
|
|
||||||
useNativeDriver={true}
|
|
||||||
/>
|
|
||||||
</Modal>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
media = <View style={styles.media}>{media_attachments}</View>
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
media = <></>
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
media_attachments.length > 0 && (
|
|
||||||
<View
|
|
||||||
style={{
|
|
||||||
width: width + 8,
|
|
||||||
height: width / 2,
|
|
||||||
marginTop: 4,
|
|
||||||
marginLeft: -4
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{media}
|
|
||||||
</View>
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
|
||||||
media: {
|
|
||||||
flex: 1,
|
|
||||||
flexDirection: 'column',
|
|
||||||
flexWrap: 'wrap',
|
|
||||||
justifyContent: 'space-between',
|
|
||||||
alignItems: 'stretch',
|
|
||||||
alignContent: 'stretch'
|
|
||||||
},
|
|
||||||
image: {
|
|
||||||
width: '100%',
|
|
||||||
height: '100%'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
Media.propTypes = {
|
|
||||||
media_attachments: PropTypes.arrayOf(propTypesAttachment),
|
|
||||||
sensitive: PropTypes.bool.isRequired,
|
|
||||||
width: PropTypes.number.isRequired
|
|
||||||
}
|
|
@ -8,7 +8,7 @@ import Avatar from './Toot/Avatar'
|
|||||||
import Header from './Toot/Header'
|
import Header from './Toot/Header'
|
||||||
import Content from './Toot/Content'
|
import Content from './Toot/Content'
|
||||||
import Poll from './Toot/Poll'
|
import Poll from './Toot/Poll'
|
||||||
import Media from './Toot/Media'
|
import Attachment from './Toot/Attachment'
|
||||||
import Card from './Toot/Card'
|
import Card from './Toot/Card'
|
||||||
import Actions from './Toot/Actions'
|
import Actions from './Toot/Actions'
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ export default function TootNotification ({ toot }) {
|
|||||||
)}
|
)}
|
||||||
{toot.status.poll && <Poll poll={toot.status.poll} />}
|
{toot.status.poll && <Poll poll={toot.status.poll} />}
|
||||||
{toot.status.media_attachments && (
|
{toot.status.media_attachments && (
|
||||||
<Media
|
<Attachment
|
||||||
media_attachments={toot.status.media_attachments}
|
media_attachments={toot.status.media_attachments}
|
||||||
sensitive={toot.status.sensitive}
|
sensitive={toot.status.sensitive}
|
||||||
width={Dimensions.get('window').width - 24 - 50 - 8}
|
width={Dimensions.get('window').width - 24 - 50 - 8}
|
||||||
|
@ -8,7 +8,7 @@ import Avatar from './Toot/Avatar'
|
|||||||
import Header from './Toot/Header'
|
import Header from './Toot/Header'
|
||||||
import Content from './Toot/Content'
|
import Content from './Toot/Content'
|
||||||
import Poll from './Toot/Poll'
|
import Poll from './Toot/Poll'
|
||||||
import Media from './Toot/Media'
|
import Attachment from './Toot/Attachment'
|
||||||
import Card from './Toot/Card'
|
import Card from './Toot/Card'
|
||||||
import Actions from './Toot/Actions'
|
import Actions from './Toot/Actions'
|
||||||
|
|
||||||
@ -50,9 +50,9 @@ export default function TootTimeline ({ toot }) {
|
|||||||
/>
|
/>
|
||||||
{/* Can pass toot info to next page to speed up performance */}
|
{/* Can pass toot info to next page to speed up performance */}
|
||||||
<Pressable
|
<Pressable
|
||||||
onPress={() =>
|
// onPress={() =>
|
||||||
navigation.navigate('Toot', { toot: actualContent.id })
|
// navigation.navigate('Toot', { toot: actualContent.id })
|
||||||
}
|
// }
|
||||||
>
|
>
|
||||||
{actualContent.content ? (
|
{actualContent.content ? (
|
||||||
<Content
|
<Content
|
||||||
@ -67,8 +67,8 @@ export default function TootTimeline ({ toot }) {
|
|||||||
<></>
|
<></>
|
||||||
)}
|
)}
|
||||||
{actualContent.poll && <Poll poll={actualContent.poll} />}
|
{actualContent.poll && <Poll poll={actualContent.poll} />}
|
||||||
{actualContent.media_attachments && (
|
{actualContent.media_attachments.length > 0 && (
|
||||||
<Media
|
<Attachment
|
||||||
media_attachments={actualContent.media_attachments}
|
media_attachments={actualContent.media_attachments}
|
||||||
sensitive={actualContent.sensitive}
|
sensitive={actualContent.sensitive}
|
||||||
width={Dimensions.get('window').width - 24 - 50 - 8}
|
width={Dimensions.get('window').width - 24 - 50 - 8}
|
||||||
|
@ -3,6 +3,7 @@ import { createNativeStackNavigator } from 'react-native-screens/native-stack'
|
|||||||
import { Feather } from '@expo/vector-icons'
|
import { Feather } from '@expo/vector-icons'
|
||||||
|
|
||||||
import Timeline from 'src/stacks/common/Timeline'
|
import Timeline from 'src/stacks/common/Timeline'
|
||||||
|
import sharedScreens from 'src/stacks/Shared/sharedScreens'
|
||||||
|
|
||||||
const Stack = createNativeStackNavigator()
|
const Stack = createNativeStackNavigator()
|
||||||
|
|
||||||
@ -28,6 +29,8 @@ export default function Notifications () {
|
|||||||
<Stack.Screen name='Notifications'>
|
<Stack.Screen name='Notifications'>
|
||||||
{() => <Timeline page='Notifications' />}
|
{() => <Timeline page='Notifications' />}
|
||||||
</Stack.Screen>
|
</Stack.Screen>
|
||||||
|
|
||||||
|
{sharedScreens(Stack)}
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
45
src/stacks/Shared/sharedScreens.jsx
Normal file
45
src/stacks/Shared/sharedScreens.jsx
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import React from 'react'
|
||||||
|
|
||||||
|
import Account from 'src/stacks/Shared/Account'
|
||||||
|
import Hashtag from 'src/stacks/Shared/Hashtag'
|
||||||
|
import Toot from 'src/stacks/Shared/Toot'
|
||||||
|
import Webview from 'src/stacks/Shared/Webview'
|
||||||
|
|
||||||
|
export default function sharedScreens (Stack) {
|
||||||
|
return [
|
||||||
|
<Stack.Screen
|
||||||
|
key='Account'
|
||||||
|
name='Account'
|
||||||
|
component={Account}
|
||||||
|
options={{
|
||||||
|
headerTranslucent: true,
|
||||||
|
headerStyle: { backgroundColor: 'rgba(255, 255, 255, 0)' },
|
||||||
|
headerCenter: () => {}
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
<Stack.Screen
|
||||||
|
key='Hashtag'
|
||||||
|
name='Hashtag'
|
||||||
|
component={Hashtag}
|
||||||
|
options={({ route }) => ({
|
||||||
|
title: `#${decodeURIComponent(route.params.hashtag)}`
|
||||||
|
})}
|
||||||
|
/>,
|
||||||
|
<Stack.Screen
|
||||||
|
key='Toot'
|
||||||
|
name='Toot'
|
||||||
|
component={Toot}
|
||||||
|
options={() => ({
|
||||||
|
title: '对话'
|
||||||
|
})}
|
||||||
|
/>,
|
||||||
|
<Stack.Screen
|
||||||
|
key='Webview'
|
||||||
|
name='Webview'
|
||||||
|
component={Webview}
|
||||||
|
// options={({ route }) => ({
|
||||||
|
// title: `${route.params.domain}`
|
||||||
|
// })}
|
||||||
|
/>
|
||||||
|
]
|
||||||
|
}
|
@ -22,10 +22,12 @@ export default function Timeline ({
|
|||||||
const [timelineReady, setTimelineReady] = useState(false)
|
const [timelineReady, setTimelineReady] = useState(false)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (state.status === 'idle') {
|
let mounted = true
|
||||||
|
if (state.status === 'idle' && mounted) {
|
||||||
dispatch(fetch({ page, hashtag, list, toot, account }))
|
dispatch(fetch({ page, hashtag, list, toot, account }))
|
||||||
setTimelineReady(true)
|
setTimelineReady(true)
|
||||||
}
|
}
|
||||||
|
return () => (mounted = false)
|
||||||
}, [state, dispatch])
|
}, [state, dispatch])
|
||||||
|
|
||||||
let content
|
let content
|
||||||
|
@ -6,10 +6,7 @@ import SegmentedControl from '@react-native-community/segmented-control'
|
|||||||
import { Feather } from '@expo/vector-icons'
|
import { Feather } from '@expo/vector-icons'
|
||||||
|
|
||||||
import Timeline from './Timeline'
|
import Timeline from './Timeline'
|
||||||
import Account from 'src/stacks/Shared/Account'
|
import sharedScreens from 'src/stacks/Shared/sharedScreens'
|
||||||
import Hashtag from 'src/stacks/Shared/Hashtag'
|
|
||||||
import Toot from 'src/stacks/Shared/Toot'
|
|
||||||
import Webview from 'src/stacks/Shared/Webview'
|
|
||||||
|
|
||||||
const Stack = createNativeStackNavigator()
|
const Stack = createNativeStackNavigator()
|
||||||
|
|
||||||
@ -93,36 +90,8 @@ export default function TimelinesCombined ({ name, content }) {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Stack.Screen>
|
</Stack.Screen>
|
||||||
<Stack.Screen
|
|
||||||
name='Account'
|
{sharedScreens(Stack)}
|
||||||
component={Account}
|
|
||||||
options={{
|
|
||||||
headerTranslucent: true,
|
|
||||||
headerStyle: { backgroundColor: 'rgba(255, 255, 255, 0)' },
|
|
||||||
headerCenter: () => {}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Stack.Screen
|
|
||||||
name='Hashtag'
|
|
||||||
component={Hashtag}
|
|
||||||
options={({ route }) => ({
|
|
||||||
title: `#${decodeURIComponent(route.params.hashtag)}`
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
<Stack.Screen
|
|
||||||
name='Toot'
|
|
||||||
component={Toot}
|
|
||||||
options={() => ({
|
|
||||||
title: '对话'
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
<Stack.Screen
|
|
||||||
name='Webview'
|
|
||||||
component={Webview}
|
|
||||||
// options={({ route }) => ({
|
|
||||||
// title: `${route.params.domain}`
|
|
||||||
// })}
|
|
||||||
/>
|
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user