1
0
mirror of https://github.com/misskey-dev/misskey.git synced 2026-05-16 16:45:30 +02:00

enhance: 絵文字データの参照を自前ライブラリに変更 (#17381)

* wip

* enhance: 絵文字データの参照を自前ライブラリに変更

* fix

* update to v17.0.2

* fix assets handling

* fix

* update mfm-js

* update emoji library

* Update COPYING [ci skip]

* Update Changelog

* Update Changelog

* fix: 端末の絵文字にフォールバックできるように
This commit is contained in:
かっこかり
2026-05-09 18:35:38 +09:00
committed by GitHub
parent 717931cfcb
commit a09a2c2eee
27 changed files with 80 additions and 7769 deletions

View File

@@ -55,7 +55,6 @@
"dependencies": {
"@aws-sdk/client-s3": "3.1037.0",
"@aws-sdk/lib-storage": "3.1037.0",
"@discordapp/twemoji": "16.0.1",
"@fastify/accepts": "5.0.4",
"@fastify/cors": "11.2.0",
"@fastify/express": "4.0.5",
@@ -63,6 +62,8 @@
"@fastify/multipart": "10.0.0",
"@fastify/static": "9.1.3",
"@kitajs/html": "4.2.13",
"@misskey-dev/emoji-assets": "17.0.3",
"@misskey-dev/emoji-data": "17.0.3",
"@misskey-dev/sharp-read-bmp": "1.2.0",
"@misskey-dev/summaly": "5.3.0",
"@napi-rs/canvas": "0.1.100",
@@ -76,7 +77,6 @@
"@simplewebauthn/server": "13.3.0",
"@sinonjs/fake-timers": "15.3.2",
"@smithy/node-http-handler": "4.6.1",
"@twemoji/parser": "16.0.0",
"accepts": "1.3.8",
"ajv": "8.20.0",
"archiver": "7.0.1",
@@ -111,7 +111,7 @@
"jsonld": "9.0.0",
"juice": "11.1.1",
"meilisearch": "0.57.0",
"mfm-js": "0.25.0",
"mfm-js": "0.26.0",
"mime-types": "3.0.2",
"misskey-js": "workspace:*",
"misskey-reversi": "workspace:*",

File diff suppressed because one or more lines are too long

View File

@@ -71,7 +71,7 @@ export class ClientServerService {
private readonly clientAssets: string;
private readonly assets: string;
private readonly swAssets: string;
private readonly fluentEmojisDir: string;
private readonly fluentEmojiDir: string;
private readonly twemojiDir: string;
private readonly frontendViteOut: string;
private readonly frontendEmbedViteOut: string;
@@ -135,8 +135,8 @@ export class ClientServerService {
this.clientAssets = resolve(frontendRootdir, 'assets');
this.assets = resolve(this.config.rootDir, 'built/_frontend_dist_');
this.swAssets = resolve(this.config.rootDir, 'built/_sw_dist_');
this.fluentEmojisDir = resolve(this.config.rootDir, 'fluent-emojis/dist');
this.twemojiDir = resolve(backendRootdir, 'node_modules/@discordapp/twemoji/dist/svg');
this.fluentEmojiDir = resolve(backendRootdir, 'node_modules/@misskey-dev/emoji-assets/built/fluent-emoji');
this.twemojiDir = resolve(backendRootdir, 'node_modules/@misskey-dev/emoji-assets/built/twemoji');
this.frontendViteOut = resolve(this.config.rootDir, 'built/_frontend_vite_');
this.frontendEmbedViteOut = resolve(this.config.rootDir, 'built/_frontend_embed_vite_');
this.tarball = resolve(this.config.rootDir, 'built/tarball');
@@ -306,7 +306,7 @@ export class ClientServerService {
reply.header('Content-Security-Policy', 'default-src \'none\'; style-src \'unsafe-inline\'');
return reply.sendFile(path, this.fluentEmojisDir, {
return reply.sendFile(path, this.fluentEmojiDir, {
maxAge: ms('30 days'),
});
});

View File

@@ -10,10 +10,8 @@
"lint": "pnpm typecheck && pnpm eslint"
},
"dependencies": {
"@discordapp/twemoji": "16.0.1",
"@rollup/plugin-json": "6.1.0",
"@rollup/pluginutils": "5.3.0",
"@twemoji/parser": "16.0.0",
"@vitejs/plugin-vue": "6.0.6",
"buraha": "0.0.1",
"estree-walker": "3.0.3",
@@ -21,7 +19,7 @@
"i18n": "workspace:*",
"icons-subsetter": "workspace:*",
"json5": "2.2.3",
"mfm-js": "0.25.0",
"mfm-js": "0.26.0",
"misskey-js": "workspace:*",
"punycode.js": "2.3.1",
"rollup": "4.60.2",
@@ -31,6 +29,7 @@
"vue": "3.5.33"
},
"devDependencies": {
"@misskey-dev/emoji-assets": "17.0.3",
"@misskey-dev/summaly": "5.3.0",
"@tabler/icons-webfont": "3.35.0",
"@testing-library/vue": "8.1.0",

View File

@@ -21,7 +21,7 @@ html {
accent-color: var(--MI_THEME-accent);
overflow: clip;
overflow-wrap: break-word;
font-family: 'Hiragino Maru Gothic Pro', "BIZ UDGothic", Roboto, HelveticaNeue, Arial, sans-serif;
font-family: 'Hiragino Maru Gothic Pro', "BIZ UDGothic", Roboto, HelveticaNeue, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 14px;
line-height: 1.35;
text-size-adjust: 100%;

View File

@@ -98,7 +98,8 @@ export function getConfig(): UserConfig {
'@/': __dirname + '/src/',
'@@/': __dirname + '/../frontend-shared/',
'/client-assets/': __dirname + '/assets/',
'/static-assets/': __dirname + '/../backend/assets/'
'/static-assets/': __dirname + '/../backend/assets/',
'/fluent-emoji/': '@misskey-dev/emoji-assets/fluent-emoji/',
},
},

View File

@@ -19,7 +19,7 @@ export function char2fluentEmojiFilePath(char: string): string {
// Fluent Emojiは国旗非対応 https://github.com/microsoft/fluentui-emoji/issues/25
if (codes[0]?.startsWith('1f1')) return char2twemojiFilePath(char);
if (!codes.includes('200d')) codes = codes.filter(x => x !== 'fe0f');
codes = codes.filter(x => x != null && x.length > 0);
const fileName = (codes as string[]).map(x => x.padStart(4, '0')).join('-');
codes = codes.filter(x => x && x.length);
const fileName = codes.join('-');
return `${fluentEmojiPngBase}/${fileName}.png`;
}

File diff suppressed because it is too large Load Diff

View File

@@ -11,8 +11,7 @@ export type UnicodeEmojiDef = {
category: typeof unicodeEmojiCategories[number];
};
// initial converted from https://github.com/muan/emojilib/commit/242fe68be86ed6536843b83f7e32f376468b38fb
import _emojilist from './emojilist.json' with { type: 'json' };
import _emojilist from '@misskey-dev/emoji-data/emojilist.json';
export const emojilist: UnicodeEmojiDef[] = _emojilist.map(x => ({
name: x[1] as string,

View File

@@ -19,6 +19,7 @@
"js-built"
],
"dependencies": {
"@misskey-dev/emoji-data": "17.0.3",
"i18n": "workspace:*",
"json5": "2.2.3",
"misskey-js": "workspace:*",

View File

@@ -51,7 +51,6 @@ await fs.readFile(
if (
micromatch(Array.from(modules), [
'../../assets/**',
'../../fluent-emojis/**',
'../../locales/ja-JP.yml',
'assets/**',
'public/**',

View File

@@ -7,7 +7,7 @@ import { type SharedOptions, http, HttpResponse } from 'msw';
export const onUnhandledRequest = ((req, print) => {
const url = new URL(req.url);
if (url.hostname !== 'localhost' || /^\/(?:client-assets\/|fluent-emojis?\/|iframe.html$|node_modules\/|src\/|sb-|static-assets\/|vite\/)/.test(url.pathname)) {
if (url.hostname !== 'localhost' || /^\/(?:client-assets\/|fluent-emoji\/|iframe.html$|node_modules\/|src\/|sb-|static-assets\/|vite\/)/.test(url.pathname)) {
return
}
print.warning()
@@ -16,16 +16,7 @@ export const onUnhandledRequest = ((req, print) => {
export const commonHandlers = [
http.get('/fluent-emoji/:codepoints.png', async ({ params }) => {
const { codepoints } = params;
const value = await fetch(`https://raw.githubusercontent.com/misskey-dev/emojis/main/dist/${codepoints}.png`).then((response) => response.blob());
return new HttpResponse(value, {
headers: {
'Content-Type': 'image/png',
},
});
}),
http.get('/fluent-emojis/:codepoints.png', async ({ params }) => {
const { codepoints } = params;
const value = await fetch(`https://raw.githubusercontent.com/misskey-dev/emojis/main/dist/${codepoints}.png`).then((response) => response.blob());
const value = await fetch(`https://unpkg.com/@misskey-dev/emoji-assets@17.0.3/built/fluent-emoji/${codepoints}.png`).then((response) => response.blob());
return new HttpResponse(value, {
headers: {
'Content-Type': 'image/png',
@@ -34,7 +25,7 @@ export const commonHandlers = [
}),
http.get('/twemoji/:codepoints.svg', async ({ params }) => {
const { codepoints } = params;
const value = await fetch(`https://unpkg.com/@discordapp/twemoji@16.0.1/dist/svg/${codepoints}.svg`).then((response) => response.blob());
const value = await fetch(`https://unpkg.com/@misskey-dev/emoji-assets@17.0.3/built/twemoji/${codepoints}.svg`).then((response) => response.blob());
return new HttpResponse(value, {
headers: {
'Content-Type': 'image/svg+xml',

View File

@@ -17,14 +17,13 @@
},
"dependencies": {
"@analytics/google-analytics": "1.1.0",
"@discordapp/twemoji": "16.0.1",
"@mcaptcha/core-glue": "0.1.0-alpha-5",
"@misskey-dev/browser-image-resizer": "2024.1.0",
"@misskey-dev/emoji-data": "17.0.3",
"@sentry/vue": "10.50.0",
"@simplewebauthn/browser": "13.3.0",
"@syuilo/aiscript": "1.2.1",
"@syuilo/aiscript-0-19-0": "npm:@syuilo/aiscript@^0.19.0",
"@twemoji/parser": "16.0.0",
"@vitejs/plugin-vue": "6.0.6",
"aiscript-vscode": "github:aiscript-dev/aiscript-vscode#v0.1.16",
"analytics": "0.8.19",
@@ -53,7 +52,7 @@
"json5": "2.2.3",
"matter-js": "0.20.0",
"mediabunny": "1.41.0",
"mfm-js": "0.25.0",
"mfm-js": "0.26.0",
"misskey-bubble-game": "workspace:*",
"misskey-js": "workspace:*",
"misskey-reversi": "workspace:*",
@@ -72,6 +71,7 @@
"wanakana": "5.3.1"
},
"devDependencies": {
"@misskey-dev/emoji-assets": "17.0.3",
"@misskey-dev/summaly": "5.3.0",
"@rollup/plugin-json": "6.1.0",
"@rollup/pluginutils": "5.3.0",

View File

@@ -15,7 +15,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div class="version">v{{ version }}</div>
<span v-for="emoji in easterEggEmojis" :key="emoji.id" class="emoji" :data-physics-x="emoji.left" :data-physics-y="emoji.top" :class="{ _physics_circle_: !emoji.emoji.startsWith(':') }">
<MkCustomEmoji v-if="emoji.emoji[0] === ':'" class="emoji" :name="emoji.emoji" :normal="true" :noStyle="true" :fallbackToImage="true"/>
<MkEmoji v-else class="emoji" :emoji="emoji.emoji" :normal="true" :noStyle="true"/>
<MkEmoji v-else class="emoji unicode" :emoji="emoji.emoji" :normal="true" :noStyle="true"/>
</span>
</div>
<button v-if="thereIsTreasure" class="_button treasure" @click="getTreasure"><img src="/fluent-emoji/1f3c6.png" class="treasureImg"></button>
@@ -560,6 +560,10 @@ definePage(() => ({
pointer-events: none;
font-size: 24px;
width: 24px;
&.unicode {
height: 24px;
}
}
}
}

View File

@@ -1040,9 +1040,9 @@ function downloadEmojiIndex(lang: typeof emojiIndexLangs[number]) {
function download() {
switch (lang) {
case 'en-US': return import('../../unicode-emoji-indexes/en-US.json').then(x => x.default);
case 'ja-JP': return import('../../unicode-emoji-indexes/ja-JP.json').then(x => x.default);
case 'ja-JP_hira': return import('../../unicode-emoji-indexes/ja-JP_hira.json').then(x => x.default);
case 'en-US': return import('@misskey-dev/emoji-data/indexes/en-US.json').then(x => x.default);
case 'ja-JP': return import('@misskey-dev/emoji-data/indexes/ja-JP.json').then(x => x.default);
case 'ja-JP_hira': return import('@misskey-dev/emoji-data/indexes/ja-JP_hira.json').then(x => x.default);
default: throw new Error('unrecognized lang: ' + lang);
}
}

View File

@@ -25,7 +25,7 @@
html {
overflow: auto;
overflow-wrap: break-word;
font-family: 'Hiragino Maru Gothic Pro', "BIZ UDGothic", Roboto, HelveticaNeue, Arial, sans-serif;
font-family: 'Hiragino Maru Gothic Pro', "BIZ UDGothic", Roboto, HelveticaNeue, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
font-size: 14px;
line-height: 1.35;
text-size-adjust: 100%;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -137,8 +137,7 @@ export function getConfig(): UserConfig {
'@@/': __dirname + '/../frontend-shared/',
'/client-assets/': __dirname + '/assets/',
'/static-assets/': __dirname + '/../backend/assets/',
'/fluent-emojis/': __dirname + '/../../fluent-emojis/dist/',
'/fluent-emoji/': __dirname + '/../../fluent-emojis/dist/',
'/fluent-emoji/': '@misskey-dev/emoji-assets/fluent-emoji/',
},
},