diff --git a/.node-version b/.node-version index e27f7a8bf..971a6537e 100644 --- a/.node-version +++ b/.node-version @@ -1 +1 @@ -v16.2.0 +v16.6.2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e530f930..4fc982beb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,25 @@ + + +## 12.87.0 (2021/08/12) + +### Improvements +- 絵文字オートコンプリートで一文字目は最近使った絵文字をサジェストするように +- 絵文字オートコンプリートのパフォーマンスを改善 +- about-misskeyページにドキュメントへのリンクを追加 +- Docker: Node.jsを16.6.2に +- 依存関係の更新 +- 翻訳の更新 + +### Bugfixes +- Misskey更新時、テーマキャッシュの影響でスタイルがおかしくなる問題を修正 + ## 12.86.0 (2021/08/11) ### Improvements @@ -9,4 +31,4 @@ ### Bugfixes - ハッシュタグ入力が空のときに#が付くのを修正 -- フォロー通知のEメール通知を修正 +- フォローリクエストのEメール通知を修正 diff --git a/Dockerfile b/Dockerfile index c090839e7..db879b6db 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:16.2.0-alpine3.13 AS base +FROM node:16.6.2-alpine3.13 AS base ENV NODE_ENV=production diff --git a/locales/de-DE.yml b/locales/de-DE.yml index e9cca4249..59aac7e33 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -771,6 +771,7 @@ received: "Erhalten" searchResult: "Suchergebnisse" hashtags: "Hashtags" troubleshooting: "Problembehandlung" +useBlurEffect: "Weichzeichnungseffekt in der Benutzeroberfläche verwenden" _docs: continueReading: "Mehr lesen" features: "Funktionen" diff --git a/locales/en-US.yml b/locales/en-US.yml index 36ce8c0f8..94e374c8d 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -249,7 +249,7 @@ agreeTo: "I agree to {0}" tos: "Terms of Service" start: "Begin" home: "Home" -remoteUserCaution: "As this user is from a renote instance, the shown information may be incomplete." +remoteUserCaution: "As this user is from a remote instance, the shown information may be incomplete." activity: "Activity" images: "Images" birthday: "Birthday" @@ -771,6 +771,7 @@ received: "Received" searchResult: "Search results" hashtags: "Hashtags" troubleshooting: "Troubleshooting" +useBlurEffect: "Use blur effects in the UI" _docs: continueReading: "Read more" features: "Features" diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 9b03c20cd..be4792401 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -772,6 +772,7 @@ searchResult: "検索結果" hashtags: "ハッシュタグ" troubleshooting: "トラブルシューティング" useBlurEffect: "UIにぼかし効果を使用" +learnMore: "詳しく" _docs: continueReading: "続きを読む" diff --git a/locales/ko-KR.yml b/locales/ko-KR.yml index 6562874bc..c4cc84caf 100644 --- a/locales/ko-KR.yml +++ b/locales/ko-KR.yml @@ -771,12 +771,14 @@ received: "수신" searchResult: "검색 결과" hashtags: "해시태그" troubleshooting: "트러블 슈팅" +useBlurEffect: "UI에 흐림 효과 사용" _docs: continueReading: "계속 읽기" features: "기능" generalTopics: "일반 주제" advancedTopics: "심화 주제" admin: "관리" + translateWarn: "이 문서는 번역되었기 때문에 원본과는 내용이 다를 수 있습니다." _ad: back: "뒤로" reduceFrequencyOfThisAd: "이 광고의 표시 빈도 낮추기" diff --git a/locales/ru-RU.yml b/locales/ru-RU.yml index 2d1334f52..b9cfe6f2c 100644 --- a/locales/ru-RU.yml +++ b/locales/ru-RU.yml @@ -529,6 +529,7 @@ removeAllFollowing: "Удалить всех подписчиков" removeAllFollowingDescription: "Отменить все подписки с домена {host}? Пожалуйста, применяйте это действие, если инстанс больше не существует." userSuspended: "Эта учётная запись заморожена" userSilenced: "Этот пользователь был заглушен" +menu: "Меню" divider: "Линия-разделитель" addItem: "Добавить элемент" rooms: "Комната" @@ -761,15 +762,23 @@ middle: "Средне" low: "Низкий" emailNotConfiguredWarning: "Не указан адрес электронной почты" ratio: "Соотношение" +customCss: "Индивидуальный CSS" +customCssWarn: "Используйте эту настройку только если знаете, что делаете. Ошибки здесь чреваты тем, что сайт перестанет нормально работать у вас." global: "Всеобщая" +squareAvatars: "Квадратные аватарки" sent: "Отправить" +received: "Получено" +searchResult: "Результаты поиска" hashtags: "Хэштег" +troubleshooting: "Разрешение проблем" +useBlurEffect: "Размытие в интерфейсе" _docs: continueReading: "Читать подробнее" features: "Возможности" generalTopics: "Основные темы" advancedTopics: "Дополнительные темы" admin: "Управление" + translateWarn: "Это перевод документа. Он может неточно отражать содержимое оригинала." _ad: back: "Выход" reduceFrequencyOfThisAd: "Реже показывать эту рекламу" diff --git a/locales/zh-CN.yml b/locales/zh-CN.yml index 650353dac..afe364d4e 100644 --- a/locales/zh-CN.yml +++ b/locales/zh-CN.yml @@ -771,6 +771,8 @@ received: "收取" searchResult: "搜索结果" hashtags: "话题标签" troubleshooting: "故障排除" +useBlurEffect: "在UI上使用模糊效果" +learnMore: "更多信息" _docs: continueReading: "继续阅读" features: "特性" diff --git a/package.json b/package.json index 93517177c..1db104477 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "misskey", "author": "syuilo ", - "version": "12.86.0", + "version": "12.87.0", "codename": "indigo", "repository": { "type": "git", @@ -44,7 +44,7 @@ "@sinonjs/fake-timers": "7.1.2", "@syuilo/aiscript": "0.11.1", "@types/bcryptjs": "2.4.2", - "@types/bull": "3.15.2", + "@types/bull": "3.15.3", "@types/cbor": "6.0.0", "@types/dateformat": "3.0.1", "@types/escape-regexp": "0.0.0", @@ -57,8 +57,8 @@ "@types/jsonld": "1.5.6", "@types/katex": "0.11.1", "@types/koa": "2.13.4", - "@types/koa-bodyparser": "4.3.2", - "@types/koa-cors": "0.0.1", + "@types/koa-bodyparser": "4.3.3", + "@types/koa-cors": "0.0.2", "@types/koa-favicon": "2.0.21", "@types/koa-logger": "3.1.1", "@types/koa-mount": "4.0.0", @@ -68,10 +68,10 @@ "@types/koa__multer": "2.0.3", "@types/koa__router": "8.0.7", "@types/markdown-it": "12.0.3", - "@types/matter-js": "0.17.3", + "@types/matter-js": "0.17.5", "@types/mocha": "8.2.3", - "@types/node": "16.3.3", - "@types/node-fetch": "2.5.11", + "@types/node": "16.6.0", + "@types/node-fetch": "2.5.12", "@types/nodemailer": "6.4.4", "@types/nprogress": "0.2.0", "@types/oauth": "0.9.1", @@ -88,7 +88,7 @@ "@types/request-stats": "3.0.0", "@types/rimraf": "3.0.1", "@types/seedrandom": "2.4.28", - "@types/sharp": "0.28.4", + "@types/sharp": "0.28.5", "@types/sinonjs__fake-timers": "6.0.3", "@types/speakeasy": "2.0.6", "@types/throttle-debounce": "2.1.0", @@ -98,40 +98,40 @@ "@types/web-push": "3.3.2", "@types/webpack": "5.28.0", "@types/webpack-stream": "3.2.12", - "@types/websocket": "1.0.3", - "@types/ws": "7.4.6", - "@typescript-eslint/parser": "4.28.3", - "@vue/compiler-sfc": "3.2.1", + "@types/websocket": "1.0.4", + "@types/ws": "7.4.7", + "@typescript-eslint/parser": "4.29.1", + "@vue/compiler-sfc": "3.2.2", "abort-controller": "3.0.0", - "apexcharts": "3.27.2", + "apexcharts": "3.27.3", "autobind-decorator": "2.4.0", "autosize": "4.0.4", "autwh": "0.1.0", - "aws-sdk": "2.948.0", + "aws-sdk": "2.966.0", "bcryptjs": "2.4.3", "blurhash": "1.1.3", "broadcast-channel": "3.7.0", "bull": "3.26.0", "cafy": "15.2.1", - "cbor": "7.0.6", - "chalk": "4.1.1", + "cbor": "8.0.0", + "chalk": "4.1.2", "chart.js": "2.9.4", "cli-highlight": "2.1.11", "commander": "7.2.0", "concurrently": "6.2.0", "content-disposition": "0.5.3", - "core-js": "3.15.2", + "core-js": "3.16.1", "crc-32": "1.2.0", - "css-loader": "6.0.0", - "cssnano": "5.0.6", + "css-loader": "6.2.0", + "cssnano": "5.0.7", "dateformat": "4.5.1", "diskusage": "1.1.3", "escape-regexp": "0.0.1", - "eslint": "7.30.0", - "eslint-plugin-vue": "7.13.0", + "eslint": "7.32.0", + "eslint-plugin-vue": "7.16.0", "eventemitter3": "4.0.7", "feed": "4.2.2", - "file-type": "16.5.1", + "file-type": "16.5.3", "fluent-ffmpeg": "2.1.2", "glob": "7.1.7", "got": "11.8.2", @@ -146,17 +146,17 @@ "http-proxy-agent": "4.0.1", "http-signature": "1.3.5", "https-proxy-agent": "5.0.0", - "idb-keyval": "5.0.6", + "idb-keyval": "5.1.3", "insert-text-at-cursor": "0.3.0", "is-root": "2.1.0", "is-svg": "4.3.1", "js-yaml": "4.1.0", - "jsdom": "16.6.0", + "jsdom": "16.7.0", "json5": "2.2.0", "json5-loader": "4.0.1", "jsonld": "5.2.0", "jsrsasign": "8.0.20", - "katex": "0.13.11", + "katex": "0.13.13", "koa": "2.13.1", "koa-bodyparser": "4.3.0", "koa-favicon": "2.1.0", @@ -168,7 +168,7 @@ "koa-views": "7.0.1", "langmap": "0.0.16", "lookup-dns-cache": "2.1.0", - "markdown-it": "12.1.0", + "markdown-it": "12.2.0", "markdown-it-anchor": "7.1.0", "matter-js": "0.17.1", "mfm-js": "0.19.0", @@ -176,7 +176,7 @@ "mocha": "8.4.0", "moji": "0.5.1", "ms": "2.1.3", - "multer": "1.4.2", + "multer": "1.4.3", "nested-property": "4.0.0", "node-fetch": "2.6.1", "nodemailer": "6.6.3", @@ -185,7 +185,7 @@ "parse5": "6.0.1", "pg": "8.6.0", "portscanner": "2.2.0", - "postcss": "8.3.5", + "postcss": "8.3.6", "postcss-loader": "6.1.1", "prismjs": "1.24.1", "probe-image-size": "7.2.1", @@ -202,32 +202,32 @@ "redis": "3.1.2", "redis-lock": "0.1.4", "reflect-metadata": "0.1.13", - "regenerator-runtime": "0.13.7", + "regenerator-runtime": "0.13.9", "rename": "1.0.4", "request-stats": "3.0.0", "require-all": "3.0.0", "rimraf": "3.0.2", "rndstr": "1.0.0", "s-age": "1.1.2", - "sass": "1.35.2", + "sass": "1.37.5", "sass-loader": "12.1.0", "seedrandom": "3.0.5", "sharp": "0.28.3", "speakeasy": "2.0.0", "stringz": "2.1.0", - "style-loader": "3.1.0", - "summaly": "2.4.0", + "style-loader": "3.2.1", + "summaly": "2.4.1", "syslog-pro": "1.0.0", - "systeminformation": "5.7.7", + "systeminformation": "5.8.0", "syuilo-password-strength": "0.0.1", "textarea-caret": "3.1.0", "three": "0.117.1", "throttle-debounce": "3.0.1", "tinycolor2": "1.4.2", "tmp": "0.2.1", - "ts-loader": "9.2.3", - "ts-node": "10.1.0", - "tsc-alias": "1.3.7", + "ts-loader": "9.2.5", + "ts-node": "10.2.0", + "tsc-alias": "1.3.8", "tsconfig-paths": "3.10.1", "tslint": "6.1.3", "tslint-sonarts": "1.9.0", @@ -237,21 +237,21 @@ "ulid": "2.3.0", "uuid": "8.3.2", "v-debounce": "0.1.2", - "vanilla-tilt": "1.7.0", - "vue": "3.2.1", + "vanilla-tilt": "1.7.1", + "vue": "3.2.2", "vue-color": "2.8.1", "vue-json-pretty": "1.8.1", - "vue-loader": "16.3.1", + "vue-loader": "16.5.0", "vue-prism-editor": "2.0.0-alpha.2", "vue-router": "4.0.5", "vue-style-loader": "4.1.3", "vue-svg-loader": "0.17.0-beta.2", "vuedraggable": "4.0.1", "web-push": "3.4.5", - "webpack": "5.45.1", + "webpack": "5.50.0", "webpack-cli": "4.7.2", "websocket": "1.0.34", - "ws": "7.5.3", + "ws": "8.1.0", "xev": "2.0.1" }, "devDependencies": { diff --git a/src/client/components/autocomplete.vue b/src/client/components/autocomplete.vue index 35cfb7730..065ee6de2 100644 --- a/src/client/components/autocomplete.vue +++ b/src/client/components/autocomplete.vue @@ -35,6 +35,7 @@ import { twemojiSvgBase } from '@/misc/twemoji-base'; import { getStaticImageUrl } from '@client/scripts/get-static-image-url'; import { acct } from '@client/filters/user'; import * as os from '@client/os'; +import { instance } from '@client/instance'; type EmojiDef = { emoji: string; @@ -75,6 +76,36 @@ for (const x of lib) { emjdb.sort((a, b) => a.name.length - b.name.length); +//#region Construct Emoji DB +const customEmojis = instance.emojis; +const emojiDefinitions: EmojiDef[] = []; + +for (const x of customEmojis) { + emojiDefinitions.push({ + name: x.name, + emoji: `:${x.name}:`, + url: x.url, + isCustomEmoji: true + }); + + if (x.aliases) { + for (const alias of x.aliases) { + emojiDefinitions.push({ + name: alias, + aliasOf: x.name, + emoji: `:${x.name}:`, + url: x.url, + isCustomEmoji: true + }); + } + } +} + +emojiDefinitions.sort((a, b) => a.name.length - b.name.length); + +const emojiDb = markRaw(emojiDefinitions.concat(emjdb)); +//#endregion + export default defineComponent({ props: { type: { @@ -124,7 +155,6 @@ export default defineComponent({ emojis: [], items: [], select: -1, - emojiDb: [] as EmojiDef[] } }, @@ -144,36 +174,6 @@ export default defineComponent({ mounted() { this.setPosition(); - //#region Construct Emoji DB - const customEmojis = this.$instance.emojis; - const emojiDefinitions: EmojiDef[] = []; - - for (const x of customEmojis) { - emojiDefinitions.push({ - name: x.name, - emoji: `:${x.name}:`, - url: x.url, - isCustomEmoji: true - }); - - if (x.aliases) { - for (const alias of x.aliases) { - emojiDefinitions.push({ - name: alias, - aliasOf: x.name, - emoji: `:${x.name}:`, - url: x.url, - isCustomEmoji: true - }); - } - } - } - - emojiDefinitions.sort((a, b) => a.name.length - b.name.length); - - this.emojiDb = markRaw(emojiDefinitions.concat(emjdb)); - //#endregion - this.textarea.addEventListener('keydown', this.onKeydown); for (const el of Array.from(document.querySelectorAll('body *'))) { @@ -203,6 +203,13 @@ export default defineComponent({ complete(type, value) { this.$emit('done', { type, value }); this.$emit('closed'); + + if (type === 'emoji') { + let recents = this.$store.state.recentlyUsedEmojis; + recents = recents.filter((e: any) => e !== value); + recents.unshift(value); + this.$store.set('recentlyUsedEmojis', recents.splice(0, 32)); + } }, setPosition() { @@ -281,29 +288,26 @@ export default defineComponent({ } } else if (this.type == 'emoji') { if (this.q == null || this.q == '') { - this.emojis = this.emojiDb.filter(x => x.isCustomEmoji && !x.aliasOf).sort((a, b) => { - var textA = a.name.toUpperCase(); - var textB = b.name.toUpperCase(); - return (textA < textB) ? -1 : (textA > textB) ? 1 : 0; - }); + // 最近使った絵文字をサジェスト + this.emojis = this.$store.state.recentlyUsedEmojis.map(emoji => emojiDb.find(e => e.emoji == emoji)).filter(x => x != null); return; } const matched = []; const max = 30; - this.emojiDb.some(x => { + emojiDb.some(x => { if (x.name.startsWith(this.q) && !x.aliasOf && !matched.some(y => y.emoji == x.emoji)) matched.push(x); return matched.length == max; }); if (matched.length < max) { - this.emojiDb.some(x => { + emojiDb.some(x => { if (x.name.startsWith(this.q) && !matched.some(y => y.emoji == x.emoji)) matched.push(x); return matched.length == max; }); } if (matched.length < max) { - this.emojiDb.some(x => { + emojiDb.some(x => { if (x.name.includes(this.q) && !matched.some(y => y.emoji == x.emoji)) matched.push(x); return matched.length == max; }); diff --git a/src/client/init.ts b/src/client/init.ts index a4a228da2..95aa18862 100644 --- a/src/client/init.ts +++ b/src/client/init.ts @@ -16,7 +16,7 @@ import { router } from '@client/router'; import { applyTheme } from '@client/scripts/theme'; import { isDeviceDarkmode } from '@client/scripts/is-device-darkmode'; import { i18n } from '@client/i18n'; -import { stream, dialog, post } from '@client/os'; +import { stream, dialog, post, popup } from '@client/os'; import * as sound from '@client/scripts/sound'; import { $i, refreshAccount, login, updateAccount, signout } from '@client/account'; import { defaultStore, ColdDeviceStorage } from '@client/store'; @@ -198,6 +198,19 @@ if (splash) { splash.style.pointerEvents = 'none'; } +// クライアントが更新されたか? +const lastVersion = localStorage.getItem('lastVersion'); +if (lastVersion !== version) { + localStorage.setItem('lastVersion', version); + + // テーマリビルドするため + localStorage.removeItem('theme'); + + // TODO: バージョンが新しくなった時だけダイアログ出す + //popup(); +} + +// NOTE: この処理は必ず↑のクライアント更新時処理より後に来ること(テーマ再構築のため) watch(defaultStore.reactiveState.darkMode, (darkMode) => { applyTheme(darkMode ? ColdDeviceStorage.get('darkTheme') : ColdDeviceStorage.get('lightTheme')); }, { immediate: localStorage.theme == null }); diff --git a/src/client/pages/about-misskey.vue b/src/client/pages/about-misskey.vue index f7b9245fc..a324ebce5 100644 --- a/src/client/pages/about-misskey.vue +++ b/src/client/pages/about-misskey.vue @@ -4,14 +4,14 @@
- +
Misskey
v{{ version }}
-
- {{ $ts._aboutMisskey.about }} +
+ {{ $ts._aboutMisskey.about }}
{{ $ts.learnMore }}
@@ -54,7 +54,6 @@