mizzkey/packages/frontend-embed/src/boot.ts

113 lines
3 KiB
TypeScript
Raw Normal View History

/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
// https://vitejs.dev/config/build-options.html#build-modulepreload
import 'vite/modulepreload-polyfill';
2024-08-27 13:21:40 +02:00
import '@tabler/icons-webfont/dist/tabler-icons.scss';
import '@/style.scss';
import { createApp, defineAsyncComponent } from 'vue';
2024-08-27 04:00:15 +02:00
import lightTheme from '@@/themes/l-light.json5';
import darkTheme from '@@/themes/d-dark.json5';
2024-09-02 09:13:57 +02:00
import { MediaProxy } from '@@/js/media-proxy.js';
2024-08-27 04:00:15 +02:00
import { applyTheme } from './theme.js';
2024-08-27 12:59:53 +02:00
import { fetchCustomEmojis } from './custom-emojis.js';
2024-09-02 09:13:57 +02:00
import { DI } from './di.js';
import { serverMetadata } from './server-metadata.js';
import { url } from './config.js';
2024-08-23 01:07:23 +02:00
import { parseEmbedParams } from '@/embed-page.js';
2024-09-02 09:13:57 +02:00
import { setIframeId } from '@/post-message.js';
2024-08-27 01:16:02 +02:00
console.info('Misskey Embed');
const params = new URLSearchParams(location.search);
const embedParams = parseEmbedParams(params);
2024-08-27 01:24:34 +02:00
console.info(embedParams);
2024-08-27 13:58:35 +02:00
if (embedParams.colorMode === 'dark') {
applyTheme(darkTheme);
} else if (embedParams.colorMode === 'light') {
applyTheme(lightTheme);
} else {
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
applyTheme(darkTheme);
} else {
applyTheme(lightTheme);
}
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (mql) => {
if (mql.matches) {
applyTheme(darkTheme);
} else {
applyTheme(lightTheme);
}
});
}
2024-08-27 04:00:15 +02:00
// サイズの制限
document.documentElement.style.maxWidth = '500px';
// iframeIdの設定
function setIframeIdHandler(event: MessageEvent) {
if (event.data?.type === 'misskey:embedParent:registerIframeId' && event.data.payload?.iframeId != null) {
setIframeId(event.data.payload.iframeId);
window.removeEventListener('message', setIframeIdHandler);
}
}
2024-07-06 04:20:04 +02:00
window.addEventListener('message', setIframeIdHandler);
2024-08-27 12:59:53 +02:00
try {
await fetchCustomEmojis();
} catch (err) { /* empty */ }
2024-08-22 10:32:24 +02:00
const app = createApp(
2024-08-22 10:19:36 +02:00
defineAsyncComponent(() => import('@/ui.vue')),
2024-08-22 10:32:24 +02:00
);
2024-09-02 09:13:57 +02:00
app.provide(DI.mediaProxy, new MediaProxy(serverMetadata, url));
2024-08-22 10:32:24 +02:00
app.provide('embedParams', embedParams);
2024-07-06 06:03:21 +02:00
2024-08-27 01:20:46 +02:00
// https://github.com/misskey-dev/misskey/pull/8575#issuecomment-1114239210
// なぜか2回実行されることがあるため、mountするdivを1つに制限する
const rootEl = ((): HTMLElement => {
const MISSKEY_MOUNT_DIV_ID = 'misskey_app';
const currentRoot = document.getElementById(MISSKEY_MOUNT_DIV_ID);
if (currentRoot) {
console.warn('multiple import detected');
return currentRoot;
}
const root = document.createElement('div');
root.id = MISSKEY_MOUNT_DIV_ID;
document.body.appendChild(root);
return root;
})();
app.mount(rootEl);
// boot.jsのやつを解除
window.onerror = null;
window.onunhandledrejection = null;
2024-08-26 10:18:49 +02:00
removeSplash();
function removeSplash() {
const splash = document.getElementById('splash');
if (splash) {
splash.style.opacity = '0';
splash.style.pointerEvents = 'none';
// transitionendイベントが発火しない場合があるため
window.setTimeout(() => {
splash.remove();
}, 1000);
}
}