mirror of
https://github.com/cheeaun/phanpy.git
synced 2024-11-26 03:05:41 +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';
|
} from '@szhsin/react-menu';
|
||||||
import { useEffect, useRef, useState } from 'preact/hooks';
|
import { useEffect, useRef, useState } from 'preact/hooks';
|
||||||
|
|
||||||
import RelativeTime from '../components/relative-time';
|
|
||||||
import { api } from '../utils/api';
|
import { api } from '../utils/api';
|
||||||
import emojifyText from '../utils/emojify-text';
|
import emojifyText from '../utils/emojify-text';
|
||||||
import enhanceContent from '../utils/enhance-content';
|
import enhanceContent from '../utils/enhance-content';
|
||||||
|
import getHTMLText from '../utils/getHTMLText';
|
||||||
import handleContentLinks from '../utils/handle-content-links';
|
import handleContentLinks from '../utils/handle-content-links';
|
||||||
import niceDateTime from '../utils/nice-date-time';
|
import niceDateTime from '../utils/nice-date-time';
|
||||||
import shortenNumber from '../utils/shorten-number';
|
import shortenNumber from '../utils/shorten-number';
|
||||||
|
@ -24,6 +24,8 @@ import AccountBlock from './account-block';
|
||||||
import Avatar from './avatar';
|
import Avatar from './avatar';
|
||||||
import Icon from './icon';
|
import Icon from './icon';
|
||||||
import Link from './link';
|
import Link from './link';
|
||||||
|
import Modal from './modal';
|
||||||
|
import TranslationBlock from './translation-block';
|
||||||
|
|
||||||
const MUTE_DURATIONS = [
|
const MUTE_DURATIONS = [
|
||||||
1000 * 60 * 5, // 5 minutes
|
1000 * 60 * 5, // 5 minutes
|
||||||
|
@ -389,7 +391,7 @@ function RelatedActions({ info, instance, authenticated }) {
|
||||||
const [relationship, setRelationship] = useState(null);
|
const [relationship, setRelationship] = useState(null);
|
||||||
const [familiarFollowers, setFamiliarFollowers] = useState([]);
|
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 accountID = useRef(id);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
@ -484,6 +486,8 @@ function RelatedActions({ info, instance, authenticated }) {
|
||||||
const loading = relationshipUIState === 'loading';
|
const loading = relationshipUIState === 'loading';
|
||||||
const menuInstanceRef = useRef(null);
|
const menuInstanceRef = useRef(null);
|
||||||
|
|
||||||
|
const [showTranslatedBio, setShowTranslatedBio] = useState(false);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{familiarFollowers?.length > 0 && (
|
{familiarFollowers?.length > 0 && (
|
||||||
|
@ -571,6 +575,14 @@ function RelatedActions({ info, instance, authenticated }) {
|
||||||
<Icon icon="at" />
|
<Icon icon="at" />
|
||||||
<span>Mention @{username}</span>
|
<span>Mention @{username}</span>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
onClick={() => {
|
||||||
|
setShowTranslatedBio(true);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Icon icon="translate" />
|
||||||
|
<span>Translate bio</span>
|
||||||
|
</MenuItem>
|
||||||
<MenuDivider />
|
<MenuDivider />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
@ -816,6 +828,18 @@ function RelatedActions({ info, instance, authenticated }) {
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</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;
|
export default AccountInfo;
|
||||||
|
|
|
@ -25,6 +25,7 @@ import NameText from '../components/name-text';
|
||||||
import { api } from '../utils/api';
|
import { api } from '../utils/api';
|
||||||
import enhanceContent from '../utils/enhance-content';
|
import enhanceContent from '../utils/enhance-content';
|
||||||
import getTranslateTargetLanguage from '../utils/get-translate-target-language';
|
import getTranslateTargetLanguage from '../utils/get-translate-target-language';
|
||||||
|
import getHTMLText from '../utils/getHTMLText';
|
||||||
import handleContentLinks from '../utils/handle-content-links';
|
import handleContentLinks from '../utils/handle-content-links';
|
||||||
import htmlContentLength from '../utils/html-content-length';
|
import htmlContentLength from '../utils/html-content-length';
|
||||||
import niceDateTime from '../utils/nice-date-time';
|
import niceDateTime from '../utils/nice-date-time';
|
||||||
|
@ -1695,18 +1696,6 @@ function nicePostURL(url) {
|
||||||
|
|
||||||
const unfurlMastodonLink = throttle(_unfurlMastodonLink);
|
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 root = document.documentElement;
|
||||||
const defaultBoundingBoxPadding = 8;
|
const defaultBoundingBoxPadding = 8;
|
||||||
function safeBoundingBoxPadding() {
|
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) {
|
function statusPeek(status) {
|
||||||
const { spoilerText, content, poll, mediaAttachments } = status;
|
const { spoilerText, content, poll, mediaAttachments } = status;
|
||||||
|
|
Loading…
Reference in a new issue