diff --git a/packages/backend/src/server/web/boot.js b/packages/backend/src/server/web/boot.js index 5e59a51ed9..1a71244119 100644 --- a/packages/backend/src/server/web/boot.js +++ b/packages/backend/src/server/web/boot.js @@ -32,6 +32,8 @@ renderError('FORCED_ERROR', 'This error is forced by having forceError in local storage.') } + const isEmbedPage = document.documentElement.classList.contains('embed'); + //#region Detect language & fetch translations if (!localStorage.hasOwnProperty('locale')) { const supportedLangs = LANGS; @@ -104,49 +106,51 @@ } //#endregion - //#region Theme - const theme = localStorage.getItem('theme'); - if (theme) { - for (const [k, v] of Object.entries(JSON.parse(theme))) { - document.documentElement.style.setProperty(`--${k}`, v.toString()); + if (!isEmbedPage) { + //#region Theme + const theme = localStorage.getItem('theme'); + if (theme) { + for (const [k, v] of Object.entries(JSON.parse(theme))) { + document.documentElement.style.setProperty(`--${k}`, v.toString()); - // HTMLの theme-color 適用 - if (k === 'htmlThemeColor') { - for (const tag of document.head.children) { - if (tag.tagName === 'META' && tag.getAttribute('name') === 'theme-color') { - tag.setAttribute('content', v); - break; + // HTMLの theme-color 適用 + if (k === 'htmlThemeColor') { + for (const tag of document.head.children) { + if (tag.tagName === 'META' && tag.getAttribute('name') === 'theme-color') { + tag.setAttribute('content', v); + break; + } } } } } - } - const colorScheme = localStorage.getItem('colorScheme'); - if (colorScheme) { - document.documentElement.style.setProperty('color-scheme', colorScheme); - } - //#endregion + const colorScheme = localStorage.getItem('colorScheme'); + if (colorScheme) { + document.documentElement.style.setProperty('color-scheme', colorScheme); + } + //#endregion - const fontSize = localStorage.getItem('fontSize'); - if (fontSize) { - document.documentElement.classList.add('f-' + fontSize); - } + const fontSize = localStorage.getItem('fontSize'); + if (fontSize) { + document.documentElement.classList.add('f-' + fontSize); + } - const useSystemFont = localStorage.getItem('useSystemFont'); - if (useSystemFont) { - document.documentElement.classList.add('useSystemFont'); - } + const useSystemFont = localStorage.getItem('useSystemFont'); + if (useSystemFont) { + document.documentElement.classList.add('useSystemFont'); + } - const wallpaper = localStorage.getItem('wallpaper'); - if (wallpaper) { - document.documentElement.style.backgroundImage = `url(${wallpaper})`; - } + const wallpaper = localStorage.getItem('wallpaper'); + if (wallpaper) { + document.documentElement.style.backgroundImage = `url(${wallpaper})`; + } - const customCss = localStorage.getItem('customCss'); - if (customCss && customCss.length > 0) { - const style = document.createElement('style'); - style.innerHTML = customCss; - document.head.appendChild(style); + const customCss = localStorage.getItem('customCss'); + if (customCss && customCss.length > 0) { + const style = document.createElement('style'); + style.innerHTML = customCss; + document.head.appendChild(style); + } } async function addStyle(styleText) { diff --git a/packages/frontend/src/_embed_boot_.ts b/packages/frontend/src/_embed_boot_.ts index e83d7efb2e..bbd42905e3 100644 --- a/packages/frontend/src/_embed_boot_.ts +++ b/packages/frontend/src/_embed_boot_.ts @@ -11,6 +11,7 @@ import '@/style.embed.scss'; import type { CommonBootOptions } from '@/boot/common.js'; import { subBoot } from '@/boot/sub-boot.js'; import { setIframeId, postMessageToParentWindow } from '@/scripts/post-message.js'; +import { defaultStore } from '@/store.js'; const bootOptions: Partial = {}; @@ -21,6 +22,11 @@ if (color && ['light', 'dark'].includes(color)) { bootOptions.forceColorMode = color as 'light' | 'dark'; } +// 外部タブでのstoreの変更の影響を受けないように +defaultStore.setConfig({ + disableMessageChannel: true, +}); + // iframeIdの設定 window.addEventListener('message', event => { if (event.data?.type === 'misskey:embedParent:registerIframeId' && event.data.payload?.iframeId != null) { diff --git a/packages/frontend/src/pizzax.ts b/packages/frontend/src/pizzax.ts index ac325e923f..f7d23b202a 100644 --- a/packages/frontend/src/pizzax.ts +++ b/packages/frontend/src/pizzax.ts @@ -32,6 +32,10 @@ type PizzaxChannelMessage = { userId?: string; }; +export type PizzaxConfig = { + disableMessageChannel: boolean; +}; + export class Storage { public readonly ready: Promise; public readonly loaded: Promise; @@ -47,6 +51,10 @@ export class Storage { public readonly state: State; public readonly reactiveState: ReactiveState; + private options: PizzaxConfig = { + disableMessageChannel: false, + }; + private pizzaxChannel: BroadcastChannel>; // 簡易的にキューイングして占有ロックとする @@ -60,12 +68,13 @@ export class Storage { return promise; } - constructor(key: string, def: T) { + constructor(key: string, def: T, options?: Partial) { this.key = key; this.deviceStateKeyName = `pizzax::${key}`; this.deviceAccountStateKeyName = $i ? `pizzax::${key}::${$i.id}` : ''; this.registryCacheKeyName = $i ? `pizzax::${key}::cache::${$i.id}` : ''; this.def = def; + this.options = Object.assign(this.options, options); this.pizzaxChannel = new BroadcastChannel(`pizzax::${key}`); @@ -119,7 +128,7 @@ export class Storage { this.pizzaxChannel.addEventListener('message', ({ where, key, value, userId }) => { // アカウント変更すればunisonReloadが効くため、このreturnが発火することは // まずないと思うけど一応弾いておく - if (where === 'deviceAccount' && !($i && userId !== $i.id)) return; + if ((where === 'deviceAccount' && !($i && userId !== $i.id) || this.options.disableMessageChannel)) return; this.reactiveState[key].value = this.state[key] = value; }); @@ -174,6 +183,10 @@ export class Storage { }); } + public setConfig(config: Partial) { + this.options = Object.assign(this.options, config); + } + public set(key: K, value: T[K]['default']): Promise { // IndexedDBやBroadcastChannelで扱うために単純なオブジェクトにする // (JSON.parse(JSON.stringify(value))の代わり) @@ -187,11 +200,13 @@ export class Storage { if (_DEV_) console.log(`set ${String(key)} start`); switch (this.def[key].where) { case 'device': { - this.pizzaxChannel.postMessage({ - where: 'device', - key, - value: rawValue, - }); + if (!this.options.disableMessageChannel) { + this.pizzaxChannel.postMessage({ + where: 'device', + key, + value: rawValue, + }); + } const deviceState = await get(this.deviceStateKeyName) || {}; deviceState[key] = rawValue; await set(this.deviceStateKeyName, deviceState); @@ -199,12 +214,14 @@ export class Storage { } case 'deviceAccount': { if ($i == null) break; - this.pizzaxChannel.postMessage({ - where: 'deviceAccount', - key, - value: rawValue, - userId: $i.id, - }); + if (!this.options.disableMessageChannel) { + this.pizzaxChannel.postMessage({ + where: 'deviceAccount', + key, + value: rawValue, + userId: $i.id, + }); + } const deviceAccountState = await get(this.deviceAccountStateKeyName) || {}; deviceAccountState[key] = rawValue; await set(this.deviceAccountStateKeyName, deviceAccountState);