mirror of
https://github.com/cheeaun/phanpy.git
synced 2024-11-25 18:55:44 +03:00
Experimental feature: translate bio
This commit is contained in:
parent
9fc8154237
commit
a41871ae4b
4 changed files with 67 additions and 15 deletions
|
@ -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 }) {
|
|||
<Icon icon="at" />
|
||||
<span>Mention @{username}</span>
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
onClick={() => {
|
||||
setShowTranslatedBio(true);
|
||||
}}
|
||||
>
|
||||
<Icon icon="translate" />
|
||||
<span>Translate bio</span>
|
||||
</MenuItem>
|
||||
<MenuDivider />
|
||||
</>
|
||||
)}
|
||||
|
@ -816,6 +828,18 @@ function RelatedActions({ info, instance, authenticated }) {
|
|||
)}
|
||||
</span>
|
||||
</p>
|
||||
{!!showTranslatedBio && (
|
||||
<Modal
|
||||
class="light"
|
||||
onClick={(e) => {
|
||||
if (e.target === e.currentTarget) {
|
||||
setShowTranslatedBio(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<TranslatedBioSheet note={note} fields={fields} />
|
||||
</Modal>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -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 (
|
||||
<div class="sheet">
|
||||
<header>
|
||||
<h2>Translated Bio</h2>
|
||||
</header>
|
||||
<main>
|
||||
<p
|
||||
style={{
|
||||
whiteSpace: 'pre-wrap',
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
</p>
|
||||
<TranslationBlock forceTranslate text={text} />
|
||||
</main>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export default AccountInfo;
|
||||
|
|
|
@ -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, '</p>\n\n')
|
||||
.replace(/<\/li>/g, '</li>\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() {
|
||||
|
|
13
src/utils/getHTMLText.jsx
Normal file
13
src/utils/getHTMLText.jsx
Normal file
|
@ -0,0 +1,13 @@
|
|||
const div = document.createElement('div');
|
||||
function getHTMLText(html) {
|
||||
if (!html) return '';
|
||||
div.innerHTML = html
|
||||
.replace(/<\/p>/g, '</p>\n\n')
|
||||
.replace(/<\/li>/g, '</li>\n');
|
||||
div.querySelectorAll('br').forEach((br) => {
|
||||
br.replaceWith('\n');
|
||||
});
|
||||
return div.innerText.replace(/[\r\n]{3,}/g, '\n\n').trim();
|
||||
}
|
||||
|
||||
export default getHTMLText;
|
|
@ -1,4 +1,4 @@
|
|||
import { getHTMLText } from '../components/status';
|
||||
import getHTMLText from './getHTMLText';
|
||||
|
||||
function statusPeek(status) {
|
||||
const { spoilerText, content, poll, mediaAttachments } = status;
|
||||
|
|
Loading…
Reference in a new issue