diff --git a/src/client/account.ts b/src/client/account.ts index c539673c0d..48fe76146c 100644 --- a/src/client/account.ts +++ b/src/client/account.ts @@ -1,4 +1,4 @@ -import { get, set } from 'idb-keyval'; +import { get, set } from '@/scripts/idb-proxy'; import { reactive } from 'vue'; import { apiUrl } from '@/config'; import { waiting } from '@/os'; diff --git a/src/client/components/sidebar.vue b/src/client/components/sidebar.vue index 8eace36f19..476c7f8734 100644 --- a/src/client/components/sidebar.vue +++ b/src/client/components/sidebar.vue @@ -242,7 +242,7 @@ export default defineComponent({ addAcount() { os.popup(import('./signin-dialog.vue'), {}, { done: async res => { - addAccount(res.id, res.i); + await addAccount(res.id, res.i); os.success(); }, }, 'closed'); diff --git a/src/client/init.ts b/src/client/init.ts index 7385c59de2..21bdbee5a8 100644 --- a/src/client/init.ts +++ b/src/client/init.ts @@ -4,7 +4,7 @@ import '@/style.scss'; -import { set } from 'idb-keyval'; +import { set } from '@/scripts/idb-proxy'; // TODO: そのうち消す if (localStorage.getItem('vuex') != null) { @@ -69,9 +69,9 @@ import { isMobile } from '@/scripts/is-mobile'; import { getThemes } from '@/theme-store'; import { initializeSw } from '@/scripts/initialize-sw'; import { reload, reloadChannel } from '@/scripts/unison-reload'; +import { reactionPicker } from '@/scripts/reaction-picker'; import { deleteLoginId } from '@/scripts/login-id'; import { getAccountFromId } from '@/scripts/get-account-from-id'; -import { reactionPicker } from '@/scripts/reaction-picker'; console.info(`Misskey v${version}`); diff --git a/src/client/scripts/get-account-from-id.ts b/src/client/scripts/get-account-from-id.ts index be4cfaeba4..ba3adceecc 100644 --- a/src/client/scripts/get-account-from-id.ts +++ b/src/client/scripts/get-account-from-id.ts @@ -1,4 +1,4 @@ -import { get } from 'idb-keyval'; +import { get } from '@/scripts/idb-proxy'; export async function getAccountFromId(id: string) { const accounts = await get('accounts') as { token: string; id: string; }[]; diff --git a/src/client/scripts/idb-proxy.ts b/src/client/scripts/idb-proxy.ts new file mode 100644 index 0000000000..c0d01e6292 --- /dev/null +++ b/src/client/scripts/idb-proxy.ts @@ -0,0 +1,34 @@ +// FirefoxのプライベートモードなどではindexedDBが使用不可能なので、使う +import { + get as iget, + set as iset, + del as idel, +} from 'idb-keyval'; + +const fallbackName = (key: string) => `idbfallback::${key}`; + +let idbAvailable = typeof window !== 'undefined' ? !!window.indexedDB : true; + +if (idbAvailable) { + try { + const request = indexedDB.open('keyval-store'); + if (request.error) idbAvailable = false; + } catch (e) { + idbAvailable = false; + } +} + +export async function get(key: string) { + if (idbAvailable) return iget(key); + return JSON.parse(localStorage.getItem(fallbackName(key))); +} + +export async function set(key: string, val: any) { + if (idbAvailable) return iset(key, val); + return localStorage.setItem(fallbackName(key), JSON.stringify(val)); +} + +export async function del(key: string) { + if (idbAvailable) return idel(key); + return localStorage.removeItem(fallbackName(key)); +} diff --git a/src/client/sw/sw.ts b/src/client/sw/sw.ts index 5b17855e08..6f78f3cb38 100644 --- a/src/client/sw/sw.ts +++ b/src/client/sw/sw.ts @@ -32,7 +32,10 @@ self.addEventListener('activate', ev => { //#region When: Fetching self.addEventListener('fetch', ev => { - // Nothing to do + ev.respondWith( + fetch(ev.request) + .catch(() => new Response(`Offline. Service Worker @${_VERSION_}`, { status: 200 })) + ); }); //#endregion diff --git a/src/client/ui/_common_/common.vue b/src/client/ui/_common_/common.vue index 8709f5a686..26e3a5b35e 100644 --- a/src/client/ui/_common_/common.vue +++ b/src/client/ui/_common_/common.vue @@ -55,44 +55,46 @@ export default defineComponent({ const sideViewHook = inject('sideViewHook', null); //#region Listen message from SW - navigator.serviceWorker.addEventListener('message', ev => { - if (_DEV_) { - console.log('sw msg', ev.data); - } + if ('serviceWorker' in navigator) { + navigator.serviceWorker.addEventListener('message', ev => { + if (_DEV_) { + console.log('sw msg', ev.data); + } - const data = ev.data as SwMessage; - if (data.type !== 'order') return; + const data = ev.data as SwMessage; + if (data.type !== 'order') return; - if (data.loginId !== $i?.id) { - return getAccountFromId(data.loginId).then(account => { - if (!account) return; - return login(account.token, data.url); - }); - } + if (data.loginId !== $i?.id) { + return getAccountFromId(data.loginId).then(account => { + if (!account) return; + return login(account.token, data.url); + }); + } - switch (data.order) { - case 'post': - return post(data.options); - case 'push': - if (data.url.startsWith('/my/messaging')) { - if (router.currentRoute.value.path === data.url) return; - if (ColdDeviceStorage.get('chatOpenBehavior') === 'window') return pageWindow(data.url); - if (ColdDeviceStorage.get('chatOpenBehavior') === 'popout') return popout(data.url); - } - if (router.currentRoute.value.path === data.url) { - return window.scroll({ top: 0, behavior: 'smooth' }); - } - if (navHook) { - return navHook(data.url); - } - if (sideViewHook && defaultStore.state.defaultSideView && data.url !== '/') { - return sideViewHook(data.url); - } - return router.push(data.url); - default: - return; - } - }); + switch (data.order) { + case 'post': + return post(data.options); + case 'push': + if (data.url.startsWith('/my/messaging')) { + if (router.currentRoute.value.path === data.url) return; + if (ColdDeviceStorage.get('chatOpenBehavior') === 'window') return pageWindow(data.url); + if (ColdDeviceStorage.get('chatOpenBehavior') === 'popout') return popout(data.url); + } + if (router.currentRoute.value.path === data.url) { + return window.scroll({ top: 0, behavior: 'smooth' }); + } + if (navHook) { + return navHook(data.url); + } + if (sideViewHook && defaultStore.state.defaultSideView && data.url !== '/') { + return sideViewHook(data.url); + } + return router.push(data.url); + default: + return; + } + }); + } } return {