Merge 427ad0b809
into d4654dd7bd
This commit is contained in:
commit
b815b16ec4
|
@ -185,8 +185,10 @@ export type Config = {
|
|||
driveUrl: string;
|
||||
userAgent: string;
|
||||
frontendEntry: { file: string | null };
|
||||
frontendBootLoader: { file: string };
|
||||
frontendManifestExists: boolean;
|
||||
frontendEmbedEntry: { file: string | null };
|
||||
frontendEmbedBootLoader: { file: string };
|
||||
frontendEmbedManifestExists: boolean;
|
||||
mediaProxy: string;
|
||||
externalMediaProxyEnabled: boolean;
|
||||
|
@ -235,10 +237,10 @@ export function loadConfig(): Config {
|
|||
const frontendEmbedManifestExists = fs.existsSync(_dirname + '/../../../built/_frontend_embed_vite_/manifest.json');
|
||||
const frontendManifest = frontendManifestExists ?
|
||||
JSON.parse(fs.readFileSync(`${_dirname}/../../../built/_frontend_vite_/manifest.json`, 'utf-8'))
|
||||
: { 'src/_boot_.ts': { file: null } };
|
||||
: { 'src/_boot_.ts': { file: null }, 'src/_bootloader.ts': { file: 'src/_bootloader.ts' } };
|
||||
const frontendEmbedManifest = frontendEmbedManifestExists ?
|
||||
JSON.parse(fs.readFileSync(`${_dirname}/../../../built/_frontend_embed_vite_/manifest.json`, 'utf-8'))
|
||||
: { 'src/boot.ts': { file: null } };
|
||||
: { 'src/boot.ts': { file: null }, 'src/_bootloader.ts': { file: 'src/_bootloader.ts' } };
|
||||
|
||||
const config = yaml.load(fs.readFileSync(path, 'utf-8')) as Source;
|
||||
|
||||
|
@ -312,8 +314,10 @@ export function loadConfig(): Config {
|
|||
: null,
|
||||
userAgent: `Misskey/${version} (${config.url})`,
|
||||
frontendEntry: frontendManifest['src/_boot_.ts'],
|
||||
frontendBootLoader: frontendManifest['src/_bootloader.ts'],
|
||||
frontendManifestExists: frontendManifestExists,
|
||||
frontendEmbedEntry: frontendEmbedManifest['src/boot.ts'],
|
||||
frontendEmbedBootLoader: frontendEmbedManifest['src/_bootloader.ts'],
|
||||
frontendEmbedManifestExists: frontendEmbedManifestExists,
|
||||
perChannelMaxNoteCacheCount: config.perChannelMaxNoteCacheCount ?? 1000,
|
||||
perUserNotificationsMaxCount: config.perUserNotificationsMaxCount ?? 500,
|
||||
|
|
|
@ -2,6 +2,7 @@ block vars
|
|||
|
||||
block loadClientEntry
|
||||
- const entry = config.frontendEmbedEntry;
|
||||
- const bootLoader = config.frontendEmbedBootLoader;
|
||||
|
||||
doctype html
|
||||
|
||||
|
@ -47,8 +48,7 @@ html(class='embed')
|
|||
script(type='application/json' id='misskey_embedCtx' data-generated-at=now)
|
||||
!= embedCtx
|
||||
|
||||
script
|
||||
include ../boot.embed.js
|
||||
script(type='module', src=`/embed_vite/${bootLoader.file}`)
|
||||
|
||||
body
|
||||
noscript: p
|
||||
|
|
|
@ -2,6 +2,7 @@ block vars
|
|||
|
||||
block loadClientEntry
|
||||
- const entry = config.frontendEntry;
|
||||
- const bootLoader = config.frontendBootLoader;
|
||||
- const baseUrl = config.url;
|
||||
|
||||
doctype html
|
||||
|
@ -76,8 +77,7 @@ html
|
|||
script(type='application/json' id='misskey_clientCtx' data-generated-at=now)
|
||||
!= clientCtx
|
||||
|
||||
script
|
||||
include ../boot.js
|
||||
script(type='module', src=`/vite/${bootLoader.file}`)
|
||||
|
||||
body
|
||||
noscript: p
|
||||
|
|
|
@ -6,6 +6,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;
|
||||
|
|
|
@ -5,18 +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;
|
||||
|
@ -31,33 +37,13 @@
|
|||
document.documentElement.classList.add('noborder');
|
||||
}
|
||||
|
||||
//#region Detect language & fetch translations
|
||||
const supportedLangs = LANGS;
|
||||
/** @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(CLIENT_ENTRY ? `/embed_vite/${CLIENT_ENTRY.replace('scripts', lang)}` : '/embed_vite/src/_boot_.ts')
|
||||
.catch(async e => {
|
||||
console.error(e);
|
||||
await import(`/embed_vite/${(window.CLIENT_ENTRY ?? 'src/boot.ts').replace('scripts', lang)}`)
|
||||
.catch(async error => {
|
||||
console.error(error);
|
||||
renderError('APP_IMPORT');
|
||||
});
|
||||
}
|
||||
|
@ -72,44 +58,19 @@
|
|||
}
|
||||
//#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,
|
|
@ -121,6 +121,7 @@ export function getConfig(): UserConfig {
|
|||
define: {
|
||||
_VERSION_: JSON.stringify(meta.version),
|
||||
_LANGS_: JSON.stringify(Object.entries(locales).map(([k, v]) => [k, v._lang_])),
|
||||
_LANG_IDS_: JSON.stringify(Object.keys(locales)),
|
||||
_ENV_: JSON.stringify(process.env.NODE_ENV),
|
||||
_DEV_: process.env.NODE_ENV !== 'production',
|
||||
_PERF_PREFIX_: JSON.stringify('Misskey:'),
|
||||
|
@ -139,6 +140,7 @@ export function getConfig(): UserConfig {
|
|||
input: {
|
||||
i18n: './src/i18n.ts',
|
||||
entry: './src/boot.ts',
|
||||
bootloader: './src/_bootloader.ts',
|
||||
},
|
||||
external: externalPackages.map(p => p.match),
|
||||
preserveEntrySignatures: 'allow-extension',
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -6,6 +6,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;
|
||||
|
|
|
@ -3,50 +3,40 @@
|
|||
* 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;
|
||||
}
|
||||
|
||||
// ブロックの中に入れないと、定義した変数がブラウザのグローバルスコープに登録されてしまい邪魔なので
|
||||
(async () => {
|
||||
window.onerror = (e) => {
|
||||
console.error(e);
|
||||
renderError('SOMETHING_HAPPENED', e);
|
||||
const CLIENT_ENTRY = window.CLIENT_ENTRY;
|
||||
|
||||
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 = LANGS;
|
||||
/** @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(CLIENT_ENTRY ? `/vite/${CLIENT_ENTRY.replace('scripts', lang)}` : '/vite/src/_boot_.ts')
|
||||
await import(`/vite/${(CLIENT_ENTRY ?? 'src/_boot_.ts').replace('scripts', lang)}`)
|
||||
.catch(async e => {
|
||||
console.error(e);
|
||||
renderError('APP_IMPORT', e);
|
||||
|
@ -78,7 +68,7 @@
|
|||
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 適用
|
||||
|
@ -119,50 +109,13 @@
|
|||
}
|
||||
}
|
||||
|
||||
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');
|
||||
|
@ -214,7 +167,7 @@
|
|||
<br>
|
||||
<div id="errors"></div>
|
||||
`;
|
||||
errorsElement = document.getElementById('errors');
|
||||
errorsElement = document.getElementById('errors')!;
|
||||
}
|
||||
const detailsElement = document.createElement('details');
|
||||
detailsElement.id = 'errorInfo';
|
|
@ -25,3 +25,8 @@ declare module 'search-index:settings' {
|
|||
declare module 'search-index:admin' {
|
||||
export const searchIndexes: XGeneratedSearchIndexItem[];
|
||||
}
|
||||
|
||||
declare module 'virtual:supported-langs' {
|
||||
const value: string[];
|
||||
export default value;
|
||||
}
|
||||
|
|
|
@ -160,6 +160,7 @@ export function getConfig(): UserConfig {
|
|||
define: {
|
||||
_VERSION_: JSON.stringify(meta.version),
|
||||
_LANGS_: JSON.stringify(Object.entries(locales).map(([k, v]) => [k, v._lang_])),
|
||||
_LANG_IDS_: JSON.stringify(Object.keys(locales)),
|
||||
_ENV_: JSON.stringify(process.env.NODE_ENV),
|
||||
_DEV_: process.env.NODE_ENV !== 'production',
|
||||
_PERF_PREFIX_: JSON.stringify('Misskey:'),
|
||||
|
@ -178,6 +179,7 @@ export function getConfig(): UserConfig {
|
|||
input: {
|
||||
i18n: './src/i18n.ts',
|
||||
entry: './src/_boot_.ts',
|
||||
bootloader: './src/_bootloader.ts',
|
||||
},
|
||||
external: externalPackages.map(p => p.match),
|
||||
preserveEntrySignatures: 'allow-extension',
|
||||
|
|
|
@ -53,8 +53,8 @@ async function buildBackendScript() {
|
|||
await fs.mkdir('./packages/backend/built/server/web', { recursive: true });
|
||||
|
||||
for (const file of [
|
||||
'./packages/backend/src/server/web/boot.js',
|
||||
'./packages/backend/src/server/web/boot.embed.js',
|
||||
//'./packages/backend/src/server/web/boot.js',
|
||||
//'./packages/backend/src/server/web/boot.embed.js',
|
||||
'./packages/backend/src/server/web/bios.js',
|
||||
'./packages/backend/src/server/web/cli.js',
|
||||
'./packages/backend/src/server/web/error.js',
|
||||
|
|
Loading…
Reference in New Issue