mirror of
https://github.com/tooot-app/app
synced 2025-06-05 22:19:13 +02:00
Transform into TypeScript
This commit is contained in:
@ -1,14 +1,23 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import propTypesEmoji from 'src/prop-types/emoji'
|
||||
import propTypesMention from 'src/prop-types/mention'
|
||||
import { StyleSheet, Text } from 'react-native'
|
||||
import HTMLView from 'react-native-htmlview'
|
||||
import HTMLView, { HTMLViewNode } from 'react-native-htmlview'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
|
||||
import Emojis from 'src/components/Toot/Emojis'
|
||||
|
||||
function renderNode ({ node, index, navigation, mentions, showFullLink }) {
|
||||
const renderNode = ({
|
||||
node,
|
||||
index,
|
||||
navigation,
|
||||
mentions,
|
||||
showFullLink
|
||||
}: {
|
||||
node: HTMLViewNode
|
||||
index: number
|
||||
navigation: object
|
||||
mentions?: mastodon.Mention[]
|
||||
showFullLink: boolean
|
||||
}) => {
|
||||
if (node.name == 'a') {
|
||||
const classes = node.attribs.class
|
||||
const href = node.attribs.href
|
||||
@ -69,27 +78,40 @@ function renderNode ({ node, index, navigation, mentions, showFullLink }) {
|
||||
}
|
||||
}
|
||||
|
||||
export default function ParseContent ({
|
||||
export interface Props {
|
||||
content: string
|
||||
emojis?: mastodon.Emoji[]
|
||||
emojiSize?: number
|
||||
mentions?: mastodon.Mention[]
|
||||
showFullLink?: boolean
|
||||
linesTruncated?: number
|
||||
}
|
||||
|
||||
const ParseContent: React.FC<Props> = ({
|
||||
content,
|
||||
emojis,
|
||||
emojiSize = 14,
|
||||
mentions,
|
||||
showFullLink = false,
|
||||
linesTruncated = 10
|
||||
}) {
|
||||
}) => {
|
||||
const navigation = useNavigation()
|
||||
|
||||
return (
|
||||
<HTMLView
|
||||
value={content}
|
||||
stylesheet={HTMLstyles}
|
||||
paragraphBreak={null}
|
||||
paragraphBreak=''
|
||||
renderNode={(node, index) =>
|
||||
renderNode({ node, index, navigation, mentions, showFullLink })
|
||||
}
|
||||
TextComponent={({ children }) => (
|
||||
<Emojis content={children} emojis={emojis} dimension={emojiSize} />
|
||||
)}
|
||||
TextComponent={({ children }) =>
|
||||
emojis ? (
|
||||
<Emojis content={children} emojis={emojis} dimension={emojiSize} />
|
||||
) : (
|
||||
<Text>{children}</Text>
|
||||
)
|
||||
}
|
||||
RootComponent={({ children }) => {
|
||||
return <Text numberOfLines={linesTruncated}>{children}</Text>
|
||||
}}
|
||||
@ -109,11 +131,4 @@ const HTMLstyles = StyleSheet.create({
|
||||
}
|
||||
})
|
||||
|
||||
ParseContent.propTypes = {
|
||||
content: PropTypes.string.isRequired,
|
||||
emojis: PropTypes.arrayOf(propTypesEmoji),
|
||||
emojiSize: PropTypes.number,
|
||||
mentions: PropTypes.arrayOf(propTypesMention),
|
||||
showFullLink: PropTypes.bool,
|
||||
linesTruncated: PropTypes.number
|
||||
}
|
||||
export default ParseContent
|
@ -1,17 +1,22 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import propTypesEmoji from 'src/prop-types/emoji'
|
||||
import { StyleSheet, Text, View } from 'react-native'
|
||||
import { Feather } from '@expo/vector-icons'
|
||||
|
||||
import Emojis from './Emojis'
|
||||
|
||||
export default function Actioned ({
|
||||
export interface Props {
|
||||
action: 'favourite' | 'follow' | 'mention' | 'poll' | 'reblog'
|
||||
name?: string
|
||||
emojis?: mastodon.Emoji[]
|
||||
notification?: boolean
|
||||
}
|
||||
|
||||
const Actioned: React.FC<Props> = ({
|
||||
action,
|
||||
name,
|
||||
emojis,
|
||||
notification = false
|
||||
}) {
|
||||
}) => {
|
||||
let icon
|
||||
let content
|
||||
switch (action) {
|
||||
@ -51,7 +56,11 @@ export default function Actioned ({
|
||||
{icon}
|
||||
{content ? (
|
||||
<View style={styles.content}>
|
||||
<Emojis content={content} emojis={emojis} dimension={12} />
|
||||
{emojis ? (
|
||||
<Emojis content={content} emojis={emojis} dimension={12} />
|
||||
) : (
|
||||
<Text>{content}</Text>
|
||||
)}
|
||||
</View>
|
||||
) : (
|
||||
<></>
|
||||
@ -74,10 +83,4 @@ const styles = StyleSheet.create({
|
||||
}
|
||||
})
|
||||
|
||||
Actioned.propTypes = {
|
||||
action: PropTypes.oneOf(['favourite', 'follow', 'mention', 'poll', 'reblog'])
|
||||
.isRequired,
|
||||
name: PropTypes.string,
|
||||
emojis: PropTypes.arrayOf(propTypesEmoji),
|
||||
notification: PropTypes.bool
|
||||
}
|
||||
export default Actioned
|
@ -1,18 +1,26 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Pressable, StyleSheet, Text, View } from 'react-native'
|
||||
import { Feather } from '@expo/vector-icons'
|
||||
|
||||
import action from 'src/components/action'
|
||||
|
||||
export default function Actions ({
|
||||
export interface Props {
|
||||
id: string
|
||||
replies_count: number
|
||||
reblogs_count: number
|
||||
reblogged?: boolean
|
||||
favourites_count: number
|
||||
favourited?: boolean
|
||||
}
|
||||
|
||||
const Actions: React.FC<Props> = ({
|
||||
id,
|
||||
replies_count,
|
||||
reblogs_count,
|
||||
reblogged,
|
||||
favourites_count,
|
||||
favourited
|
||||
}) {
|
||||
}) => {
|
||||
return (
|
||||
<View style={styles.actions}>
|
||||
<Pressable style={styles.action}>
|
||||
@ -23,7 +31,17 @@ export default function Actions ({
|
||||
<Feather name='repeat' />
|
||||
<Text>{reblogs_count}</Text>
|
||||
</Pressable>
|
||||
<Pressable style={styles.action} onPress={() => action('favourite', id)}>
|
||||
<Pressable
|
||||
style={styles.action}
|
||||
onPress={() =>
|
||||
action({
|
||||
id,
|
||||
type: 'favourite',
|
||||
stateKey: 'favourited',
|
||||
statePrev: favourited || false
|
||||
})
|
||||
}
|
||||
>
|
||||
<Feather name='heart' />
|
||||
<Text>{favourites_count}</Text>
|
||||
</Pressable>
|
||||
@ -49,11 +67,4 @@ const styles = StyleSheet.create({
|
||||
}
|
||||
})
|
||||
|
||||
Actions.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
replies_count: PropTypes.number.isRequired,
|
||||
reblogs_count: PropTypes.number.isRequired,
|
||||
reblogged: PropTypes.bool.isRequired,
|
||||
favourites_count: PropTypes.number.isRequired,
|
||||
favourited: PropTypes.bool.isRequired
|
||||
}
|
||||
export default Actions
|
@ -1,12 +1,20 @@
|
||||
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 }) {
|
||||
export interface Props {
|
||||
media_attachments: mastodon.Attachment[]
|
||||
sensitive: boolean
|
||||
width: number
|
||||
}
|
||||
|
||||
const Attachment: React.FC<Props> = ({
|
||||
media_attachments,
|
||||
sensitive,
|
||||
width
|
||||
}) => {
|
||||
let attachment
|
||||
let attachmentHeight
|
||||
// if (width) {}
|
||||
@ -74,8 +82,4 @@ export default function Attachment ({ media_attachments, sensitive, width }) {
|
||||
)
|
||||
}
|
||||
|
||||
Attachment.propTypes = {
|
||||
media_attachments: PropTypes.arrayOf(propTypesAttachment),
|
||||
sensitive: PropTypes.bool.isRequired,
|
||||
width: PropTypes.number.isRequired
|
||||
}
|
||||
export default Attachment
|
@ -1,10 +1,18 @@
|
||||
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 }) {
|
||||
export interface Props {
|
||||
media_attachments: mastodon.Attachment[]
|
||||
sensitive: boolean
|
||||
width: number
|
||||
}
|
||||
|
||||
const AttachmentImage: React.FC<Props> = ({
|
||||
media_attachments,
|
||||
sensitive,
|
||||
width
|
||||
}) => {
|
||||
const [mediaSensitive, setMediaSensitive] = useState(sensitive)
|
||||
const [imageModalVisible, setImageModalVisible] = useState(false)
|
||||
const [imageModalIndex, setImageModalIndex] = useState(0)
|
||||
@ -16,8 +24,8 @@ export default function AttachmentImage ({ media_attachments, sensitive, width }
|
||||
}
|
||||
}, [mediaSensitive])
|
||||
|
||||
let images = []
|
||||
media_attachments = media_attachments.map((m, i) => {
|
||||
let images: { url: string; width: number; height: number }[] = []
|
||||
const imagesNode = media_attachments.map((m, i) => {
|
||||
images.push({
|
||||
url: m.url,
|
||||
width: m.meta.original.width,
|
||||
@ -44,7 +52,7 @@ export default function AttachmentImage ({ media_attachments, sensitive, width }
|
||||
return (
|
||||
<>
|
||||
<View style={styles.media}>
|
||||
{media_attachments}
|
||||
{imagesNode}
|
||||
{mediaSensitive && (
|
||||
<View
|
||||
style={{
|
||||
@ -95,8 +103,4 @@ const styles = StyleSheet.create({
|
||||
}
|
||||
})
|
||||
|
||||
AttachmentImage.propTypes = {
|
||||
media_attachments: PropTypes.arrayOf(propTypesAttachment),
|
||||
sensitive: PropTypes.bool.isRequired,
|
||||
width: PropTypes.number.isRequired
|
||||
}
|
||||
export default AttachmentImage
|
@ -1,15 +1,19 @@
|
||||
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 ({
|
||||
export interface Props {
|
||||
media_attachments: mastodon.Attachment[]
|
||||
sensitive: boolean
|
||||
width: number
|
||||
}
|
||||
|
||||
const AttachmentVideo: React.FC<Props> = ({
|
||||
media_attachments,
|
||||
sensitive,
|
||||
width
|
||||
}) {
|
||||
}) => {
|
||||
const videoPlayer = useRef()
|
||||
const [mediaSensitive, setMediaSensitive] = useState(sensitive)
|
||||
const [videoPlay, setVideoPlay] = useState(false)
|
||||
@ -28,7 +32,7 @@ export default function AttachmentVideo ({
|
||||
>
|
||||
<Video
|
||||
ref={videoPlayer}
|
||||
source={{ uri: video.remote_url }}
|
||||
source={{ uri: video.remote_url || video.url }}
|
||||
style={{
|
||||
width: videoWidth,
|
||||
height: videoHeight
|
||||
@ -65,8 +69,4 @@ export default function AttachmentVideo ({
|
||||
)
|
||||
}
|
||||
|
||||
AttachmentVideo.propTypes = {
|
||||
media_attachments: PropTypes.arrayOf(propTypesAttachment),
|
||||
sensitive: PropTypes.bool.isRequired,
|
||||
width: PropTypes.number.isRequired
|
||||
}
|
||||
export default AttachmentVideo
|
@ -1,9 +1,13 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Image, Pressable, StyleSheet } from 'react-native'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
|
||||
export default function Avatar ({ uri, id }) {
|
||||
export interface Props {
|
||||
uri: string
|
||||
id: string
|
||||
}
|
||||
|
||||
const Avatar: React.FC<Props> = ({ uri, id }) => {
|
||||
const navigation = useNavigation()
|
||||
// Need to fix go back root
|
||||
return (
|
||||
@ -32,7 +36,4 @@ const styles = StyleSheet.create({
|
||||
}
|
||||
})
|
||||
|
||||
Avatar.propTypes = {
|
||||
uri: PropTypes.string.isRequired,
|
||||
id: PropTypes.string.isRequired
|
||||
}
|
||||
export default Avatar
|
@ -1,9 +1,12 @@
|
||||
import React from 'react'
|
||||
import propTypesCard from 'src/prop-types/card'
|
||||
import { Image, Pressable, StyleSheet, Text, View } from 'react-native'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
|
||||
export default function Card ({ card }) {
|
||||
export interface Props {
|
||||
card: mastodon.Card
|
||||
}
|
||||
|
||||
const Card: React.FC<Props> = ({ card }) => {
|
||||
const navigation = useNavigation()
|
||||
return (
|
||||
card && (
|
||||
@ -53,6 +56,4 @@ const styles = StyleSheet.create({
|
||||
}
|
||||
})
|
||||
|
||||
Card.propTypes = {
|
||||
card: propTypesCard
|
||||
}
|
||||
export default Card
|
@ -1,11 +1,22 @@
|
||||
import React, { useState } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { Text } from 'react-native'
|
||||
import Collapsible from 'react-native-collapsible'
|
||||
|
||||
import ParseContent from 'src/components/ParseContent'
|
||||
|
||||
export default function Content ({ content, emojis, mentions, spoiler_text }) {
|
||||
export interface Props {
|
||||
content: string
|
||||
emojis: mastodon.Emoji[]
|
||||
mentions: mastodon.Mention[]
|
||||
spoiler_text?: string
|
||||
}
|
||||
|
||||
const Content: React.FC<Props> = ({
|
||||
content,
|
||||
emojis,
|
||||
mentions,
|
||||
spoiler_text
|
||||
}) => {
|
||||
const [spoilerCollapsed, setSpoilerCollapsed] = useState(true)
|
||||
|
||||
return (
|
||||
@ -40,9 +51,4 @@ export default function Content ({ content, emojis, mentions, spoiler_text }) {
|
||||
)
|
||||
}
|
||||
|
||||
Content.propTypes = {
|
||||
content: ParseContent.propTypes.content,
|
||||
emojis: ParseContent.propTypes.emojis,
|
||||
mentions: ParseContent.propTypes.mentions,
|
||||
spoiler_text: PropTypes.string
|
||||
}
|
||||
export default Content
|
@ -1,49 +0,0 @@
|
||||
import React from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import propTypesEmoji from 'src/prop-types/emoji'
|
||||
import { Image, Text } from 'react-native'
|
||||
|
||||
const regexEmoji = new RegExp(/(:[a-z0-9_]+:)/)
|
||||
|
||||
export default function Emojis ({ content, emojis, dimension }) {
|
||||
const hasEmojis = content.match(regexEmoji)
|
||||
return hasEmojis ? (
|
||||
content.split(regexEmoji).map((str, i) => {
|
||||
if (str.match(regexEmoji)) {
|
||||
const emojiShortcode = str.split(regexEmoji)[1]
|
||||
const emojiIndex = emojis.findIndex(emoji => {
|
||||
return emojiShortcode === `:${emoji.shortcode}:`
|
||||
})
|
||||
return emojiIndex === -1 ? (
|
||||
<Text key={i} style={{ color: 'red' }}>
|
||||
Something wrong with emoji!
|
||||
</Text>
|
||||
) : (
|
||||
<Image
|
||||
key={i}
|
||||
source={{ uri: emojis[emojiIndex].url }}
|
||||
style={{ width: dimension, height: dimension }}
|
||||
/>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<Text
|
||||
key={i}
|
||||
style={{ fontSize: dimension, lineHeight: dimension + 1 }}
|
||||
>
|
||||
{str}
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
})
|
||||
) : (
|
||||
<Text style={{ fontSize: dimension, lineHeight: dimension + 1 }}>
|
||||
{content}
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
|
||||
Emojis.propTypes = {
|
||||
content: PropTypes.string.isRequired,
|
||||
emojis: PropTypes.arrayOf(propTypesEmoji)
|
||||
}
|
52
src/components/Toot/Emojis.tsx
Normal file
52
src/components/Toot/Emojis.tsx
Normal file
@ -0,0 +1,52 @@
|
||||
import React from 'react'
|
||||
import { Image, Text } from 'react-native'
|
||||
|
||||
const regexEmoji = new RegExp(/(:[a-z0-9_]+:)/)
|
||||
|
||||
export interface Props {
|
||||
content: string
|
||||
emojis: mastodon.Emoji[]
|
||||
dimension: number
|
||||
}
|
||||
|
||||
const Emojis: React.FC<Props> = ({ content, emojis, dimension }) => {
|
||||
const hasEmojis = content.match(regexEmoji)
|
||||
return hasEmojis ? (
|
||||
<>
|
||||
{content.split(regexEmoji).map((str, i) => {
|
||||
if (str.match(regexEmoji)) {
|
||||
const emojiShortcode = str.split(regexEmoji)[1]
|
||||
const emojiIndex = emojis.findIndex(emoji => {
|
||||
return emojiShortcode === `:${emoji.shortcode}:`
|
||||
})
|
||||
return emojiIndex === -1 ? (
|
||||
<Text key={i} style={{ color: 'red' }}>
|
||||
Something wrong with emoji!
|
||||
</Text>
|
||||
) : (
|
||||
<Image
|
||||
key={i}
|
||||
source={{ uri: emojis[emojiIndex].url }}
|
||||
style={{ width: dimension, height: dimension }}
|
||||
/>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<Text
|
||||
key={i}
|
||||
style={{ fontSize: dimension, lineHeight: dimension + 1 }}
|
||||
>
|
||||
{str}
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
})}
|
||||
</>
|
||||
) : (
|
||||
<Text style={{ fontSize: dimension, lineHeight: dimension + 1 }}>
|
||||
{content}
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
|
||||
export default Emojis
|
@ -1,17 +1,26 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { StyleSheet, Text, View } from 'react-native'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
|
||||
import Emojis from './Emojis'
|
||||
import relativeTime from 'src/utils/relativeTime'
|
||||
|
||||
export default function Header ({
|
||||
export interface Props {
|
||||
name: string
|
||||
emojis?: mastodon.Emoji[]
|
||||
account: string
|
||||
created_at: string
|
||||
application?: mastodon.Application
|
||||
}
|
||||
|
||||
const Header: React.FC<Props> = ({
|
||||
name,
|
||||
emojis,
|
||||
account,
|
||||
created_at,
|
||||
application
|
||||
}) {
|
||||
}) => {
|
||||
const navigation = useNavigation()
|
||||
const [since, setSince] = useState(relativeTime(created_at))
|
||||
|
||||
// causing full re-render
|
||||
@ -25,7 +34,11 @@ export default function Header ({
|
||||
<View>
|
||||
<View style={styles.names}>
|
||||
<View style={styles.name}>
|
||||
<Emojis content={name} emojis={emojis} dimension={14} />
|
||||
{emojis ? (
|
||||
<Emojis content={name} emojis={emojis} dimension={14} />
|
||||
) : (
|
||||
<Text>{name}</Text>
|
||||
)}
|
||||
</View>
|
||||
<Text style={styles.account} numberOfLines={1}>
|
||||
@{account}
|
||||
@ -38,7 +51,11 @@ export default function Header ({
|
||||
{application && application.name !== 'Web' && (
|
||||
<View>
|
||||
<Text
|
||||
onPress={() => Linking.openURL(application.website)}
|
||||
onPress={() => {
|
||||
navigation.navigate('Webview', {
|
||||
uri: application.website
|
||||
})
|
||||
}}
|
||||
style={styles.application}
|
||||
>
|
||||
{application.name}
|
||||
@ -78,13 +95,4 @@ const styles = StyleSheet.create({
|
||||
}
|
||||
})
|
||||
|
||||
Header.propTypes = {
|
||||
name: PropTypes.string.isRequired,
|
||||
emojis: Emojis.propTypes.emojis,
|
||||
account: PropTypes.string.isRequired,
|
||||
created_at: PropTypes.string.isRequired,
|
||||
application: PropTypes.exact({
|
||||
name: PropTypes.string.isRequired,
|
||||
website: PropTypes.string
|
||||
})
|
||||
}
|
||||
export default Header
|
@ -1,10 +1,13 @@
|
||||
import React from 'react'
|
||||
import propTypesPoll from 'src/prop-types/poll'
|
||||
import { StyleSheet, Text, View } from 'react-native'
|
||||
|
||||
import Emojis from './Emojis'
|
||||
|
||||
export default function Poll ({ poll }) {
|
||||
export interface Props {
|
||||
poll: mastodon.Poll
|
||||
}
|
||||
|
||||
const Poll: React.FC<Props> = ({ poll }) => {
|
||||
return (
|
||||
<View>
|
||||
{poll.options.map((option, index) => (
|
||||
@ -13,7 +16,11 @@ export default function Poll ({ poll }) {
|
||||
<Text>
|
||||
{Math.round((option.votes_count / poll.votes_count) * 100)}%
|
||||
</Text>
|
||||
<Text>{option.title}</Text>
|
||||
<Emojis
|
||||
content={option.title}
|
||||
emojis={poll.emojis}
|
||||
dimension={14}
|
||||
/>
|
||||
</View>
|
||||
<View
|
||||
style={{
|
||||
@ -42,6 +49,4 @@ const styles = StyleSheet.create({
|
||||
}
|
||||
})
|
||||
|
||||
Poll.propTypes = {
|
||||
poll: propTypesPoll
|
||||
}
|
||||
export default Poll
|
@ -1,5 +1,4 @@
|
||||
import React, { useMemo } from 'react'
|
||||
import propTypesNotification from 'src/prop-types/notification'
|
||||
import { Dimensions, Pressable, StyleSheet, Text, View } from 'react-native'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
|
||||
@ -12,7 +11,11 @@ import Attachment from './Toot/Attachment'
|
||||
import Card from './Toot/Card'
|
||||
import Actions from './Toot/Actions'
|
||||
|
||||
export default function TootNotification ({ toot }) {
|
||||
export interface Props {
|
||||
toot: mastodon.Notification
|
||||
}
|
||||
|
||||
const TootNotification: React.FC<Props> = ({ toot }) => {
|
||||
const navigation = useNavigation()
|
||||
const actualAccount = toot.status ? toot.status.account : toot.account
|
||||
|
||||
@ -46,8 +49,8 @@ export default function TootNotification ({ toot }) {
|
||||
emojis={toot.status.emojis}
|
||||
mentions={toot.status.mentions}
|
||||
spoiler_text={toot.status.spoiler_text}
|
||||
tags={toot.status.tags}
|
||||
style={{ flex: 1 }}
|
||||
// tags={toot.status.tags}
|
||||
// style={{ flex: 1 }}
|
||||
/>
|
||||
)}
|
||||
{toot.status.poll && <Poll poll={toot.status.poll} />}
|
||||
@ -99,6 +102,4 @@ const styles = StyleSheet.create({
|
||||
}
|
||||
})
|
||||
|
||||
TootNotification.propTypes = {
|
||||
toot: propTypesNotification
|
||||
}
|
||||
export default TootNotification
|
@ -1,5 +1,4 @@
|
||||
import React, { useMemo } from 'react'
|
||||
import propTypesStatus from 'src/prop-types/status'
|
||||
import { Dimensions, Pressable, StyleSheet, View } from 'react-native'
|
||||
import { useNavigation } from '@react-navigation/native'
|
||||
|
||||
@ -12,15 +11,14 @@ import Attachment from './Toot/Attachment'
|
||||
import Card from './Toot/Card'
|
||||
import Actions from './Toot/Actions'
|
||||
|
||||
export default function TootTimeline ({ toot }) {
|
||||
export interface Props {
|
||||
toot: mastodon.Status
|
||||
}
|
||||
|
||||
const TootTimeline: React.FC<Props> = ({ toot }) => {
|
||||
const navigation = useNavigation()
|
||||
|
||||
let actualContent
|
||||
if (toot.reblog) {
|
||||
actualContent = toot.reblog
|
||||
} else {
|
||||
actualContent = toot
|
||||
}
|
||||
let actualContent = toot.reblog ? toot.reblog : toot
|
||||
|
||||
const tootView = useMemo(() => {
|
||||
return (
|
||||
@ -60,8 +58,8 @@ export default function TootTimeline ({ toot }) {
|
||||
emojis={actualContent.emojis}
|
||||
mentions={actualContent.mentions}
|
||||
spoiler_text={actualContent.spoiler_text}
|
||||
tags={actualContent.tags}
|
||||
style={{ flex: 1 }}
|
||||
// tags={actualContent.tags}
|
||||
// style={{ flex: 1 }}
|
||||
/>
|
||||
) : (
|
||||
<></>
|
||||
@ -88,7 +86,7 @@ export default function TootTimeline ({ toot }) {
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
})
|
||||
}, [toot])
|
||||
|
||||
return tootView
|
||||
}
|
||||
@ -109,6 +107,4 @@ const styles = StyleSheet.create({
|
||||
}
|
||||
})
|
||||
|
||||
TootTimeline.propTypes = {
|
||||
toot: propTypesStatus
|
||||
}
|
||||
export default TootTimeline
|
@ -1,63 +0,0 @@
|
||||
import { Alert } from 'react-native'
|
||||
import { useSelector } from 'react-redux'
|
||||
|
||||
import { client } from 'src/api/client'
|
||||
|
||||
export default async function action (type, id) {
|
||||
// If header if needed for remote server
|
||||
const header = {
|
||||
headers: {
|
||||
Authorization: `Bearer ${useSelector(
|
||||
state => state.instanceInfo.localToken
|
||||
)}`
|
||||
}
|
||||
}
|
||||
const instance = `https://${useSelector(
|
||||
state => state.instanceInfo.local
|
||||
)}/api/v1/`
|
||||
|
||||
let endpoint
|
||||
switch (type) {
|
||||
case 'favourite':
|
||||
endpoint = `${instance}statuses/${id}/favourite`
|
||||
break
|
||||
case 'unfavourite':
|
||||
endpoint = `${instance}statuses/${id}/unfavourite`
|
||||
break
|
||||
case 'reblog':
|
||||
endpoint = `${instance}statuses/${id}/reblog`
|
||||
break
|
||||
case 'unreblog':
|
||||
endpoint = `${instance}statuses/${id}/unreblog`
|
||||
break
|
||||
case 'bookmark':
|
||||
endpoint = `${instance}statuses/${id}/bookmark`
|
||||
break
|
||||
case 'unbookmark':
|
||||
endpoint = `${instance}statuses/${id}/unbookmark`
|
||||
break
|
||||
case 'mute':
|
||||
endpoint = `${instance}statuses/${id}/mute`
|
||||
break
|
||||
case 'unmute':
|
||||
endpoint = `${instance}statuses/${id}/unmute`
|
||||
break
|
||||
case 'pin':
|
||||
endpoint = `${instance}statuses/${id}/pin`
|
||||
break
|
||||
case 'unpin':
|
||||
endpoint = `${instance}statuses/${id}/unpin`
|
||||
break
|
||||
}
|
||||
|
||||
const res = await client.post(endpoint, [], header)
|
||||
console.log(res)
|
||||
|
||||
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') }
|
||||
])
|
||||
}
|
41
src/components/action.ts
Normal file
41
src/components/action.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import { Alert } from 'react-native'
|
||||
|
||||
import client from 'src/api/client'
|
||||
|
||||
export interface params {
|
||||
id: string
|
||||
}
|
||||
|
||||
const action = async ({
|
||||
id,
|
||||
type,
|
||||
stateKey,
|
||||
statePrev
|
||||
}: {
|
||||
id: string
|
||||
type: 'favourite' | 'reblog' | 'bookmark' | 'mute' | 'pin'
|
||||
stateKey: 'favourited' | 'reblogged' | 'bookmarked' | 'muted' | 'pinned'
|
||||
statePrev: boolean
|
||||
}): Promise<void> => {
|
||||
const alert = {
|
||||
title: 'This is a title',
|
||||
message: 'This is a message'
|
||||
}
|
||||
|
||||
const res = await client({
|
||||
method: 'post',
|
||||
instance: 'local',
|
||||
endpoint: `statuses/${id}/${statePrev ? 'un' : ''}${type}`
|
||||
})
|
||||
|
||||
if (!res.body[stateKey] === statePrev) {
|
||||
// Update redux
|
||||
console.log('OK!!!')
|
||||
} else {
|
||||
Alert.alert(alert.title, alert.message, [
|
||||
{ text: 'OK', onPress: () => console.log('OK Pressed') }
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
export default action
|
Reference in New Issue
Block a user