/** * Client entry point */ // https://vitejs.dev/config/build-options.html#build-modulepreload import "vite/modulepreload-polyfill"; import "@/style.scss"; import "@phosphor-icons/web/bold"; import "@phosphor-icons/web/fill"; //#region account indexedDB migration import { set } from "@/scripts/idb-proxy"; import { App, computed, createApp, defineAsyncComponent, markRaw, version as vueVersion, watch, } from "vue"; import { compareVersions } from "compare-versions"; import widgets from "@/widgets"; import directives from "@/directives"; import { lang, ui, version } from "@/config"; import { applyTheme } from "@/scripts/theme"; import { isDeviceDarkmode } from "@/scripts/is-device-darkmode"; import { i18n } from "@/i18n"; import { alert, confirm, popup, post, toast } from "@/os"; import { stream } from "@/stream"; import * as sound from "@/scripts/sound"; import { $i, login, refreshAccount, signout, updateAccount } from "@/account"; import { ColdDeviceStorage, defaultStore } from "@/store"; import { fetchInstance, instance } from "@/instance"; import { makeHotkey } from "@/scripts/hotkey"; import { search } from "@/scripts/search"; import { deviceKind } from "@/scripts/device-kind"; import { initializeSw } from "@/scripts/initialize-sw"; import { reloadChannel } from "@/scripts/unison-reload"; import { reactionPicker } from "@/scripts/reaction-picker"; import { getUrlWithoutLoginId } from "@/scripts/login-id"; import { getAccountFromId } from "@/scripts/get-account-from-id"; import Mfm from "./components/global/MkMisskeyFlavoredMarkdown.vue"; import MkA from "./components/global/MkA.vue"; import MkAcct from "./components/global/MkAcct.vue"; import MagAvatar from "./components/global/MagAvatar.vue"; import MagAvatarResolvingProxy from "./components/global/MagAvatarResolvingProxy.vue"; import MagEmoji from "./components/global/MagEmoji.vue"; import MkUserName from "./components/global/MkUserName.vue"; import MkEllipsis from "./components/global/MkEllipsis.vue"; import MkTime from "./components/global/MkTime.vue"; import MkUrl from "./components/global/MkUrl.vue"; import I18n from "./components/global/i18n"; import RouterView from "./components/global/RouterView.vue"; import MkLoading from "./components/global/MkLoading.vue"; import MkError from "./components/global/MkError.vue"; import MkPageHeader from "./components/global/MkPageHeader.vue"; import MkSpacer from "./components/global/MkSpacer.vue"; import MkStickyContainer from "./components/global/MkStickyContainer.vue"; import MagSpinner from "@/components/global/MagSpinner.vue"; function globalComponents(app: App) { app.component("I18n", I18n); app.component("RouterView", RouterView); app.component("Mfm", Mfm); app.component("MkA", MkA); app.component("MagSpinner", MagSpinner); app.component("MkAcct", MkAcct); app.component("MagAvatar", MagAvatar); app.component("MagEmoji", MagEmoji); app.component("MkUserName", MkUserName); app.component("MkEllipsis", MkEllipsis); app.component("MkTime", MkTime); app.component("MkUrl", MkUrl); app.component("MkLoading", MkLoading); app.component("MkError", MkError); app.component("MkPageHeader", MkPageHeader); app.component("MkSpacer", MkSpacer); app.component("MkStickyContainer", MkStickyContainer); app.component("MagAvatarResolvingProxy", MagAvatarResolvingProxy); } declare module "@vue/runtime-core" { export interface GlobalComponents { I18n: typeof I18n; RouterView: typeof RouterView; Mfm: typeof Mfm; MkA: typeof MkA; MagSpinner: typeof MagSpinner; MkAcct: typeof MkAcct; MagAvatar: typeof MagAvatar; MagEmoji: typeof MagEmoji; MkUserName: typeof MkUserName; MkEllipsis: typeof MkEllipsis; MkTime: typeof MkTime; MkUrl: typeof MkUrl; MkLoading: typeof MkLoading; MkError: typeof MkError; MkPageHeader: typeof MkPageHeader; MkSpacer: typeof MkSpacer; MkStickyContainer: typeof MkStickyContainer; MagAvatarResolvingProxy: typeof MagAvatarResolvingProxy; } } const accounts = localStorage.getItem("accounts"); if (accounts) { set("accounts", JSON.parse(accounts)); localStorage.removeItem("accounts"); } //#endregion function checkForSplash() { const splash = document.getElementById("splash"); // 念のためnullチェック(HTMLが古い場合があるため(そのうち消す)) if (splash) { splash.style.opacity = "0"; splash.style.pointerEvents = "none"; splash.addEventListener("transitionend", () => { splash.remove(); }); } } (async () => { console.info(`Magnetar v${version}`); if (_DEV_) { console.warn("Development mode!!!"); console.info(`vue ${vueVersion}`); (window as any).$i = $i; (window as any).$store = defaultStore; window.addEventListener("error", (event) => { console.error(event); /* alert({ type: 'error', title: 'DEV: Unhandled error', text: event.message }); */ }); window.addEventListener("unhandledrejection", (event) => { console.error(event); /* alert({ type: 'error', title: 'DEV: Unhandled promise rejection', text: event.reason }); */ }); } // タッチデバイスでCSSの:hoverを機能させる document.addEventListener("touchend", () => {}, { passive: true }); // 一斉リロード reloadChannel.addEventListener("message", (path) => { if (path !== null) location.href = path; else location.reload(); }); //#region SEE: https://css-tricks.com/the-trick-to-viewport-units-on-mobile/ // TODO: いつの日にか消したい const vh = window.innerHeight * 0.01; document.documentElement.style.setProperty("--vh", `${vh}px`); window.addEventListener("resize", () => { const vh = window.innerHeight * 0.01; document.documentElement.style.setProperty("--vh", `${vh}px`); }); //#endregion //#region Set lang attr const html = document.documentElement; html.setAttribute("lang", lang || "en-US"); //#endregion //#region loginId const params = new URLSearchParams(location.search); const loginId = params.get("loginId"); if (loginId) { const target = getUrlWithoutLoginId(location.href); if (!$i || $i.id !== loginId) { const account = await getAccountFromId(loginId); if (account) { await login(account.token, target); } } history.replaceState({ misskey: "loginId" }, "", target); } //#endregion //#region Fetch user if ($i?.token) { if (_DEV_) { console.log("account cache found. refreshing..."); } refreshAccount(); } else { if (_DEV_) { console.log("no account cache found."); } // 連携ログインの場合用にCookieを参照する const i = (document.cookie.match(/igi=(\w+)/) || [null, null])[1]; if (i != null && i !== "null") { if (_DEV_) { console.log("signing..."); } try { document.body.innerHTML = "