Compare commits

...

16 Commits

Author SHA1 Message Date
syuilo f007890e84 Revert "chore(frontend): tweak rt style for safari"
This reverts commit 76ccae8a2f.
2023-11-17 18:31:09 +09:00
syuilo 76ccae8a2f chore(frontend): tweak rt style for safari 2023-11-17 18:17:32 +09:00
syuilo 04709cf256 2023.11.1 2023-11-17 18:05:12 +09:00
syuilo 850b834758
New translations ja-jp.yml (Chinese Traditional) (#12351) 2023-11-17 18:04:42 +09:00
syuilo 08b3662bb8 chore(frontend): tweak ui 2023-11-17 18:00:42 +09:00
syuilo 4a7ccf6deb tweak MkTime.vue 2023-11-17 17:54:13 +09:00
syuilo 4b3f9bd9a6 enhance(backend): MFMのunixtimeをISO形式で連合するように 2023-11-17 15:44:36 +09:00
syuilo 5f5712a3ee fix(frontend): MFM unixtimeのプレビューがリアルタイムで反映されない
Fix #12350
2023-11-17 15:33:57 +09:00
syuilo 1518c5ddb0 2023.11.1-beta.2 2023-11-17 15:10:14 +09:00
syuilo 4f9922d46c update deps 2023-11-17 15:10:04 +09:00
syuilo a9a743dab9 enhance(frontend): MFMでUNIX時間を指定して日時を表示できるように
Resolve #12294
2023-11-17 15:05:37 +09:00
syuilo 4d1a2bad17 typo 2023-11-17 13:27:33 +09:00
syuilo cbab3affc9
Update packages/frontend/src/pages/role.vue
Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
2023-11-17 13:26:55 +09:00
syuilo f89a827aa9
Update packages/frontend/src/pages/role.vue
Co-authored-by: Acid Chicken (硫酸鶏) <root@acid-chicken.com>
2023-11-17 13:26:48 +09:00
syuilo 43cb2d478c enhance(frontend): ruby内でMFMを使えるように 2023-11-17 13:20:40 +09:00
syuilo b517d76084 enhance(frontend): MFMでルビを振れるように
Resolve #9161
2023-11-17 13:09:56 +09:00
17 changed files with 558 additions and 497 deletions

View File

@ -12,7 +12,7 @@
-->
## 2023.x.x (unreleased)
## 2023.11.1
### General
- Feat: 管理者がコントロールパネルからメールアドレスの照会を行えるようになりました
@ -20,6 +20,10 @@
- Enhance: 依存関係の更新
### Client
- Enhance: MFMでルビを振れるように
- 例: `$[ruby 三須木 みすき]`
- Enhance: MFMでUNIX時間を指定して日時を表示できるように
- 例: `$[unixtime 1701356400]`
- Enhance: プラグインでエラーが発生した場合のハンドリングを強化
- Enhance: 細かなUIのブラッシュアップ
- Fix: 効果音が再生されるとデバイスで再生している動画や音声が停止する問題を修正 #12339

9
locales/index.d.ts vendored
View File

@ -1948,6 +1948,15 @@ export interface Locale {
"yearsAgo": string;
"invalid": string;
};
"_timeIn": {
"seconds": string;
"minutes": string;
"hours": string;
"days": string;
"weeks": string;
"months": string;
"years": string;
};
"_time": {
"second": string;
"minute": string;

View File

@ -1853,6 +1853,15 @@ _ago:
yearsAgo: "{n}年前"
invalid: "ありません"
_timeIn:
seconds: "{n}秒後"
minutes: "{n}分後"
hours: "{n}時間後"
days: "{n}日後"
weeks: "{n}週間後"
months: "{n}ヶ月後"
years: "{n}年後"
_time:
second: "秒"
minute: "分"

View File

@ -299,7 +299,7 @@ light: "淺色"
dark: "深色"
lightThemes: "淺色主題"
darkThemes: "深色主題"
syncDeviceDarkMode: "同步至此裝置的深色模式設定"
syncDeviceDarkMode: "與設備的深色模式同步"
drive: "雲端硬碟"
fileName: "檔案名稱"
selectFile: "選擇檔案"
@ -1819,6 +1819,14 @@ _ago:
monthsAgo: "{n} 個月前"
yearsAgo: "{n} 年前"
invalid: "無"
_timeIn:
seconds: "{n} 秒後"
minutes: "{n} 分後"
hours: "{n} 小時後"
days: "{n} 日後"
weeks: "{n} 週後"
months: "{n} 個月後"
years: "{n} 年後"
_time:
second: "秒"
minute: "分鐘"

View File

@ -1,6 +1,6 @@
{
"name": "misskey",
"version": "2023.11.1-beta.1",
"version": "2023.11.1",
"codename": "nasubi",
"repository": {
"type": "git",
@ -55,9 +55,9 @@
"@typescript-eslint/eslint-plugin": "6.11.0",
"@typescript-eslint/parser": "6.11.0",
"cross-env": "7.0.3",
"cypress": "13.5.0",
"cypress": "13.5.1",
"eslint": "8.53.0",
"start-server-and-test": "2.0.2"
"start-server-and-test": "2.0.3"
},
"optionalDependencies": {
"@tensorflow/tfjs-core": "4.4.0"

View File

@ -64,7 +64,7 @@
"@bull-board/ui": "5.9.1",
"@discordapp/twemoji": "14.1.2",
"@fastify/accepts": "4.2.0",
"@fastify/cookie": "9.1.0",
"@fastify/cookie": "9.2.0",
"@fastify/cors": "8.4.1",
"@fastify/express": "2.3.0",
"@fastify/http-proxy": "9.3.0",
@ -78,7 +78,7 @@
"@simplewebauthn/server": "8.3.5",
"@sinonjs/fake-timers": "11.2.2",
"@smithy/node-http-handler": "2.1.5",
"@swc/cli": "0.1.62",
"@swc/cli": "0.1.63",
"@swc/core": "1.3.96",
"accepts": "1.3.8",
"ajv": "8.12.0",
@ -87,7 +87,7 @@
"bcryptjs": "2.4.3",
"blurhash": "2.0.5",
"body-parser": "1.20.2",
"bullmq": "4.13.2",
"bullmq": "4.13.3",
"cacheable-lookup": "7.0.0",
"cbor": "9.0.1",
"chalk": "5.3.0",
@ -99,7 +99,7 @@
"date-fns": "2.30.0",
"deep-email-validator": "0.1.21",
"fastify": "4.24.3",
"fastify-raw-body": "^4.2.2",
"fastify-raw-body": "4.3.0",
"feed": "4.2.2",
"file-type": "18.7.0",
"fluent-ffmpeg": "2.1.2",
@ -132,7 +132,7 @@
"oauth2orize": "1.12.0",
"oauth2orize-pkce": "0.1.2",
"os-utils": "0.0.14",
"otpauth": "9.1.5",
"otpauth": "9.2.0",
"parse5": "7.1.2",
"pg": "8.11.3",
"pkce-challenge": "4.0.1",
@ -144,14 +144,14 @@
"qrcode": "1.5.3",
"random-seed": "0.3.0",
"ratelimiter": "3.4.1",
"re2": "1.20.5",
"re2": "1.20.8",
"redis-lock": "0.1.4",
"reflect-metadata": "0.1.13",
"rename": "1.0.4",
"rss-parser": "3.13.0",
"rxjs": "7.8.1",
"sanitize-html": "2.11.0",
"secure-json-parse": "^2.4.0",
"secure-json-parse": "2.7.0",
"sharp": "0.32.6",
"sharp-read-bmp": "github:misskey-dev/sharp-read-bmp",
"slacc": "0.0.10",
@ -192,7 +192,7 @@
"@types/jsrsasign": "10.5.12",
"@types/mime-types": "2.1.4",
"@types/ms": "0.7.34",
"@types/node": "20.9.0",
"@types/node": "20.9.1",
"@types/node-fetch": "3.0.3",
"@types/nodemailer": "6.4.14",
"@types/oauth": "0.9.4",

View File

@ -276,9 +276,18 @@ export class MfmService {
},
fn: (node) => {
const el = doc.createElement('i');
appendChildren(node.children, el);
return el;
if (node.props.name === 'unixtime') {
const text = node.children[0]!.type === 'text' ? node.children[0].props.text : '';
const date = new Date(parseInt(text, 10) * 1000);
const el = doc.createElement('time');
el.setAttribute('datetime', date.toISOString());
el.textContent = date.toISOString();
return el;
} else {
const el = doc.createElement('i');
appendChildren(node.children, el);
return el;
}
},
blockCode: (node) => {

View File

@ -24,8 +24,8 @@
"@rollup/pluginutils": "5.0.5",
"@syuilo/aiscript": "0.16.0",
"@tabler/icons-webfont": "2.37.0",
"@vitejs/plugin-vue": "4.4.1",
"@vue-macros/reactivity-transform": "0.3.23",
"@vitejs/plugin-vue": "4.5.0",
"@vue-macros/reactivity-transform": "0.4.0",
"@vue/compiler-sfc": "3.3.8",
"astring": "1.8.6",
"autosize": "6.0.1",
@ -57,7 +57,7 @@
"photoswipe": "5.4.2",
"punycode": "2.3.1",
"querystring": "0.2.1",
"rollup": "4.4.0",
"rollup": "4.4.1",
"sanitize-html": "2.11.0",
"shiki": "^0.14.5",
"sass": "1.69.5",
@ -101,7 +101,7 @@
"@types/estree": "1.0.5",
"@types/matter-js": "0.19.4",
"@types/micromatch": "4.0.5",
"@types/node": "20.9.0",
"@types/node": "20.9.1",
"@types/punycode": "2.1.2",
"@types/sanitize-html": "2.9.4",
"@types/throttle-debounce": "5.0.2",
@ -115,7 +115,7 @@
"@vue/runtime-core": "3.3.8",
"acorn": "8.11.2",
"cross-env": "7.0.3",
"cypress": "13.5.0",
"cypress": "13.5.1",
"eslint": "8.53.0",
"eslint-plugin-import": "2.29.0",
"eslint-plugin-vue": "9.18.1",
@ -128,7 +128,7 @@
"prettier": "3.1.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"start-server-and-test": "2.0.2",
"start-server-and-test": "2.0.3",
"storybook": "7.5.3",
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
"summaly": "github:misskey-dev/summaly",

View File

@ -45,12 +45,12 @@ import contains from '@/scripts/contains.js';
import { char2twemojiFilePath, char2fluentEmojiFilePath } from '@/scripts/emoji-base.js';
import { acct } from '@/filters/user.js';
import * as os from '@/os.js';
import { MFM_TAGS } from '@/scripts/mfm-tags.js';
import { defaultStore } from '@/store.js';
import { emojilist, getEmojiName } from '@/scripts/emojilist.js';
import { i18n } from '@/i18n.js';
import { miLocalStorage } from '@/local-storage.js';
import { customEmojis } from '@/custom-emojis.js';
import { MFM_TAGS } from '@/const.js';
type EmojiDef = {
emoji: string;

View File

@ -7,6 +7,7 @@ import { VNode, h } from 'vue';
import * as mfm from 'mfm-js';
import * as Misskey from 'misskey-js';
import MkUrl from '@/components/global/MkUrl.vue';
import MkTime from '@/components/global/MkTime.vue';
import MkLink from '@/components/MkLink.vue';
import MkMention from '@/components/MkMention.vue';
import MkEmoji from '@/components/global/MkEmoji.vue';
@ -238,6 +239,34 @@ export default function(props: MfmProps) {
style = `background-color: #${color};`;
break;
}
case 'ruby': {
if (token.children.length === 1) {
const child = token.children[0];
const text = child.type === 'text' ? child.props.text : '';
return h('ruby', {}, [text.split(' ')[0], h('rt', text.split(' ')[1])]);
} else {
const rt = token.children.at(-1)!;
const text = rt.type === 'text' ? rt.props.text : '';
return h('ruby', {}, [...genEl(token.children.slice(0, token.children.length - 1), scale), h('rt', text.trim())]);
}
}
case 'unixtime': {
const child = token.children[0];
const unixtime = parseInt(child.type === 'text' ? child.props.text : '');
return h('span', {
style: 'display: inline-block; font-size: 90%; border: solid 1px var(--divider); border-radius: 999px; padding: 4px 10px 4px 6px;',
}, [
h('i', {
class: 'ti ti-clock',
style: 'margin-right: 0.25em;',
}),
h(MkTime, {
key: Math.random(),
time: unixtime * 1000,
mode: 'detail',
}),
]);
}
}
if (style == null) {
return h('span', {}, ['$[', token.props.name, ' ', ...genEl(token.children, scale), ']']);

View File

@ -49,8 +49,15 @@ const relative = $computed<string>(() => {
ago >= 3600 ? i18n.t('_ago.hoursAgo', { n: Math.round(ago / 3600).toString() }) :
ago >= 60 ? i18n.t('_ago.minutesAgo', { n: (~~(ago / 60)).toString() }) :
ago >= 10 ? i18n.t('_ago.secondsAgo', { n: (~~(ago % 60)).toString() }) :
ago >= -1 ? i18n.ts._ago.justNow :
i18n.ts._ago.future);
ago >= -3 ? i18n.ts._ago.justNow :
ago < -31536000 ? i18n.t('_timeIn.years', { n: Math.round(-ago / 31536000).toString() }) :
ago < -2592000 ? i18n.t('_timeIn.months', { n: Math.round(-ago / 2592000).toString() }) :
ago < -604800 ? i18n.t('_timeIn.weeks', { n: Math.round(-ago / 604800).toString() }) :
ago < -86400 ? i18n.t('_timeIn.days', { n: Math.round(-ago / 86400).toString() }) :
ago < -3600 ? i18n.t('_timeIn.hours', { n: Math.round(-ago / 3600).toString() }) :
ago < -60 ? i18n.t('_timeIn.minutes', { n: (~~(-ago / 60)).toString() }) :
i18n.t('_timeIn.seconds', { n: (~~(-ago % 60)).toString() })
);
});
let tickId: number;

View File

@ -92,3 +92,5 @@ export const CURRENT_STICKY_BOTTOM = 'CURRENT_STICKY_BOTTOM';
export const DEFAULT_SERVER_ERROR_IMAGE_URL = 'https://xn--931a.moe/assets/error.jpg';
export const DEFAULT_NOT_FOUND_IMAGE_URL = 'https://xn--931a.moe/assets/not-found.jpg';
export const DEFAULT_INFO_IMAGE_URL = 'https://xn--931a.moe/assets/info.jpg';
export const MFM_TAGS = ['tada', 'jelly', 'twitch', 'shake', 'spin', 'jump', 'bounce', 'flip', 'x2', 'x3', 'x4', 'scale', 'position', 'fg', 'bg', 'font', 'blur', 'rainbow', 'sparkle', 'rotate', 'ruby', 'unixtime'];

View File

@ -18,16 +18,16 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSpacer v-else-if="tab === 'users'" :contentMax="1200">
<div class="_gaps_s">
<div v-if="role">{{ role.description }}</div>
<MkUserList v-if="visiable" :pagination="users" :extractor="(item) => item.user"/>
<div v-else-if="!visiable" class="_fullinfo">
<MkUserList v-if="visible" :pagination="users" :extractor="(item) => item.user"/>
<div v-else-if="!visible" class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<div>{{ i18n.ts.nothing }}</div>
</div>
</div>
</MkSpacer>
<MkSpacer v-else-if="tab === 'timeline'" :contentMax="700">
<MkTimeline v-if="visiable" ref="timeline" src="role" :role="props.role"/>
<div v-else-if="!visiable" class="_fullinfo">
<MkTimeline v-if="visible" ref="timeline" src="role" :role="props.role"/>
<div v-else-if="!visible" class="_fullinfo">
<img :src="infoImageUrl" class="_ghost"/>
<div>{{ i18n.ts.nothing }}</div>
</div>
@ -55,7 +55,7 @@ const props = withDefaults(defineProps<{
let tab = $ref(props.initialTab);
let role = $ref();
let error = $ref();
let visiable = $ref(false);
let visible = $ref(false);
watch(() => props.role, () => {
os.api('roles/show', {
@ -63,7 +63,7 @@ watch(() => props.role, () => {
}).then(res => {
role = res;
document.title = `${role?.name} | ${instanceName}`;
visiable = res.isExplorable && res.isPublic;
visible = res.isExplorable && res.isPublic;
}).catch((err) => {
if (err.code === 'NO_SUCH_ROLE') {
error = i18n.ts.noRole;

View File

@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<FormSection first>
<template #label>{{ i18n.ts.notificationRecieveConfig }}</template>
<div class="_gaps_s">
<MkFolder v-for="type in notificationTypes" :key="type">
<MkFolder v-for="type in notificationTypes.filter(x => !nonConfigurableNotificationTypes.includes(x))" :key="type">
<template #label>{{ i18n.t('_notification._types.' + type) }}</template>
<template #suffix>
{{
@ -68,6 +68,8 @@ import { definePageMetadata } from '@/scripts/page-metadata.js';
import MkPushNotificationAllowButton from '@/components/MkPushNotificationAllowButton.vue';
import { notificationTypes } from '@/const.js';
const nonConfigurableNotificationTypes = ['note'];
let allowButton = $shallowRef<InstanceType<typeof MkPushNotificationAllowButton>>();
let pushRegistrationInServer = $computed(() => allowButton?.pushRegistrationInServer);
let sendReadMessage = $computed(() => pushRegistrationInServer?.sendReadMessage || false);

View File

@ -1,6 +0,0 @@
/*
* SPDX-FileCopyrightText: syuilo and other misskey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
export const MFM_TAGS = ['tada', 'jelly', 'twitch', 'shake', 'spin', 'jump', 'bounce', 'flip', 'x2', 'x3', 'x4', 'scale', 'position', 'fg', 'bg', 'font', 'blur', 'rainbow', 'sparkle', 'rotate'];

View File

@ -23,7 +23,7 @@
"@microsoft/api-extractor": "7.38.3",
"@swc/jest": "0.2.29",
"@types/jest": "29.5.8",
"@types/node": "20.9.0",
"@types/node": "20.9.1",
"@typescript-eslint/eslint-plugin": "6.11.0",
"@typescript-eslint/parser": "6.11.0",
"eslint": "8.53.0",
@ -38,7 +38,7 @@
"built"
],
"dependencies": {
"@swc/cli": "0.1.62",
"@swc/cli": "0.1.63",
"@swc/core": "1.3.96",
"eventemitter3": "5.0.1",
"reconnecting-websocket": "4.4.0"

File diff suppressed because it is too large Load Diff