@ -29,6 +29,8 @@ const guessFqn = (account: Pick<Account, 'acct' | 'url'>): string => {
|
||||
const filterBadges = (tags?: string[]) =>
|
||||
tags?.filter(tag => tag.startsWith('badge:')).map(tag => v.parse(roleSchema, { id: tag, name: tag.replace(/^badge:/, '') }));
|
||||
|
||||
const MKLJCZK_ACCOUNTS = ['https://pl.fediverse.pl/users/mkljczk', 'https://gts.mkljczk.pl/users/mkljczk'];
|
||||
|
||||
const preprocessAccount = v.transform((account: any) => {
|
||||
if (!account?.acct) return null;
|
||||
|
||||
@ -37,7 +39,7 @@ const preprocessAccount = v.transform((account: any) => {
|
||||
const fqn = account.fqn || guessFqn(account);
|
||||
const domain = fqn.split('@')[1] || '';
|
||||
|
||||
const isCat = (account.pleroma?.is_cat ?? account.is_cat) || account.uri === 'https://pl.fediverse.pl/users/mkljczk' || account.uri === 'https://gts.mkljczk.pl/users/mkljczk';
|
||||
const isCat = (account.pleroma?.is_cat ?? account.is_cat) || MKLJCZK_ACCOUNTS.includes(account.uri ?? account.url);
|
||||
const speakAsCat = account.pleroma?.speak_as_cat ?? account.speak_as_cat ?? isCat;
|
||||
|
||||
return {
|
||||
@ -156,8 +158,8 @@ const baseAccountSchema = v.object({
|
||||
|
||||
pronouns: v.fallback(v.array(v.string()), []),
|
||||
|
||||
is_cat: v.fallback(v.optional(v.boolean()), false),
|
||||
speak_as_cat: v.fallback(v.optional(v.boolean()), false),
|
||||
is_cat: v.fallback(v.boolean(), false),
|
||||
speak_as_cat: v.fallback(v.boolean(), false),
|
||||
|
||||
__meta: coerceObject({
|
||||
pleroma: v.fallback(v.any(), undefined),
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "pl-api",
|
||||
"version": "1.0.0-rc.32",
|
||||
"version": "1.0.0-rc.33",
|
||||
"type": "module",
|
||||
"homepage": "https://github.com/mkljczk/pl-fe/tree/develop/packages/pl-api",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/mkljczk/pl-fe"
|
||||
"url": "git+https://github.com/mkljczk/pl-fe.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/mkljczk/pl-fe/issues"
|
||||
|
||||
@ -9,6 +9,7 @@ import { Link } from 'react-router-dom';
|
||||
import Emojify from 'pl-fe/features/emoji/emojify';
|
||||
import { useSettings } from 'pl-fe/hooks/use-settings';
|
||||
import { makeEmojiMap } from 'pl-fe/utils/normalizers';
|
||||
import nyaize from 'pl-fe/utils/nyaize';
|
||||
import Purify from 'pl-fe/utils/url-purify';
|
||||
|
||||
import HashtagLink from './hashtag-link';
|
||||
@ -63,8 +64,8 @@ const uniqueHashtagsWithCaseHandling = (hashtags: string[]) => {
|
||||
});
|
||||
};
|
||||
|
||||
function parseContent(props: IParsedContent, extractHashtags?: false, cleanUrls?: boolean, greentext?: boolean): ReturnType<typeof domToReact>;
|
||||
function parseContent(props: IParsedContent, extractHashtags: true, cleanUrls: boolean, greentext: boolean): {
|
||||
function parseContent(props: IParsedContent, extractHashtags?: false, cleanUrls?: boolean, greentext?: boolean, speakAsCat?: boolean): ReturnType<typeof domToReact>;
|
||||
function parseContent(props: IParsedContent, extractHashtags: true, cleanUrls: boolean, greentext: boolean, speakAsCat: boolean): {
|
||||
hashtags: Array<string>;
|
||||
content: ReturnType<typeof domToReact>;
|
||||
};
|
||||
@ -74,7 +75,7 @@ function parseContent({
|
||||
mentions,
|
||||
hasQuote,
|
||||
emojis,
|
||||
}: IParsedContent, extractHashtags = false, cleanUrls = false, greentext = false) {
|
||||
}: IParsedContent, extractHashtags = false, cleanUrls = false, greentext = false, speakAsCat = false) {
|
||||
if (html.length === 0) {
|
||||
return extractHashtags ? { content: null, hashtags: [] } : null;
|
||||
}
|
||||
@ -94,9 +95,13 @@ function parseContent({
|
||||
const options: HTMLReactParserOptions = {
|
||||
replace(domNode) {
|
||||
if (!(domNode instanceof Element)) {
|
||||
if (greentext && domNode.data.startsWith('>')) {
|
||||
return <span className='dark:text-accent-green text-lime-600'>{domNode.data}</span>;
|
||||
const data = speakAsCat ? nyaize(domNode.data) : domNode.data;
|
||||
if (greentext && data.startsWith('>')) {
|
||||
return <span className='dark:text-accent-green text-lime-600'>{data}</span>;
|
||||
}
|
||||
|
||||
if (speakAsCat) return <>{data}</>;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@ -203,7 +208,7 @@ function parseContent({
|
||||
const ParsedContent: React.FC<IParsedContent> = React.memo((props) => {
|
||||
const settings = useSettings();
|
||||
|
||||
return parseContent(props, false, settings.urlPrivacy.clearLinksInContent, false);
|
||||
return parseContent(props, false, settings.urlPrivacy.clearLinksInContent, false, false);
|
||||
}, (prevProps, nextProps) => prevProps.html === nextProps.html);
|
||||
|
||||
export { ParsedContent, parseContent };
|
||||
|
||||
@ -146,7 +146,7 @@ const StatusContent: React.FC<IStatusContent> = React.memo(({
|
||||
mentions: status.mentions,
|
||||
hasQuote: !!status.quote_id,
|
||||
emojis: status.emojis,
|
||||
}, true, urlPrivacy.clearLinksInContent, greentext), [content]);
|
||||
}, true, urlPrivacy.clearLinksInContent, greentext, status.account.speak_as_cat), [content]);
|
||||
|
||||
useEffect(() => {
|
||||
setLineClamp(!spoilerNode.current || spoilerNode.current.clientHeight >= 96);
|
||||
|
||||
31
packages/pl-fe/src/utils/nyaize.ts
Normal file
31
packages/pl-fe/src/utils/nyaize.ts
Normal file
@ -0,0 +1,31 @@
|
||||
// Adapted from Sharkey, licensed under AGPL-3.0-only
|
||||
// https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/packages/misskey-js/src/nyaize.ts
|
||||
|
||||
const koRegex1 = /[나-낳]/g;
|
||||
const koRegex2 = /(다$)|(다(?=\.))|(다(?= ))|(다(?=!))|(다(?=\?))/gm;
|
||||
const koRegex3 = /(야(?=\?))|(야$)|(야(?= ))/gm;
|
||||
|
||||
const ifAfter = (prefix: string, fn: (x: string) => string) => {
|
||||
const preLen = prefix.length;
|
||||
const regex = new RegExp(prefix, 'i');
|
||||
return (x: string, pos: number, string: string) => {
|
||||
return pos > 0 && string.substring(pos - preLen, pos).match(regex) ? fn(x) : x;
|
||||
};
|
||||
};
|
||||
|
||||
const nyaize = (text: string) =>
|
||||
text
|
||||
// ja-JP
|
||||
.replaceAll('な', 'にゃ').replaceAll('ナ', 'ニャ').replaceAll('ナ', 'ニャ')
|
||||
// en-US
|
||||
.replace(/a/gi, ifAfter('n', x => x === 'A' ? 'YA' : 'ya'))
|
||||
.replace(/ing/gi, ifAfter('morn', x => x === 'ING' ? 'YAN' : 'yan'))
|
||||
.replace(/one/gi, ifAfter('every', x => x === 'ONE' ? 'NYAN' : 'nyan'))
|
||||
// ko-KR
|
||||
.replace(koRegex1, match => !isNaN(match.charCodeAt(0)) ? String.fromCharCode(
|
||||
match.charCodeAt(0) + '냐'.charCodeAt(0) - '나'.charCodeAt(0),
|
||||
) : match)
|
||||
.replace(koRegex2, '다냥')
|
||||
.replace(koRegex3, '냥');
|
||||
|
||||
export default nyaize;
|
||||
Reference in New Issue
Block a user