From e261fa2a5178b662e44395981a9b89bd944b7ca2 Mon Sep 17 00:00:00 2001
From: AkiraFukushima
Date: Fri, 30 Aug 2024 23:53:32 +0900
Subject: [PATCH] Handle click in notification
---
.../timelines/notification/Notification.tsx | 10 ++-
.../timelines/notification/Reaction.tsx | 68 ++++++++++++++++++-
2 files changed, 76 insertions(+), 2 deletions(-)
diff --git a/renderer/components/timelines/notification/Notification.tsx b/renderer/components/timelines/notification/Notification.tsx
index 22ff51947f..a0cb310987 100644
--- a/renderer/components/timelines/notification/Notification.tsx
+++ b/renderer/components/timelines/notification/Notification.tsx
@@ -41,7 +41,15 @@ export default function Notification(props: Props) {
case 'emoji_reaction':
case 'reaction': {
if (props.notification.status) {
- return
+ return (
+
+ )
} else {
return null
}
diff --git a/renderer/components/timelines/notification/Reaction.tsx b/renderer/components/timelines/notification/Reaction.tsx
index 9a894e3a03..9374507e6f 100644
--- a/renderer/components/timelines/notification/Reaction.tsx
+++ b/renderer/components/timelines/notification/Reaction.tsx
@@ -5,15 +5,19 @@ import Body from '../status/Body'
import Poll from '../status/Poll'
import Card from '../status/Card'
import Media from '../status/Media'
+import { findAccount, findLink, ParsedAccount, accountMatch, findTag } from '@/utils/statusParser'
import { FaBarsProgress, FaHouse, FaPenToSquare, FaRetweet, FaStar } from 'react-icons/fa6'
import { FormattedMessage, useIntl } from 'react-intl'
import { MouseEventHandler, useState } from 'react'
import { Avatar, List, ListItem, Card as MaterialCard } from '@material-tailwind/react'
import { useRouter } from 'next/router'
+import { invoke } from '@/utils/invoke'
+import { Account } from '@/db'
type Props = {
notification: Entity.Notification
client: MegalodonInterface
+ account: Account
onRefresh: (status: Entity.Status) => void
openMedia: (media: Array, index: number) => void
}
@@ -37,6 +41,37 @@ export default function Reaction(props: Props) {
router.push({ query: { id: router.query.id, timeline: router.query.timeline, user_id: id, detail: true } })
}
+ const statusClicked: MouseEventHandler = async e => {
+ const parsedAccount = findAccount(e.target as HTMLElement, 'status-body')
+ if (parsedAccount) {
+ e.preventDefault()
+ e.stopPropagation()
+
+ const account = await searchAccount(parsedAccount, status, props.client, props.account.domain)
+ if (account) {
+ router.push({ query: { id: router.query.id, timeline: router.query.timeline, user_id: account.id, detail: true } })
+ } else {
+ console.warn('account not found', parsedAccount)
+ }
+ return
+ }
+
+ const parsedTag = findTag(e.target as HTMLElement, 'status-body')
+ if (parsedTag) {
+ e.preventDefault()
+ e.stopPropagation()
+ router.push({ query: { id: router.query.id, timeline: router.query.timeline, tag: parsedTag, detail: true } })
+ return
+ }
+
+ const url = findLink(e.target as HTMLElement, 'status-body')
+ if (url) {
+ invoke('open-browser', url)
+ e.preventDefault()
+ e.stopPropagation()
+ }
+ }
+
const onContextMenu: MouseEventHandler = e => {
e.preventDefault()
hideOthers()
@@ -116,7 +151,15 @@ export default function Reaction(props: Props) {
-
+
+
+
{!spoilered && (
<>
{status.poll && }
@@ -210,3 +253,26 @@ const actionId = (notification: Entity.Notification) => {
return ''
}
}
+
+async function searchAccount(account: ParsedAccount, status: Entity.Status, client: MegalodonInterface, domain: string) {
+ if (status.in_reply_to_account_id) {
+ const res = await client.getAccount(status.in_reply_to_account_id)
+ if (res.status === 200) {
+ const user = accountMatch([res.data], account, domain)
+ if (user) return user
+ }
+ }
+ if (status.in_reply_to_id) {
+ const res = await client.getStatusContext(status.id)
+ if (res.status === 200) {
+ const accounts: Array = res.data.ancestors.map(s => s.account).concat(res.data.descendants.map(s => s.account))
+ const user = accountMatch(accounts, account, domain)
+ if (user) return user
+ }
+ }
+ const res = await client.searchAccount(account.url, { resolve: true })
+ if (res.data.length === 0) return null
+ const user = accountMatch(res.data, account, domain)
+ if (user) return user
+ return null
+}