From a41871ae4b0aa7dd54f22046ca9387cd4a042f29 Mon Sep 17 00:00:00 2001 From: Lim Chee Aun Date: Wed, 29 Mar 2023 01:12:59 +0800 Subject: [PATCH] Experimental feature: translate bio --- src/components/account-info.jsx | 54 +++++++++++++++++++++++++++++++-- src/components/status.jsx | 13 +------- src/utils/getHTMLText.jsx | 13 ++++++++ src/utils/status-peek.jsx | 2 +- 4 files changed, 67 insertions(+), 15 deletions(-) create mode 100644 src/utils/getHTMLText.jsx diff --git a/src/components/account-info.jsx b/src/components/account-info.jsx index 11c2d9ea..a7fa85c2 100644 --- a/src/components/account-info.jsx +++ b/src/components/account-info.jsx @@ -9,10 +9,10 @@ import { } from '@szhsin/react-menu'; import { useEffect, useRef, useState } from 'preact/hooks'; -import RelativeTime from '../components/relative-time'; import { api } from '../utils/api'; import emojifyText from '../utils/emojify-text'; import enhanceContent from '../utils/enhance-content'; +import getHTMLText from '../utils/getHTMLText'; import handleContentLinks from '../utils/handle-content-links'; import niceDateTime from '../utils/nice-date-time'; import shortenNumber from '../utils/shorten-number'; @@ -24,6 +24,8 @@ import AccountBlock from './account-block'; import Avatar from './avatar'; import Icon from './icon'; import Link from './link'; +import Modal from './modal'; +import TranslationBlock from './translation-block'; const MUTE_DURATIONS = [ 1000 * 60 * 5, // 5 minutes @@ -389,7 +391,7 @@ function RelatedActions({ info, instance, authenticated }) { const [relationship, setRelationship] = useState(null); const [familiarFollowers, setFamiliarFollowers] = useState([]); - const { id, acct, url, username, locked, lastStatusAt } = info; + const { id, acct, url, username, locked, lastStatusAt, note, fields } = info; const accountID = useRef(id); const { @@ -484,6 +486,8 @@ function RelatedActions({ info, instance, authenticated }) { const loading = relationshipUIState === 'loading'; const menuInstanceRef = useRef(null); + const [showTranslatedBio, setShowTranslatedBio] = useState(false); + return ( <> {familiarFollowers?.length > 0 && ( @@ -571,6 +575,14 @@ function RelatedActions({ info, instance, authenticated }) { Mention @{username} + { + setShowTranslatedBio(true); + }} + > + + Translate bio + )} @@ -816,6 +828,18 @@ function RelatedActions({ info, instance, authenticated }) { )}

+ {!!showTranslatedBio && ( + { + if (e.target === e.currentTarget) { + setShowTranslatedBio(false); + } + }} + > + + + )} ); } @@ -850,4 +874,30 @@ function niceAccountURL(url) { ); } +function TranslatedBioSheet({ note, fields }) { + const fieldsText = + fields + ?.map(({ name, value }) => `${name}\n${getHTMLText(value)}`) + .join('\n\n') || ''; + + const text = getHTMLText(note) + (fieldsText ? `\n\n${fieldsText}` : ''); + + return ( +
+
+

Translated Bio

+
+
+

+ {text} +

+ +
+
+ ); +} export default AccountInfo; diff --git a/src/components/status.jsx b/src/components/status.jsx index 1831e195..3dc9c2b0 100644 --- a/src/components/status.jsx +++ b/src/components/status.jsx @@ -25,6 +25,7 @@ import NameText from '../components/name-text'; import { api } from '../utils/api'; import enhanceContent from '../utils/enhance-content'; import getTranslateTargetLanguage from '../utils/get-translate-target-language'; +import getHTMLText from '../utils/getHTMLText'; import handleContentLinks from '../utils/handle-content-links'; import htmlContentLength from '../utils/html-content-length'; import niceDateTime from '../utils/nice-date-time'; @@ -1695,18 +1696,6 @@ function nicePostURL(url) { const unfurlMastodonLink = throttle(_unfurlMastodonLink); -const div = document.createElement('div'); -export function getHTMLText(html) { - if (!html) return ''; - div.innerHTML = html - .replace(/<\/p>/g, '

\n\n') - .replace(/<\/li>/g, '\n'); - div.querySelectorAll('br').forEach((br) => { - br.replaceWith('\n'); - }); - return div.innerText.replace(/[\r\n]{3,}/g, '\n\n').trim(); -} - const root = document.documentElement; const defaultBoundingBoxPadding = 8; function safeBoundingBoxPadding() { diff --git a/src/utils/getHTMLText.jsx b/src/utils/getHTMLText.jsx new file mode 100644 index 00000000..fc03b647 --- /dev/null +++ b/src/utils/getHTMLText.jsx @@ -0,0 +1,13 @@ +const div = document.createElement('div'); +function getHTMLText(html) { + if (!html) return ''; + div.innerHTML = html + .replace(/<\/p>/g, '

\n\n') + .replace(/<\/li>/g, '\n'); + div.querySelectorAll('br').forEach((br) => { + br.replaceWith('\n'); + }); + return div.innerText.replace(/[\r\n]{3,}/g, '\n\n').trim(); +} + +export default getHTMLText; diff --git a/src/utils/status-peek.jsx b/src/utils/status-peek.jsx index 2e3b084e..6d9bd3ff 100644 --- a/src/utils/status-peek.jsx +++ b/src/utils/status-peek.jsx @@ -1,4 +1,4 @@ -import { getHTMLText } from '../components/status'; +import getHTMLText from './getHTMLText'; function statusPeek(status) { const { spoilerText, content, poll, mediaAttachments } = status;