diff --git a/CHANGELOG.md b/CHANGELOG.md index 91d4edf12..2e1666b08 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,13 @@ You should also include the user name that made the change. --> +## 12.x.x (unreleased) + +### Improvements + +### Bugfixes +- クライアントが起動しなくなることがある問題を修正 @syuilo + ## 12.113.0 (2022/07/13) ### Improvements diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 9c17bf6d1..9d71dca54 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -888,6 +888,7 @@ enableAutoSensitive: "自動NSFW判定" enableAutoSensitiveDescription: "利用可能な場合は、機械学習を利用して自動でメディアにNSFWフラグを設定します。この機能をオフにしても、インスタンスによっては自動で設定されることがあります。" activeEmailValidationDescription: "ユーザーのメールアドレスのバリデーションを、捨てアドかどうかや実際に通信可能かどうかなどを判定しより積極的に行います。オフにすると単に文字列として正しいかどうかのみチェックされます。" showAds: "広告を表示する" +navbar: "ナビゲーションバー" _sensitiveMediaDetection: description: "機械学習を使って自動でセンシティブなメディアを検出し、モデレーションに役立てることができます。サーバーの負荷が少し増えます。" diff --git a/package.json b/package.json index 93df550f8..133e885aa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "misskey", - "version": "12.113.0", + "version": "12.114.0-beta.6", "codename": "indigo", "repository": { "type": "git", diff --git a/packages/backend/src/server/web/boot.js b/packages/backend/src/server/web/boot.js index 0a5cc0e0d..957011542 100644 --- a/packages/backend/src/server/web/boot.js +++ b/packages/backend/src/server/web/boot.js @@ -14,9 +14,11 @@ // ブロックの中に入れないと、定義した変数がブラウザのグローバルスコープに登録されてしまい邪魔なので (async () => { window.onerror = (e) => { + console.error(e); renderError('SOMETHING_HAPPENED', e); }; window.onunhandledrejection = (e) => { + console.error(e); renderError('SOMETHING_HAPPENED_IN_PROMISE', e); }; @@ -47,18 +49,30 @@ localStorage.setItem('localeVersion', v); } else { await checkUpdate(); - renderError('LOCALE_FETCH_FAILED'); + renderError('LOCALE_FETCH'); return; } } //#endregion //#region Script - import(`/assets/${CLIENT_ENTRY}`) - .catch(async e => { - await checkUpdate(); - renderError('APP_FETCH_FAILED', e); - }) + function importAppScript() { + import(`/assets/${CLIENT_ENTRY}`) + .catch(async e => { + await checkUpdate(); + console.error(e); + renderError('APP_IMPORT', e); + }); + } + + // タイミングによっては、この時点でDOMの構築が済んでいる場合とそうでない場合とがある + if (document.readyState !== 'loading') { + importAppScript(); + } else { + window.addEventListener('DOMContentLoaded', () => { + importAppScript(); + }); + } //#endregion //#region Theme @@ -112,35 +126,35 @@ let errorsElement = document.getElementById('errors'); if (!errorsElement) { - document.documentElement.innerHTML = ` + document.body.innerHTML = ` - - - + + +

An error has occurred!

-

Don't worry, it's (probably) not your fault.

+

Don't worry, it's (probably) not your fault.

If the problem persists after refreshing, please contact your instance's administrator.
You may also try the following options:

- - - + + +
- - - + + +
- - - + + +
`; @@ -269,17 +283,22 @@ // eslint-disable-next-line no-inner-declarations async function checkUpdate() { - // TODO: サーバーが落ちている場合などのエラーハンドリング - const res = await fetch('/api/meta', { - method: 'POST', - cache: 'no-cache' - }); + try { + const res = await fetch('/api/meta', { + method: 'POST', + cache: 'no-cache' + }); - const meta = await res.json(); + const meta = await res.json(); - if (meta.version != v) { - localStorage.setItem('v', meta.version); - refresh(); + if (meta.version != v) { + localStorage.setItem('v', meta.version); + refresh(); + } + } catch (e) { + console.error(e); + renderError('UPDATE_CHECK', e); + throw e; } } diff --git a/packages/client/package.json b/packages/client/package.json index 8d2efd0b9..94f6688dd 100644 --- a/packages/client/package.json +++ b/packages/client/package.json @@ -56,7 +56,6 @@ "random-seed": "0.3.0", "reflect-metadata": "0.1.13", "rndstr": "1.0.0", - "rollup": "2.76.0", "s-age": "1.1.2", "sass": "1.53.0", "seedrandom": "3.0.5", @@ -102,6 +101,7 @@ "@types/ws": "8.5.3", "@typescript-eslint/eslint-plugin": "5.30.6", "@typescript-eslint/parser": "5.30.6", + "rollup": "2.76.0", "cross-env": "7.0.3", "cypress": "10.3.0", "eslint": "8.19.0", diff --git a/packages/client/src/components/global/loading.vue b/packages/client/src/components/global/loading.vue index 5a7e362fc..bcc6dfac0 100644 --- a/packages/client/src/components/global/loading.vue +++ b/packages/client/src/components/global/loading.vue @@ -16,9 +16,7 @@ diff --git a/packages/client/src/ui/_common_/sidebar-for-mobile.vue b/packages/client/src/ui/_common_/navbar-for-mobile.vue similarity index 85% rename from packages/client/src/ui/_common_/sidebar-for-mobile.vue rename to packages/client/src/ui/_common_/navbar-for-mobile.vue index e789ae5e0..8ac4c1150 100644 --- a/packages/client/src/ui/_common_/sidebar-for-mobile.vue +++ b/packages/client/src/ui/_common_/navbar-for-mobile.vue @@ -9,9 +9,9 @@
@@ -37,7 +37,7 @@ import { computed, defineAsyncComponent, defineComponent, ref, toRef, watch } fr import { host } from '@/config'; import { search } from '@/scripts/search'; import * as os from '@/os'; -import { menuDef } from '@/menu'; +import { navbarItemDef } from '@/navbar'; import { openAccountMenu } from '@/account'; import { defaultStore } from '@/store'; @@ -45,9 +45,9 @@ export default defineComponent({ setup(props, context) { const menu = toRef(defaultStore.state, 'menu'); const otherMenuItemIndicated = computed(() => { - for (const def in menuDef) { + for (const def in navbarItemDef) { if (menu.value.includes(def)) continue; - if (menuDef[def].indicated) return true; + if (navbarItemDef[def].indicated) return true; } return false; }); @@ -57,7 +57,7 @@ export default defineComponent({ accounts: [], connection: null, menu, - menuDef: menuDef, + navbarItemDef: navbarItemDef, otherMenuItemIndicated, post: os.post, search, diff --git a/packages/client/src/ui/_common_/sidebar.vue b/packages/client/src/ui/_common_/navbar.vue similarity index 79% rename from packages/client/src/ui/_common_/sidebar.vue rename to packages/client/src/ui/_common_/navbar.vue index a72bf786a..924dda25d 100644 --- a/packages/client/src/ui/_common_/sidebar.vue +++ b/packages/client/src/ui/_common_/navbar.vue @@ -4,29 +4,38 @@ - - {{ $ts.timeline }} + + {{ i18n.ts.timeline }}
- - {{ $ts.controlPanel }} + + {{ i18n.ts.controlPanel }} - - {{ $ts.settings }} + + {{ i18n.ts.settings }} @@ -35,17 +44,18 @@ diff --git a/packages/client/src/ui/classic.sidebar.vue b/packages/client/src/ui/classic.sidebar.vue index 6c0ce023e..172401f42 100644 --- a/packages/client/src/ui/classic.sidebar.vue +++ b/packages/client/src/ui/classic.sidebar.vue @@ -14,9 +14,9 @@
@@ -45,7 +45,7 @@ import { defineAsyncComponent, defineComponent } from 'vue'; import { host } from '@/config'; import { search } from '@/scripts/search'; import * as os from '@/os'; -import { menuDef } from '@/menu'; +import { navbarItemDef } from '@/navbar'; import { openAccountMenu } from '@/account'; import MkButton from '@/components/ui/button.vue'; import { StickySidebar } from '@/scripts/sticky-sidebar'; @@ -62,7 +62,7 @@ export default defineComponent({ host: host, accounts: [], connection: null, - menuDef: menuDef, + navbarItemDef: navbarItemDef, iconOnly: false, settingsWindowed: false, }; @@ -74,9 +74,9 @@ export default defineComponent({ }, otherNavItemIndicated(): boolean { - for (const def in this.menuDef) { + for (const def in this.navbarItemDef) { if (this.menu.includes(def)) continue; - if (this.menuDef[def].indicated) return true; + if (this.navbarItemDef[def].indicated) return true; } return false; }, @@ -131,7 +131,7 @@ export default defineComponent({ withExtraOperation: true, }, ev); }, - } + }, }); diff --git a/packages/client/src/ui/classic.vue b/packages/client/src/ui/classic.vue index 70db7ed12..c42407f5b 100644 --- a/packages/client/src/ui/classic.vue +++ b/packages/client/src/ui/classic.vue @@ -47,7 +47,6 @@ import XCommon from './_common_/common.vue'; import { instanceName } from '@/config'; import { StickySidebar } from '@/scripts/sticky-sidebar'; import * as os from '@/os'; -import { menuDef } from '@/menu'; import { mainRouter } from '@/router'; import { PageMetadata, provideMetadataReceiver, setPageMetadata } from '@/scripts/page-metadata'; import { defaultStore } from '@/store'; diff --git a/packages/client/src/ui/deck.vue b/packages/client/src/ui/deck.vue index 19a99a95a..f330c9981 100644 --- a/packages/client/src/ui/deck.vue +++ b/packages/client/src/ui/deck.vue @@ -69,12 +69,12 @@ import { v4 as uuid } from 'uuid'; import XCommon from './_common_/common.vue'; import { deckStore, addColumn as addColumnToStore, loadDeck } from './deck/deck-store'; import DeckColumnCore from '@/ui/deck/column-core.vue'; -import XSidebar from '@/ui/_common_/sidebar.vue'; -import XDrawerMenu from '@/ui/_common_/sidebar-for-mobile.vue'; +import XSidebar from '@/ui/_common_/navbar.vue'; +import XDrawerMenu from '@/ui/_common_/navbar-for-mobile.vue'; import MkButton from '@/components/ui/button.vue'; import { getScrollContainer } from '@/scripts/scroll'; import * as os from '@/os'; -import { menuDef } from '@/menu'; +import { navbarItemDef } from '@/navbar'; import { $i } from '@/account'; import { i18n } from '@/i18n'; import { mainRouter } from '@/router'; @@ -105,8 +105,8 @@ const columns = deckStore.reactiveState.columns; const layout = deckStore.reactiveState.layout; const menuIndicated = computed(() => { if ($i == null) return false; - for (const def in menuDef) { - if (menuDef[def].indicated) return true; + for (const def in navbarItemDef) { + if (navbarItemDef[def].indicated) return true; } return false; }); diff --git a/packages/client/src/ui/universal.vue b/packages/client/src/ui/universal.vue index 2edfb3f12..fe4fc425c 100644 --- a/packages/client/src/ui/universal.vue +++ b/packages/client/src/ui/universal.vue @@ -61,17 +61,17 @@ import { defineAsyncComponent, provide, onMounted, computed, ref, watch, Compute import XCommon from './_common_/common.vue'; import { instanceName } from '@/config'; import { StickySidebar } from '@/scripts/sticky-sidebar'; -import XDrawerMenu from '@/ui/_common_/sidebar-for-mobile.vue'; +import XDrawerMenu from '@/ui/_common_/navbar-for-mobile.vue'; import * as os from '@/os'; import { defaultStore } from '@/store'; -import { menuDef } from '@/menu'; +import { navbarItemDef } from '@/navbar'; import { i18n } from '@/i18n'; import { $i } from '@/account'; import { Router } from '@/nirax'; import { mainRouter } from '@/router'; import { PageMetadata, provideMetadataReceiver, setPageMetadata } from '@/scripts/page-metadata'; const XWidgets = defineAsyncComponent(() => import('./universal.widgets.vue')); -const XSidebar = defineAsyncComponent(() => import('@/ui/_common_/sidebar.vue')); +const XSidebar = defineAsyncComponent(() => import('@/ui/_common_/navbar.vue')); const XStatusBars = defineAsyncComponent(() => import('@/ui/_common_/statusbars.vue')); const DESKTOP_THRESHOLD = 1100; @@ -97,9 +97,9 @@ provideMetadataReceiver((info) => { }); const menuIndicated = computed(() => { - for (const def in menuDef) { + for (const def in navbarItemDef) { if (def === 'notifications') continue; // 通知は下にボタンとして表示されてるから - if (menuDef[def].indicated) return true; + if (navbarItemDef[def].indicated) return true; } return false; }); diff --git a/packages/client/vite.json5.ts b/packages/client/vite.json5.ts index 693ee7be0..0a37fbff4 100644 --- a/packages/client/vite.json5.ts +++ b/packages/client/vite.json5.ts @@ -6,33 +6,33 @@ import { createFilter, dataToEsm } from '@rollup/pluginutils'; import { RollupJsonOptions } from '@rollup/plugin-json'; export default function json5(options: RollupJsonOptions = {}): Plugin { - const filter = createFilter(options.include, options.exclude); - const indent = 'indent' in options ? options.indent : '\t'; + const filter = createFilter(options.include, options.exclude); + const indent = 'indent' in options ? options.indent : '\t'; - return { - name: 'json5', + return { + name: 'json5', - // eslint-disable-next-line no-shadow - transform(json, id) { - if (id.slice(-6) !== '.json5' || !filter(id)) return null; + // eslint-disable-next-line no-shadow + transform(json, id) { + if (id.slice(-6) !== '.json5' || !filter(id)) return null; - try { - const parsed = JSON5.parse(json); - return { - code: dataToEsm(parsed, { - preferConst: options.preferConst, - compact: options.compact, - namedExports: options.namedExports, - indent - }), - map: { mappings: '' } - }; - } catch (err) { - const message = 'Could not parse JSON file'; - const position = parseInt(/[\d]/.exec(err.message)[0], 10); - this.warn({ message, id, position }); - return null; - } - } - }; + try { + const parsed = JSON5.parse(json); + return { + code: dataToEsm(parsed, { + preferConst: options.preferConst, + compact: options.compact, + namedExports: options.namedExports, + indent, + }), + map: { mappings: '' }, + }; + } catch (err) { + const message = 'Could not parse JSON file'; + const position = parseInt(/[\d]/.exec(err.message)[0], 10); + this.warn({ message, id, position }); + return null; + } + }, + }; }