chore: 共通してるロジックをいくつか移動
This commit is contained in:
parent
0ec4f87ef8
commit
d97547da05
|
@ -5,22 +5,24 @@
|
|||
|
||||
'use strict';
|
||||
|
||||
import { addStyle, bootloaderLocales, detectLanguage } from '@@/js/bootloader';
|
||||
|
||||
interface Window {
|
||||
CLIENT_ENTRY: string | undefined;
|
||||
}
|
||||
|
||||
// ブロックの中に入れないと、定義した変数がブラウザのグローバルスコープに登録されてしまい邪魔なので
|
||||
(async () => {
|
||||
window.onerror = (e) => {
|
||||
console.error(e);
|
||||
window.onerror = (error) => {
|
||||
console.error(error);
|
||||
renderError('SOMETHING_HAPPENED');
|
||||
};
|
||||
window.onunhandledrejection = (e) => {
|
||||
console.error(e);
|
||||
window.onunhandledrejection = (error) => {
|
||||
console.error(error);
|
||||
renderError('SOMETHING_HAPPENED_IN_PROMISE');
|
||||
};
|
||||
|
||||
let forceError = localStorage.getItem('forceError');
|
||||
const forceError = localStorage.getItem('forceError');
|
||||
if (forceError != null) {
|
||||
renderError('FORCED_ERROR', 'This error is forced by having forceError in local storage.');
|
||||
return;
|
||||
|
@ -35,33 +37,13 @@ interface Window {
|
|||
document.documentElement.classList.add('noborder');
|
||||
}
|
||||
|
||||
//#region Detect language & fetch translations
|
||||
const supportedLangs = _LANG_IDS_;
|
||||
/** @type { string } */
|
||||
let lang = localStorage.getItem('lang');
|
||||
if (lang == null || !supportedLangs.includes(lang)) {
|
||||
if (supportedLangs.includes(navigator.language)) {
|
||||
lang = navigator.language;
|
||||
} else {
|
||||
lang = supportedLangs.find(x => x.split('-')[0] === navigator.language);
|
||||
|
||||
// Fallback
|
||||
if (lang == null) lang = 'en-US';
|
||||
}
|
||||
}
|
||||
|
||||
// for https://github.com/misskey-dev/misskey/issues/10202
|
||||
if (lang == null || lang.toString == null || lang.toString() === 'null') {
|
||||
console.error('invalid lang value detected!!!', typeof lang, lang);
|
||||
lang = 'en-US';
|
||||
}
|
||||
//#endregion
|
||||
const lang = detectLanguage();
|
||||
|
||||
//#region Script
|
||||
async function importAppScript() {
|
||||
await import(`/embed_vite/${(window.CLIENT_ENTRY ?? 'src/boot.ts').replace('scripts', lang)}`)
|
||||
.catch(async e => {
|
||||
console.error(e);
|
||||
.catch(async error => {
|
||||
console.error(error);
|
||||
renderError('APP_IMPORT');
|
||||
});
|
||||
}
|
||||
|
@ -76,44 +58,19 @@ interface Window {
|
|||
}
|
||||
//#endregion
|
||||
|
||||
async function addStyle(styleText) {
|
||||
let css = document.createElement('style');
|
||||
css.appendChild(document.createTextNode(styleText));
|
||||
document.head.appendChild(css);
|
||||
}
|
||||
|
||||
async function renderError(code) {
|
||||
async function renderError(code: string, _details?) {
|
||||
// Cannot set property 'innerHTML' of null を回避
|
||||
if (document.readyState === 'loading') {
|
||||
await new Promise(resolve => window.addEventListener('DOMContentLoaded', resolve));
|
||||
}
|
||||
|
||||
let messages = null;
|
||||
const bootloaderLocales = localStorage.getItem('bootloaderLocales');
|
||||
if (bootloaderLocales) {
|
||||
messages = JSON.parse(bootloaderLocales);
|
||||
}
|
||||
if (!messages) {
|
||||
// older version of misskey does not store bootloaderLocales, stores locale as a whole
|
||||
const legacyLocale = localStorage.getItem('locale');
|
||||
if (legacyLocale) {
|
||||
const parsed = JSON.parse(legacyLocale);
|
||||
messages = {
|
||||
...(parsed._bootErrors ?? {}),
|
||||
reload: parsed.reload,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (!messages) messages = {};
|
||||
|
||||
const title = messages?.title || 'Failed to initialize Misskey';
|
||||
const reload = messages?.reload || 'Reload';
|
||||
const messages = bootloaderLocales();
|
||||
|
||||
document.body.innerHTML = `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="icon"><path stroke="none" d="M0 0h24v24H0z" fill="none"/><path d="M12 12m-9 0a9 9 0 1 0 18 0a9 9 0 1 0 -18 0" /><path d="M12 9v4" /><path d="M12 16v.01" /></svg>
|
||||
<div class="message">${title}</div>
|
||||
<div class="message">${messages.title}</div>
|
||||
<div class="submessage">Error Code: ${code}</div>
|
||||
<button onclick="location.reload(!0)">
|
||||
<div>${reload}</div>
|
||||
<div>${messages.reload}</div>
|
||||
</button>`;
|
||||
addStyle(`
|
||||
#misskey_app,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
type FIXME = any;
|
||||
|
||||
declare const _LANGS_: string[][];
|
||||
declare const _LANG_IDS_: string[];
|
||||
declare const _VERSION_: string;
|
||||
declare const _ENV_: string;
|
||||
declare const _DEV_: boolean;
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: syuilo and misskey-project
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
// common portion of bootloader for frontend and frontend-embed
|
||||
|
||||
import type { Locale } from '../../../locales/index.js';
|
||||
|
||||
export function detectLanguage(): string {
|
||||
const supportedLangs = _LANG_IDS_;
|
||||
let lang: string | null | undefined = localStorage.getItem('lang');
|
||||
if (lang == null || !supportedLangs.includes(lang)) {
|
||||
if (supportedLangs.includes(navigator.language)) {
|
||||
lang = navigator.language;
|
||||
} else {
|
||||
lang = supportedLangs.find(x => x.split('-')[0] === navigator.language);
|
||||
|
||||
// Fallback
|
||||
lang ??= 'en-US';
|
||||
}
|
||||
}
|
||||
|
||||
// for https://github.com/misskey-dev/misskey/issues/10202
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
if (lang == null || lang.toString == null || lang.toString() === 'null') {
|
||||
console.error('invalid lang value detected!!!', typeof lang, lang);
|
||||
lang = 'en-US';
|
||||
}
|
||||
|
||||
return lang;
|
||||
}
|
||||
|
||||
type BootLoaderLocales = Locale['_bootErrors'] & Pick<Locale, 'reload'>;
|
||||
|
||||
export function bootloaderLocales(): BootLoaderLocales {
|
||||
let messages: Partial<BootLoaderLocales> | null = null;
|
||||
const bootloaderLocalesJson = localStorage.getItem('bootloaderLocales');
|
||||
if (bootloaderLocalesJson) {
|
||||
messages = JSON.parse(bootloaderLocalesJson);
|
||||
}
|
||||
if (!messages) {
|
||||
// older version of misskey does not store bootloaderLocales, stores locale as a whole
|
||||
const legacyLocale = localStorage.getItem('locale');
|
||||
if (legacyLocale) {
|
||||
const parsed = JSON.parse(legacyLocale);
|
||||
messages = {
|
||||
...(parsed._bootErrors ?? {}),
|
||||
reload: parsed.reload,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return Object.assign({
|
||||
title: 'Failed to initialize Misskey',
|
||||
solution: 'The following actions may solve the problem.',
|
||||
solution1: 'Update your os and browser',
|
||||
solution2: 'Disable an adblocker',
|
||||
solution3: 'Clear the browser cache',
|
||||
solution4: '(Tor Browser) Set dom.webaudio.enabled to true',
|
||||
otherOption: 'Other options',
|
||||
otherOption1: 'Clear preferences and cache',
|
||||
otherOption2: 'Start the simple client',
|
||||
otherOption3: 'Start the repair tool',
|
||||
otherOption4: 'Start Misskey in safe mode',
|
||||
reload: 'Reload',
|
||||
}, messages) as BootLoaderLocales;
|
||||
}
|
||||
|
||||
export function addStyle(styleText: string) {
|
||||
const styleElement = document.createElement('style');
|
||||
styleElement.appendChild(document.createTextNode(styleText));
|
||||
document.head.appendChild(styleElement);
|
||||
}
|
|
@ -3,8 +3,12 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
/* eslint no-restricted-globals: off */
|
||||
|
||||
'use strict';
|
||||
|
||||
import { addStyle, bootloaderLocales, detectLanguage } from '@@/js/bootloader';
|
||||
|
||||
interface Window {
|
||||
CLIENT_ENTRY: string | undefined;
|
||||
}
|
||||
|
@ -13,42 +17,22 @@ interface Window {
|
|||
(async () => {
|
||||
const CLIENT_ENTRY = window.CLIENT_ENTRY;
|
||||
|
||||
window.onerror = (e) => {
|
||||
console.error(e);
|
||||
renderError('SOMETHING_HAPPENED', e);
|
||||
window.onerror = (error) => {
|
||||
console.error(error);
|
||||
renderError('SOMETHING_HAPPENED', error);
|
||||
};
|
||||
window.onunhandledrejection = (e) => {
|
||||
console.error(e);
|
||||
renderError('SOMETHING_HAPPENED_IN_PROMISE', e);
|
||||
window.onunhandledrejection = (error) => {
|
||||
console.error(error);
|
||||
renderError('SOMETHING_HAPPENED_IN_PROMISE', error);
|
||||
};
|
||||
|
||||
let forceError = localStorage.getItem('forceError');
|
||||
const forceError = localStorage.getItem('forceError');
|
||||
if (forceError != null) {
|
||||
renderError('FORCED_ERROR', 'This error is forced by having forceError in local storage.');
|
||||
return;
|
||||
}
|
||||
|
||||
//#region Detect language
|
||||
const supportedLangs = _LANG_IDS_;
|
||||
/** @type { string } */
|
||||
let lang = localStorage.getItem('lang');
|
||||
if (lang == null || !supportedLangs.includes(lang)) {
|
||||
if (supportedLangs.includes(navigator.language)) {
|
||||
lang = navigator.language;
|
||||
} else {
|
||||
lang = supportedLangs.find(x => x.split('-')[0] === navigator.language);
|
||||
|
||||
// Fallback
|
||||
if (lang == null) lang = 'en-US';
|
||||
}
|
||||
}
|
||||
|
||||
// for https://github.com/misskey-dev/misskey/issues/10202
|
||||
if (lang == null || lang.toString == null || lang.toString() === 'null') {
|
||||
console.error('invalid lang value detected!!!', typeof lang, lang);
|
||||
lang = 'en-US';
|
||||
}
|
||||
//#endregion
|
||||
const lang = detectLanguage();
|
||||
|
||||
//#region Script
|
||||
async function importAppScript() {
|
||||
|
@ -84,7 +68,7 @@ interface Window {
|
|||
if (!isSafeMode) {
|
||||
const theme = localStorage.getItem('theme');
|
||||
if (theme) {
|
||||
for (const [k, v] of Object.entries(JSON.parse(theme))) {
|
||||
for (const [k, v] of Object.entries(JSON.parse(theme) as Record<string, string>)) {
|
||||
document.documentElement.style.setProperty(`--MI_THEME-${k}`, v.toString());
|
||||
|
||||
// HTMLの theme-color 適用
|
||||
|
@ -125,50 +109,13 @@ interface Window {
|
|||
}
|
||||
}
|
||||
|
||||
async function addStyle(styleText) {
|
||||
let css = document.createElement('style');
|
||||
css.appendChild(document.createTextNode(styleText));
|
||||
document.head.appendChild(css);
|
||||
}
|
||||
|
||||
async function renderError(code, details) {
|
||||
// Cannot set property 'innerHTML' of null を回避
|
||||
if (document.readyState === 'loading') {
|
||||
await new Promise(resolve => window.addEventListener('DOMContentLoaded', resolve));
|
||||
}
|
||||
|
||||
let messages = null;
|
||||
const bootloaderLocales = localStorage.getItem('bootloaderLocales');
|
||||
if (bootloaderLocales) {
|
||||
messages = JSON.parse(bootloaderLocales);
|
||||
}
|
||||
if (!messages) {
|
||||
// older version of misskey does not store bootloaderLocales, stores locale as a whole
|
||||
const legacyLocale = localStorage.getItem('locale');
|
||||
if (legacyLocale) {
|
||||
const parsed = JSON.parse(legacyLocale);
|
||||
messages = {
|
||||
...(parsed._bootErrors ?? {}),
|
||||
reload: parsed.reload,
|
||||
};
|
||||
}
|
||||
}
|
||||
if (!messages) messages = {};
|
||||
|
||||
messages = Object.assign({
|
||||
title: 'Failed to initialize Misskey',
|
||||
solution: 'The following actions may solve the problem.',
|
||||
solution1: 'Update your os and browser',
|
||||
solution2: 'Disable an adblocker',
|
||||
solution3: 'Clear the browser cache',
|
||||
solution4: '(Tor Browser) Set dom.webaudio.enabled to true',
|
||||
otherOption: 'Other options',
|
||||
otherOption1: 'Clear preferences and cache',
|
||||
otherOption2: 'Start the simple client',
|
||||
otherOption3: 'Start the repair tool',
|
||||
otherOption4: 'Start Misskey in safe mode',
|
||||
reload: 'Reload',
|
||||
}, messages);
|
||||
const messages = bootloaderLocales();
|
||||
|
||||
const safeModeUrl = new URL(window.location.href);
|
||||
safeModeUrl.searchParams.set('safemode', 'true');
|
||||
|
@ -220,7 +167,7 @@ interface Window {
|
|||
<br>
|
||||
<div id="errors"></div>
|
||||
`;
|
||||
errorsElement = document.getElementById('errors');
|
||||
errorsElement = document.getElementById('errors')!;
|
||||
}
|
||||
const detailsElement = document.createElement('details');
|
||||
detailsElement.id = 'errorInfo';
|
||||
|
|
Loading…
Reference in New Issue