mirror of
https://github.com/tooot-app/app
synced 2025-04-11 00:51:21 +02:00
Continue to improve #535
This commit is contained in:
parent
17d4245cd9
commit
6e8515d820
49
src/@types/mastodon.d.ts
vendored
49
src/@types/mastodon.d.ts
vendored
@ -333,23 +333,33 @@ declare namespace Mastodon {
|
|||||||
url: string
|
url: string
|
||||||
}
|
}
|
||||||
|
|
||||||
type Notification = {
|
type Notification =
|
||||||
|
| {
|
||||||
// Base
|
// Base
|
||||||
id: string
|
id: string
|
||||||
type:
|
type: 'favourite' | 'mention' | 'poll' | 'reblog' | 'status' | 'update'
|
||||||
| 'follow'
|
|
||||||
| 'follow_request'
|
|
||||||
| 'mention'
|
|
||||||
| 'reblog'
|
|
||||||
| 'favourite'
|
|
||||||
| 'poll'
|
|
||||||
| 'status'
|
|
||||||
| 'update'
|
|
||||||
created_at: string
|
created_at: string
|
||||||
account: Account
|
account: Account
|
||||||
|
status: Status
|
||||||
// Others
|
report: undefined
|
||||||
status?: Status
|
}
|
||||||
|
| {
|
||||||
|
// Base
|
||||||
|
id: string
|
||||||
|
type: 'follow' | 'follow_request' | 'admin.sign_up'
|
||||||
|
created_at: string
|
||||||
|
account: Account
|
||||||
|
status: undefined
|
||||||
|
report: undefined
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
// Base
|
||||||
|
id: string
|
||||||
|
type: 'admin.report'
|
||||||
|
created_at: string
|
||||||
|
account: Account
|
||||||
|
status: undefined
|
||||||
|
report: Report
|
||||||
}
|
}
|
||||||
|
|
||||||
type Poll = {
|
type Poll = {
|
||||||
@ -406,6 +416,19 @@ declare namespace Mastodon {
|
|||||||
note: string
|
note: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Report = {
|
||||||
|
id: string
|
||||||
|
action_taken: boolean
|
||||||
|
action_taken_at?: string
|
||||||
|
category: 'spam' | 'violation' | 'other'
|
||||||
|
comment: string
|
||||||
|
forwarded: boolean
|
||||||
|
created_at: string
|
||||||
|
status_ids?: string[]
|
||||||
|
rule_ids?: string[]
|
||||||
|
target_account: Account
|
||||||
|
}
|
||||||
|
|
||||||
type Results = {
|
type Results = {
|
||||||
accounts?: Account[]
|
accounts?: Account[]
|
||||||
statuses?: Status[]
|
statuses?: Status[]
|
||||||
|
@ -28,18 +28,18 @@ import TimelineHeaderAndroid from './Shared/HeaderAndroid'
|
|||||||
export interface Props {
|
export interface Props {
|
||||||
notification: Mastodon.Notification
|
notification: Mastodon.Notification
|
||||||
queryKey: QueryKeyTimeline
|
queryKey: QueryKeyTimeline
|
||||||
highlighted?: boolean
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const TimelineNotifications: React.FC<Props> = ({
|
const TimelineNotifications: React.FC<Props> = ({ notification, queryKey }) => {
|
||||||
notification,
|
|
||||||
queryKey,
|
|
||||||
highlighted = false
|
|
||||||
}) => {
|
|
||||||
const instanceAccount = useSelector(getInstanceAccount, () => true)
|
const instanceAccount = useSelector(getInstanceAccount, () => true)
|
||||||
|
|
||||||
const status = notification.status?.reblog ? notification.status.reblog : notification.status
|
const status = notification.status?.reblog ? notification.status.reblog : notification.status
|
||||||
const account = notification.status ? notification.status.account : notification.account
|
const account =
|
||||||
|
notification.type === 'admin.report'
|
||||||
|
? notification.report.target_account
|
||||||
|
: notification.status
|
||||||
|
? notification.status.account
|
||||||
|
: notification.account
|
||||||
const ownAccount = notification.account?.id === instanceAccount?.id
|
const ownAccount = notification.account?.id === instanceAccount?.id
|
||||||
const [spoilerExpanded, setSpoilerExpanded] = useState(
|
const [spoilerExpanded, setSpoilerExpanded] = useState(
|
||||||
instanceAccount.preferences['reading:expand:spoilers'] || false
|
instanceAccount.preferences['reading:expand:spoilers'] || false
|
||||||
@ -91,7 +91,8 @@ const TimelineNotifications: React.FC<Props> = ({
|
|||||||
notification.type === 'follow' ||
|
notification.type === 'follow' ||
|
||||||
notification.type === 'follow_request' ||
|
notification.type === 'follow_request' ||
|
||||||
notification.type === 'mention' ||
|
notification.type === 'mention' ||
|
||||||
notification.type === 'status'
|
notification.type === 'status' ||
|
||||||
|
notification.type === 'admin.sign_up'
|
||||||
? 1
|
? 1
|
||||||
: 0.5
|
: 0.5
|
||||||
}}
|
}}
|
||||||
@ -102,12 +103,7 @@ const TimelineNotifications: React.FC<Props> = ({
|
|||||||
</View>
|
</View>
|
||||||
|
|
||||||
{notification.status ? (
|
{notification.status ? (
|
||||||
<View
|
<View style={{ paddingLeft: StyleConstants.Avatar.M + StyleConstants.Spacing.S }}>
|
||||||
style={{
|
|
||||||
paddingTop: highlighted ? StyleConstants.Spacing.S : 0,
|
|
||||||
paddingLeft: highlighted ? 0 : StyleConstants.Avatar.M + StyleConstants.Spacing.S
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<TimelineContent
|
<TimelineContent
|
||||||
notificationOwnToot={['favourite', 'reblog'].includes(notification.type)}
|
notificationOwnToot={['favourite', 'reblog'].includes(notification.type)}
|
||||||
setSpoilerExpanded={setSpoilerExpanded}
|
setSpoilerExpanded={setSpoilerExpanded}
|
||||||
@ -141,8 +137,7 @@ const TimelineNotifications: React.FC<Props> = ({
|
|||||||
status,
|
status,
|
||||||
ownAccount,
|
ownAccount,
|
||||||
spoilerHidden,
|
spoilerHidden,
|
||||||
copiableContent,
|
copiableContent
|
||||||
highlighted
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<ContextMenu.Root>
|
<ContextMenu.Root>
|
||||||
|
@ -28,7 +28,12 @@ const TimelineActioned: React.FC<Props> = ({ action, isNotification, ...rest })
|
|||||||
const iconColor = colors.primaryDefault
|
const iconColor = colors.primaryDefault
|
||||||
|
|
||||||
const content = (content: string) => (
|
const content = (content: string) => (
|
||||||
<ParseEmojis content={content} emojis={account.emojis} size='S' />
|
<ParseEmojis
|
||||||
|
content={content}
|
||||||
|
emojis={account.emojis}
|
||||||
|
size='S'
|
||||||
|
style={{ color: action === 'admin.report' ? colors.red : colors.primaryDefault }}
|
||||||
|
/>
|
||||||
)
|
)
|
||||||
|
|
||||||
const onPress = () => navigation.push('Tab-Shared-Account', { account })
|
const onPress = () => navigation.push('Tab-Shared-Account', { account })
|
||||||
@ -145,6 +150,30 @@ const TimelineActioned: React.FC<Props> = ({ action, isNotification, ...rest })
|
|||||||
{content(t('shared.actioned.update'))}
|
{content(t('shared.actioned.update'))}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
case 'admin.sign_up':
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Icon
|
||||||
|
name='Users'
|
||||||
|
size={StyleConstants.Font.Size.S}
|
||||||
|
color={iconColor}
|
||||||
|
style={styles.icon}
|
||||||
|
/>
|
||||||
|
{content(t('shared.actioned.admin.sign_up', { name: `@${account.acct}` }))}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
case 'admin.report':
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Icon
|
||||||
|
name='AlertOctagon'
|
||||||
|
size={StyleConstants.Font.Size.S}
|
||||||
|
color={colors.red}
|
||||||
|
style={styles.icon}
|
||||||
|
/>
|
||||||
|
{content(t('shared.actioned.admin.report', { name: `@${account.acct}` }))}
|
||||||
|
</>
|
||||||
|
)
|
||||||
default:
|
default:
|
||||||
return <></>
|
return <></>
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,19 @@
|
|||||||
|
import Button from '@components/Button'
|
||||||
import menuAccount from '@components/contextMenu/account'
|
import menuAccount from '@components/contextMenu/account'
|
||||||
import menuInstance from '@components/contextMenu/instance'
|
import menuInstance from '@components/contextMenu/instance'
|
||||||
import menuShare from '@components/contextMenu/share'
|
import menuShare from '@components/contextMenu/share'
|
||||||
import menuStatus from '@components/contextMenu/status'
|
import menuStatus from '@components/contextMenu/status'
|
||||||
import Icon from '@components/Icon'
|
import Icon from '@components/Icon'
|
||||||
import { RelationshipIncoming, RelationshipOutgoing } from '@components/Relationship'
|
import { RelationshipIncoming, RelationshipOutgoing } from '@components/Relationship'
|
||||||
|
import browserPackage from '@helpers/browserPackage'
|
||||||
|
import { getInstanceUrl } from '@utils/slices/instancesSlice'
|
||||||
import { StyleConstants } from '@utils/styles/constants'
|
import { StyleConstants } from '@utils/styles/constants'
|
||||||
import { useTheme } from '@utils/styles/ThemeManager'
|
import { useTheme } from '@utils/styles/ThemeManager'
|
||||||
|
import * as WebBrowser from 'expo-web-browser'
|
||||||
import React, { useContext, useState } from 'react'
|
import React, { useContext, useState } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
import { Platform, Pressable, View } from 'react-native'
|
import { Platform, Pressable, View } from 'react-native'
|
||||||
|
import { useSelector } from 'react-redux'
|
||||||
import * as DropdownMenu from 'zeego/dropdown-menu'
|
import * as DropdownMenu from 'zeego/dropdown-menu'
|
||||||
import StatusContext from './Context'
|
import StatusContext from './Context'
|
||||||
import HeaderSharedAccount from './HeaderShared/Account'
|
import HeaderSharedAccount from './HeaderShared/Account'
|
||||||
@ -21,6 +27,7 @@ export type Props = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const TimelineHeaderNotification: React.FC<Props> = ({ notification }) => {
|
const TimelineHeaderNotification: React.FC<Props> = ({ notification }) => {
|
||||||
|
const { t } = useTranslation('componentTimeline')
|
||||||
const { queryKey, status } = useContext(StatusContext)
|
const { queryKey, status } = useContext(StatusContext)
|
||||||
|
|
||||||
const { colors } = useTheme()
|
const { colors } = useTheme()
|
||||||
@ -40,12 +47,32 @@ const TimelineHeaderNotification: React.FC<Props> = ({ notification }) => {
|
|||||||
const mStatus = menuStatus({ status, queryKey })
|
const mStatus = menuStatus({ status, queryKey })
|
||||||
const mInstance = menuInstance({ status, queryKey })
|
const mInstance = menuInstance({ status, queryKey })
|
||||||
|
|
||||||
|
const url = useSelector(getInstanceUrl)
|
||||||
|
|
||||||
const actions = () => {
|
const actions = () => {
|
||||||
switch (notification.type) {
|
switch (notification.type) {
|
||||||
case 'follow':
|
case 'follow':
|
||||||
return <RelationshipOutgoing id={notification.account.id} />
|
return <RelationshipOutgoing id={notification.account.id} />
|
||||||
case 'follow_request':
|
case 'follow_request':
|
||||||
return <RelationshipIncoming id={notification.account.id} />
|
return <RelationshipIncoming id={notification.account.id} />
|
||||||
|
case 'admin.report':
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
type='text'
|
||||||
|
content={t('shared.actions.openReport')}
|
||||||
|
onPress={async () =>
|
||||||
|
WebBrowser.openAuthSessionAsync(
|
||||||
|
`https://${url}/admin/reports/${notification.report.id}`,
|
||||||
|
'tooot://tooot',
|
||||||
|
{
|
||||||
|
browserPackage: await browserPackage(),
|
||||||
|
dismissButtonStyle: 'done',
|
||||||
|
readerMode: false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
)
|
||||||
default:
|
default:
|
||||||
if (status) {
|
if (status) {
|
||||||
return (
|
return (
|
||||||
@ -118,12 +145,25 @@ const TimelineHeaderNotification: React.FC<Props> = ({ notification }) => {
|
|||||||
<View style={{ flex: 1, flexDirection: 'row' }}>
|
<View style={{ flex: 1, flexDirection: 'row' }}>
|
||||||
<View
|
<View
|
||||||
style={{
|
style={{
|
||||||
flex: notification.type === 'follow' || notification.type === 'follow_request' ? 1 : 4
|
flex:
|
||||||
|
notification.type === 'follow' ||
|
||||||
|
notification.type === 'follow_request' ||
|
||||||
|
notification.type === 'admin.report'
|
||||||
|
? 1
|
||||||
|
: 4
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<HeaderSharedAccount
|
<HeaderSharedAccount
|
||||||
account={notification.status ? notification.status.account : notification.account}
|
account={
|
||||||
{...((notification.type === 'follow' || notification.type === 'follow_request') && {
|
notification.type === 'admin.report'
|
||||||
|
? notification.report.target_account
|
||||||
|
: notification.status
|
||||||
|
? notification.status.account
|
||||||
|
: notification.account
|
||||||
|
}
|
||||||
|
{...((notification.type === 'follow' ||
|
||||||
|
notification.type === 'follow_request' ||
|
||||||
|
notification.type === 'admin.report') && {
|
||||||
withoutName: true
|
withoutName: true
|
||||||
})}
|
})}
|
||||||
/>
|
/>
|
||||||
@ -151,7 +191,9 @@ const TimelineHeaderNotification: React.FC<Props> = ({ notification }) => {
|
|||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
{ marginLeft: StyleConstants.Spacing.M },
|
{ marginLeft: StyleConstants.Spacing.M },
|
||||||
notification.type === 'follow' || notification.type === 'follow_request'
|
notification.type === 'follow' ||
|
||||||
|
notification.type === 'follow_request' ||
|
||||||
|
notification.type === 'admin.report'
|
||||||
? { flexShrink: 1 }
|
? { flexShrink: 1 }
|
||||||
: { flex: 1 }
|
: { flex: 1 }
|
||||||
]}
|
]}
|
||||||
|
@ -30,7 +30,9 @@
|
|||||||
"default": "{{name}} boosted",
|
"default": "{{name}} boosted",
|
||||||
"notification": "{{name}} boosted your toot"
|
"notification": "{{name}} boosted your toot"
|
||||||
},
|
},
|
||||||
"update": "Reblog has been edited"
|
"update": "Reblog has been edited",
|
||||||
|
"admin.sign_up": "{{name}} joined the instance",
|
||||||
|
"admin.report": "{{name}} reported:"
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
"reply": {
|
"reply": {
|
||||||
@ -52,7 +54,8 @@
|
|||||||
"bookmarked": {
|
"bookmarked": {
|
||||||
"accessibilityLabel": "Add this toot to bookmarks",
|
"accessibilityLabel": "Add this toot to bookmarks",
|
||||||
"function": "Bookmark toot"
|
"function": "Bookmark toot"
|
||||||
}
|
},
|
||||||
|
"openReport": "Open report"
|
||||||
},
|
},
|
||||||
"actionsUsers": {
|
"actionsUsers": {
|
||||||
"reblogged_by": {
|
"reblogged_by": {
|
||||||
|
@ -180,7 +180,7 @@ const ScreenImagesViewer = ({
|
|||||||
options: [
|
options: [
|
||||||
t('content.options.save'),
|
t('content.options.save'),
|
||||||
t('content.options.share'),
|
t('content.options.share'),
|
||||||
t('content.options.cancel')
|
t('common:buttons.cancel')
|
||||||
],
|
],
|
||||||
cancelButtonIndex: 2,
|
cancelButtonIndex: 2,
|
||||||
userInterfaceStyle: mode
|
userInterfaceStyle: mode
|
||||||
|
Loading…
x
Reference in New Issue
Block a user