Merge commit '15182d1e5e595b21c47b48c5d258f30a0251e753' into glitch-soc/merge-upstream

Conflicts:
- `.rubocop_todo.yml`:
  glitch-soc had extra ignores.
  Removed them.
This commit is contained in:
Claire
2023-10-24 20:31:20 +02:00
69 changed files with 419 additions and 374 deletions

View File

@@ -3,7 +3,7 @@ import { PureComponent } from 'react';
import { assetHost } from 'mastodon/utils/config';
import unicodeMapping from '../features/emoji/emoji_unicode_mapping_light';
import { unicodeMapping } from '../features/emoji/emoji_unicode_mapping_light';
export default class AutosuggestEmoji extends PureComponent {

View File

@@ -3,7 +3,11 @@ import React from 'react';
import { Router as OriginalRouter } from 'react-router';
import type { LocationDescriptor, Path } from 'history';
import type {
LocationDescriptor,
LocationDescriptorObject,
Path,
} from 'history';
import { createBrowserHistory } from 'history';
import { layoutFromWindow } from 'mastodon/is_mobile';
@@ -20,39 +24,55 @@ const browserHistory = createBrowserHistory<
const originalPush = browserHistory.push.bind(browserHistory);
const originalReplace = browserHistory.replace.bind(browserHistory);
function extractRealPath(path: HistoryPath) {
if (typeof path === 'string') return path;
else return path.pathname;
function normalizePath(
path: HistoryPath,
state?: MastodonLocationState,
): LocationDescriptorObject<MastodonLocationState> {
const location = typeof path === 'string' ? { pathname: path } : { ...path };
if (location.state === undefined && state !== undefined) {
location.state = state;
} else if (
location.state !== undefined &&
state !== undefined &&
process.env.NODE_ENV === 'development'
) {
// eslint-disable-next-line no-console
console.log(
'You should avoid providing a 2nd state argument to push when the 1st argument is a location-like object that already has state; it is ignored',
);
}
if (
layoutFromWindow() === 'multi-column' &&
!location.pathname?.startsWith('/deck')
) {
location.pathname = `/deck${location.pathname}`;
}
return location;
}
browserHistory.push = (path: HistoryPath, state?: MastodonLocationState) => {
state = state ?? {};
state.fromMastodon = true;
const location = normalizePath(path, state);
const realPath = extractRealPath(path);
if (!realPath) return;
location.state = location.state ?? {};
location.state.fromMastodon = true;
if (layoutFromWindow() === 'multi-column' && !realPath.startsWith('/deck')) {
originalPush(`/deck${realPath}`, state);
} else {
originalPush(path, state);
}
originalPush(location);
};
browserHistory.replace = (path: HistoryPath, state?: MastodonLocationState) => {
const location = normalizePath(path, state);
if (!location.pathname) return;
if (browserHistory.location.state?.fromMastodon) {
state = state ?? {};
state.fromMastodon = true;
location.state = location.state ?? {};
location.state.fromMastodon = true;
}
const realPath = extractRealPath(path);
if (!realPath) return;
if (layoutFromWindow() === 'multi-column' && !realPath.startsWith('/deck')) {
originalReplace(`/deck${realPath}`, state);
} else {
originalReplace(path, state);
}
originalReplace(location);
};
export const Router: React.FC<PropsWithChildren> = ({ children }) => {

View File

@@ -4,7 +4,7 @@ import { assetHost } from 'mastodon/utils/config';
import { autoPlayGif } from '../../initial_state';
import unicodeMapping from './emoji_unicode_mapping_light';
import { unicodeMapping } from './emoji_unicode_mapping_light';
const trie = new Trie(Object.keys(unicodeMapping));

View File

@@ -13,15 +13,20 @@ export type Search = string;
* This could be a potential area of refactoring or error handling.
* The non-existence of 'skins' property is evident at [this location]{@link app/javascript/mastodon/features/emoji/emoji_compressed.js:121}.
*/
export type Skins = null;
type Skins = null;
export type FilenameData = string[] | string[][];
type Filename = string;
type UnicodeFilename = string;
export type FilenameData = [
filename: Filename,
unicodeFilename?: UnicodeFilename,
][];
export type ShortCodesToEmojiDataKey =
| EmojiData['id']
| BaseEmoji['native']
| keyof NimbleEmojiIndex['emojis'];
export type SearchData = [
type SearchData = [
BaseEmoji['native'],
Emoji['short_names'],
Search,
@@ -32,9 +37,9 @@ export type ShortCodesToEmojiData = Record<
ShortCodesToEmojiDataKey,
[FilenameData, SearchData]
>;
export type EmojisWithoutShortCodes = FilenameData[];
type EmojisWithoutShortCodes = FilenameData;
export type EmojiCompressed = [
type EmojiCompressed = [
ShortCodesToEmojiData,
Skins,
Category[],

View File

@@ -30,22 +30,13 @@ const emojis: Emojis = {};
// decompress
Object.keys(shortCodesToEmojiData).forEach((shortCode) => {
const [_filenameData, searchData] = shortCodesToEmojiData[shortCode];
const native = searchData[0];
let short_names = searchData[1];
const search = searchData[2];
let unified = searchData[3];
const [native, short_names, search, unified] = searchData;
if (!unified) {
// unified name can be derived from unicodeToUnifiedName
unified = unicodeToUnifiedName(native);
}
if (short_names) short_names = [shortCode].concat(short_names);
emojis[shortCode] = {
native,
search,
short_names,
unified,
short_names: short_names ? [shortCode].concat(short_names) : undefined,
unified: unified ?? unicodeToUnifiedName(native),
};
});

View File

@@ -1,37 +0,0 @@
// A mapping of unicode strings to an object containing the filename
// (i.e. the svg filename) and a shortCode intended to be shown
// as a "title" attribute in an HTML element (aka tooltip).
import emojiCompressed from './emoji_compressed';
import { unicodeToFilename } from './unicode_to_filename';
const [
shortCodesToEmojiData,
_skins,
_categories,
_short_names,
emojisWithoutShortCodes,
] = emojiCompressed;
// decompress
const unicodeMapping = {};
function processEmojiMapData(emojiMapData, shortCode) {
let [ native, filename ] = emojiMapData;
if (!filename) {
// filename name can be derived from unicodeToFilename
filename = unicodeToFilename(native);
}
unicodeMapping[native] = {
shortCode: shortCode,
filename: filename,
};
}
Object.keys(shortCodesToEmojiData).forEach((shortCode) => {
let [ filenameData ] = shortCodesToEmojiData[shortCode];
filenameData.forEach(emojiMapData => processEmojiMapData(emojiMapData, shortCode));
});
emojisWithoutShortCodes.forEach(emojiMapData => processEmojiMapData(emojiMapData));
export default unicodeMapping;

View File

@@ -0,0 +1,60 @@
// A mapping of unicode strings to an object containing the filename
// (i.e. the svg filename) and a shortCode intended to be shown
// as a "title" attribute in an HTML element (aka tooltip).
import type {
FilenameData,
ShortCodesToEmojiDataKey,
} from './emoji_compressed';
import emojiCompressed from './emoji_compressed';
import { unicodeToFilename } from './unicode_to_filename';
type UnicodeMapping = {
[key in FilenameData[number][0]]: {
shortCode: ShortCodesToEmojiDataKey;
filename: FilenameData[number][number];
};
};
const [
shortCodesToEmojiData,
_skins,
_categories,
_short_names,
emojisWithoutShortCodes,
] = emojiCompressed;
// decompress
const unicodeMapping: UnicodeMapping = {};
function processEmojiMapData(
emojiMapData: FilenameData[number],
shortCode?: ShortCodesToEmojiDataKey,
) {
const [native, _filename] = emojiMapData;
let filename = emojiMapData[1];
if (!filename) {
// filename name can be derived from unicodeToFilename
filename = unicodeToFilename(native);
}
unicodeMapping[native] = {
shortCode,
filename,
};
}
Object.keys(shortCodesToEmojiData).forEach(
(shortCode: ShortCodesToEmojiDataKey) => {
if (shortCode === undefined) return;
const [filenameData, _searchData] = shortCodesToEmojiData[shortCode];
filenameData.forEach((emojiMapData) => {
processEmojiMapData(emojiMapData, shortCode);
});
},
);
emojisWithoutShortCodes.forEach((emojiMapData) => {
processEmojiMapData(emojiMapData);
});
export { unicodeMapping };

View File

@@ -18,7 +18,7 @@ import { AnimatedNumber } from 'mastodon/components/animated_number';
import { Icon } from 'mastodon/components/icon';
import { IconButton } from 'mastodon/components/icon_button';
import EmojiPickerDropdown from 'mastodon/features/compose/containers/emoji_picker_dropdown_container';
import unicodeMapping from 'mastodon/features/emoji/emoji_unicode_mapping_light';
import { unicodeMapping } from 'mastodon/features/emoji/emoji_unicode_mapping_light';
import { autoPlayGif, reduceMotion, disableSwiping, mascot } from 'mastodon/initial_state';
import { assetHost } from 'mastodon/utils/config';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';

View File

@@ -534,6 +534,7 @@
"reply_indicator.cancel": "Zrušit",
"report.block": "Blokovat",
"report.block_explanation": "Neuvidíte příspěvky tohoto uživatele. On neuvidí vaše příspěvky, ani vás nebude moci sledovat. Pozná, že je blokován.",
"report.categories.legal": "Právní ustanovení",
"report.categories.other": "Ostatní",
"report.categories.spam": "Spam",
"report.categories.violation": "Obsah porušuje jedno nebo více pravidel serveru",
@@ -590,6 +591,7 @@
"search_popout.options": "Možnosti hledání",
"search_popout.quick_actions": "Rychlé akce",
"search_popout.recent": "Nedávná vyhledávání",
"search_popout.specific_date": "konkrétní datum",
"search_popout.user": "uživatel",
"search_results.accounts": "Profily",
"search_results.all": "Vše",

View File

@@ -590,6 +590,7 @@
"search.quick_action.open_url": "在 Mastodon 中打開網址",
"search.quick_action.status_search": "符合的帖文 {x}",
"search.search_or_paste": "搜尋或貼上網址",
"search_popout.full_text_search_disabled_message": "在 {domain} 上無法使用。",
"search_popout.language_code": "ISO 語言代碼",
"search_popout.options": "搜尋選項",
"search_popout.quick_actions": "快速動作",

View File

@@ -662,9 +662,9 @@
"status.share": "分享",
"status.show_filter_reason": "仍要顯示",
"status.show_less": "減少顯示",
"status.show_less_all": "減少顯示這類嘟文",
"status.show_less_all": "隱藏所有內容警告與額外標籤",
"status.show_more": "顯示更多",
"status.show_more_all": "顯示更多這類嘟文",
"status.show_more_all": "顯示所有內容警告與額外標籤",
"status.show_original": "顯示原文",
"status.title.with_attachments": "{user} 嘟了 {attachmentCount, plural, other {{attachmentCount} 個附加檔案}}",
"status.translate": "翻譯",