|
|
|
|
@ -1,5 +1,7 @@
|
|
|
|
|
<template>
|
|
|
|
|
<div class="flex flex-col items-center justify-center w-full h-screen bg-primary">
|
|
|
|
|
<div
|
|
|
|
|
class="flex flex-col items-center justify-center w-full h-screen bg-primary"
|
|
|
|
|
>
|
|
|
|
|
<div class="flex flex-col items-center space-y-6 max-w-md text-center">
|
|
|
|
|
<div class="flex items-center space-x-4">
|
|
|
|
|
<img src="/logo.svg" alt="Hoppscotch" class="h-7 w-7" />
|
|
|
|
|
@ -9,39 +11,70 @@
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-if="appState === AppState.LOADING" class="flex flex-col items-center space-y-4">
|
|
|
|
|
<div
|
|
|
|
|
v-if="appState === AppState.LOADING"
|
|
|
|
|
class="flex flex-col items-center space-y-4"
|
|
|
|
|
>
|
|
|
|
|
<HoppSmartSpinner />
|
|
|
|
|
<p class="text-secondaryDark">{{ statusMessage }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div
|
|
|
|
|
v-else-if="appState === AppState.UPDATE_AVAILABLE || appState === AppState.UPDATE_IN_PROGRESS || appState === AppState.UPDATE_READY"
|
|
|
|
|
v-else-if="
|
|
|
|
|
appState === AppState.UPDATE_AVAILABLE ||
|
|
|
|
|
appState === AppState.UPDATE_IN_PROGRESS ||
|
|
|
|
|
appState === AppState.UPDATE_READY
|
|
|
|
|
"
|
|
|
|
|
class="flex flex-col items-center space-y-4"
|
|
|
|
|
>
|
|
|
|
|
<IconLucideDownload class="h-16 w-16 text-accent" />
|
|
|
|
|
<div class="text-center">
|
|
|
|
|
<h2 class="text-xl font-semibold text-secondaryDark">Update Available</h2>
|
|
|
|
|
<p class="text-secondary mt-1">{{ updateMessage || 'A new version of Hoppscotch is available, downloading...' }}</p>
|
|
|
|
|
<h2 class="text-xl font-semibold text-secondaryDark">
|
|
|
|
|
Update Available
|
|
|
|
|
</h2>
|
|
|
|
|
<p class="text-secondary mt-1">
|
|
|
|
|
{{
|
|
|
|
|
updateMessage ||
|
|
|
|
|
"A new version of Hoppscotch is available, downloading..."
|
|
|
|
|
}}
|
|
|
|
|
</p>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-if="downloadProgress.total && downloadProgress.downloaded" class="w-full">
|
|
|
|
|
<div
|
|
|
|
|
v-if="downloadProgress.total && downloadProgress.downloaded"
|
|
|
|
|
class="w-full"
|
|
|
|
|
>
|
|
|
|
|
<div class="w-full bg-primaryLight rounded-full h-2.5">
|
|
|
|
|
<div
|
|
|
|
|
class="bg-accent h-2.5 rounded-full"
|
|
|
|
|
:style="{ width: `${(downloadProgress.downloaded / downloadProgress.total) * 100}%` }"
|
|
|
|
|
:style="{
|
|
|
|
|
width: `${
|
|
|
|
|
(downloadProgress.downloaded / downloadProgress.total) * 100
|
|
|
|
|
}%`,
|
|
|
|
|
}"
|
|
|
|
|
></div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="flex justify-between text-sm text-secondaryLight mt-1">
|
|
|
|
|
<span>{{ Math.round((downloadProgress.downloaded / downloadProgress.total) * 100) }}%</span>
|
|
|
|
|
<span
|
|
|
|
|
>{{
|
|
|
|
|
Math.round(
|
|
|
|
|
(downloadProgress.downloaded / downloadProgress.total) * 100
|
|
|
|
|
)
|
|
|
|
|
}}%</span
|
|
|
|
|
>
|
|
|
|
|
<span class="text-xs">
|
|
|
|
|
{{ formatBytes(downloadProgress.downloaded) }} / {{ formatBytes(downloadProgress.total) }}
|
|
|
|
|
{{ formatBytes(downloadProgress.downloaded) }} /
|
|
|
|
|
{{ formatBytes(downloadProgress.total) }}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-else-if="downloadProgress.downloaded > 0" class="w-full">
|
|
|
|
|
<div class="w-full bg-primaryLight rounded-full h-2.5">
|
|
|
|
|
<div class="bg-accent h-2.5 rounded-full animate-pulse" style="width: 100%"></div>
|
|
|
|
|
<div
|
|
|
|
|
class="bg-accent h-2.5 rounded-full animate-pulse"
|
|
|
|
|
style="width: 100%"
|
|
|
|
|
></div>
|
|
|
|
|
</div>
|
|
|
|
|
<p class="text-sm text-secondaryLight text-center mt-1">
|
|
|
|
|
Downloaded {{ formatBytes(downloadProgress.downloaded) }}
|
|
|
|
|
@ -70,10 +103,15 @@
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div v-else-if="appState === AppState.ERROR" class="flex flex-col items-center space-y-4">
|
|
|
|
|
<div
|
|
|
|
|
v-else-if="appState === AppState.ERROR"
|
|
|
|
|
class="flex flex-col items-center space-y-4"
|
|
|
|
|
>
|
|
|
|
|
<IconLucideAlertCircle class="h-16 w-16 text-red-500" />
|
|
|
|
|
<div class="text-center">
|
|
|
|
|
<h2 class="text-xl font-semibold text-secondaryDark">Something went wrong</h2>
|
|
|
|
|
<h2 class="text-xl font-semibold text-secondaryDark">
|
|
|
|
|
Something went wrong
|
|
|
|
|
</h2>
|
|
|
|
|
<p class="text-red-500 mt-2">{{ error }}</p>
|
|
|
|
|
</div>
|
|
|
|
|
<HoppButtonPrimary
|
|
|
|
|
@ -91,24 +129,24 @@
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
|
|
|
import { ref, onMounted } from "vue";
|
|
|
|
|
import { LazyStore } from '@tauri-apps/plugin-store';
|
|
|
|
|
import { load } from "@hoppscotch/plugin-appload";
|
|
|
|
|
import { getVersion } from '@tauri-apps/api/app';
|
|
|
|
|
import { ref, onMounted } from "vue"
|
|
|
|
|
import { LazyStore } from "@tauri-apps/plugin-store"
|
|
|
|
|
import { load } from "@hoppscotch/plugin-appload"
|
|
|
|
|
import { getVersion } from "@tauri-apps/api/app"
|
|
|
|
|
|
|
|
|
|
import { UpdateStatus, CheckResult, UpdateState } from "~/types";
|
|
|
|
|
import { UpdaterService } from "~/utils/updater";
|
|
|
|
|
import { UpdateStatus, CheckResult, UpdateState } from "~/types"
|
|
|
|
|
import { UpdaterService } from "~/utils/updater"
|
|
|
|
|
|
|
|
|
|
import IconLucideAlertCircle from "~icons/lucide/alert-circle";
|
|
|
|
|
import IconLucideRefreshCw from "~icons/lucide/refresh-cw";
|
|
|
|
|
import IconLucideDownload from "~icons/lucide/download";
|
|
|
|
|
import IconLucideAlertCircle from "~icons/lucide/alert-circle"
|
|
|
|
|
import IconLucideRefreshCw from "~icons/lucide/refresh-cw"
|
|
|
|
|
import IconLucideDownload from "~icons/lucide/download"
|
|
|
|
|
|
|
|
|
|
const APP_STORE_PATH = "hoppscotch-desktop.store";
|
|
|
|
|
const APP_STORE_PATH = "hoppscotch-desktop.store"
|
|
|
|
|
|
|
|
|
|
// `InstanceSwitcherService` store path.
|
|
|
|
|
// NOTE: This should be removed eventually,
|
|
|
|
|
// right now this is part 1/5 of HFE-864
|
|
|
|
|
const INSTANCE_STORE_PATH = "hopp.store.json";
|
|
|
|
|
const INSTANCE_STORE_PATH = "hopp.store.json"
|
|
|
|
|
|
|
|
|
|
enum AppState {
|
|
|
|
|
LOADING = "loading",
|
|
|
|
|
@ -116,108 +154,116 @@ enum AppState {
|
|
|
|
|
UPDATE_IN_PROGRESS = "update_in_progress",
|
|
|
|
|
UPDATE_READY = "update_ready",
|
|
|
|
|
ERROR = "error",
|
|
|
|
|
LOADED = "loaded"
|
|
|
|
|
LOADED = "loaded",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface VendoredInstance {
|
|
|
|
|
type: "vendored";
|
|
|
|
|
displayName: string;
|
|
|
|
|
version: string;
|
|
|
|
|
type: "vendored"
|
|
|
|
|
displayName: string
|
|
|
|
|
version: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface ConnectionState {
|
|
|
|
|
status: "idle" | "connecting" | "connected" | "error";
|
|
|
|
|
instance?: VendoredInstance;
|
|
|
|
|
target?: string;
|
|
|
|
|
message?: string;
|
|
|
|
|
status: "idle" | "connecting" | "connected" | "error"
|
|
|
|
|
instance?: VendoredInstance
|
|
|
|
|
target?: string
|
|
|
|
|
message?: string
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const appStore = new LazyStore(APP_STORE_PATH);
|
|
|
|
|
const appState = ref<AppState>(AppState.LOADING);
|
|
|
|
|
const updateStatus = ref("");
|
|
|
|
|
const updateMessage = ref("");
|
|
|
|
|
const downloadProgress = ref<{ downloaded: number; total?: number }>({ downloaded: 0 });
|
|
|
|
|
const error = ref("");
|
|
|
|
|
const statusMessage = ref("Initializing...");
|
|
|
|
|
const appVersion = ref("...");
|
|
|
|
|
const appStore = new LazyStore(APP_STORE_PATH)
|
|
|
|
|
const appState = ref<AppState>(AppState.LOADING)
|
|
|
|
|
const updateStatus = ref("")
|
|
|
|
|
const updateMessage = ref("")
|
|
|
|
|
const downloadProgress = ref<{ downloaded: number; total?: number }>({
|
|
|
|
|
downloaded: 0,
|
|
|
|
|
})
|
|
|
|
|
const error = ref("")
|
|
|
|
|
const statusMessage = ref("Initializing...")
|
|
|
|
|
const appVersion = ref("...")
|
|
|
|
|
|
|
|
|
|
const updaterService = new UpdaterService(appStore);
|
|
|
|
|
const updaterService = new UpdaterService(appStore)
|
|
|
|
|
|
|
|
|
|
const formatBytes = (bytes: number): string => {
|
|
|
|
|
if (bytes === 0) return '0 Bytes';
|
|
|
|
|
if (bytes === 0) return "0 Bytes"
|
|
|
|
|
|
|
|
|
|
const k = 1024;
|
|
|
|
|
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
|
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
|
|
|
const k = 1024
|
|
|
|
|
const sizes = ["Bytes", "KB", "MB", "GB"]
|
|
|
|
|
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
|
|
|
|
|
|
|
|
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
|
|
|
|
|
};
|
|
|
|
|
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const saveConnectionState = async (state: ConnectionState) => {
|
|
|
|
|
try {
|
|
|
|
|
await appStore.set("connectionState", state);
|
|
|
|
|
await appStore.save();
|
|
|
|
|
await appStore.set("connectionState", state)
|
|
|
|
|
await appStore.save()
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error("Failed to save connection state:", err);
|
|
|
|
|
console.error("Failed to save connection state:", err)
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const setupUpdateStateWatcher = async () => {
|
|
|
|
|
const unsubscribe = await appStore.onKeyChange<UpdateState>("updateState", (newValue) => {
|
|
|
|
|
if (!newValue) return;
|
|
|
|
|
const unsubscribe = await appStore.onKeyChange<UpdateState>(
|
|
|
|
|
"updateState",
|
|
|
|
|
(newValue) => {
|
|
|
|
|
if (!newValue) return
|
|
|
|
|
|
|
|
|
|
updateStatus.value = newValue.status;
|
|
|
|
|
updateMessage.value = newValue.message || "";
|
|
|
|
|
updateStatus.value = newValue.status
|
|
|
|
|
updateMessage.value = newValue.message || ""
|
|
|
|
|
|
|
|
|
|
if (newValue.progress) {
|
|
|
|
|
downloadProgress.value = newValue.progress;
|
|
|
|
|
if (newValue.progress) {
|
|
|
|
|
downloadProgress.value = newValue.progress
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (newValue.status === UpdateStatus.AVAILABLE) {
|
|
|
|
|
appState.value = AppState.UPDATE_AVAILABLE
|
|
|
|
|
} else if (newValue.status === UpdateStatus.ERROR) {
|
|
|
|
|
error.value = newValue.message || "Unknown error"
|
|
|
|
|
appState.value = AppState.ERROR
|
|
|
|
|
} else if (
|
|
|
|
|
newValue.status === UpdateStatus.DOWNLOADING ||
|
|
|
|
|
newValue.status === UpdateStatus.INSTALLING
|
|
|
|
|
) {
|
|
|
|
|
appState.value = AppState.UPDATE_IN_PROGRESS
|
|
|
|
|
} else if (newValue.status === UpdateStatus.READY_TO_RESTART) {
|
|
|
|
|
appState.value = AppState.UPDATE_READY
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if (newValue.status === UpdateStatus.AVAILABLE) {
|
|
|
|
|
appState.value = AppState.UPDATE_AVAILABLE;
|
|
|
|
|
} else if (newValue.status === UpdateStatus.ERROR) {
|
|
|
|
|
error.value = newValue.message || "Unknown error";
|
|
|
|
|
appState.value = AppState.ERROR;
|
|
|
|
|
} else if (newValue.status === UpdateStatus.DOWNLOADING || newValue.status === UpdateStatus.INSTALLING) {
|
|
|
|
|
appState.value = AppState.UPDATE_IN_PROGRESS;
|
|
|
|
|
} else if (newValue.status === UpdateStatus.READY_TO_RESTART) {
|
|
|
|
|
appState.value = AppState.UPDATE_READY;
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return unsubscribe;
|
|
|
|
|
};
|
|
|
|
|
return unsubscribe
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const installUpdate = async () => {
|
|
|
|
|
try {
|
|
|
|
|
appState.value = AppState.UPDATE_IN_PROGRESS;
|
|
|
|
|
await updaterService.downloadAndInstall();
|
|
|
|
|
appState.value = AppState.UPDATE_IN_PROGRESS
|
|
|
|
|
await updaterService.downloadAndInstall()
|
|
|
|
|
// In a rare occurrence where we reach here but automatic restart didn't happen,
|
|
|
|
|
// we'll just show a restart button instead
|
|
|
|
|
} catch (err) {
|
|
|
|
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
|
|
|
error.value = `Failed to install update: ${errorMessage}`;
|
|
|
|
|
appState.value = AppState.ERROR;
|
|
|
|
|
const errorMessage = err instanceof Error ? err.message : String(err)
|
|
|
|
|
error.value = `Failed to install update: ${errorMessage}`
|
|
|
|
|
appState.value = AppState.ERROR
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const skipUpdate = async () => {
|
|
|
|
|
await loadVendored();
|
|
|
|
|
};
|
|
|
|
|
await loadVendored()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const restartApp = async () => {
|
|
|
|
|
try {
|
|
|
|
|
await updaterService.restartApp();
|
|
|
|
|
await updaterService.restartApp()
|
|
|
|
|
} catch (err) {
|
|
|
|
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
|
|
|
error.value = `Failed to restart app: ${errorMessage}`;
|
|
|
|
|
appState.value = AppState.ERROR;
|
|
|
|
|
const errorMessage = err instanceof Error ? err.message : String(err)
|
|
|
|
|
error.value = `Failed to restart app: ${errorMessage}`
|
|
|
|
|
appState.value = AppState.ERROR
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const loadVendored = async () => {
|
|
|
|
|
try {
|
|
|
|
|
statusMessage.value = "Loading application...";
|
|
|
|
|
statusMessage.value = "Loading application..."
|
|
|
|
|
|
|
|
|
|
// Standardized vendored instance data.
|
|
|
|
|
// NOTE: This should be removed eventually,
|
|
|
|
|
@ -225,96 +271,101 @@ const loadVendored = async () => {
|
|
|
|
|
const vendoredInstance: VendoredInstance = {
|
|
|
|
|
type: "vendored",
|
|
|
|
|
displayName: "Hoppscotch",
|
|
|
|
|
version: "25.5.1"
|
|
|
|
|
};
|
|
|
|
|
version: "25.5.2",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const connectionState: ConnectionState = {
|
|
|
|
|
status: "connected",
|
|
|
|
|
instance: vendoredInstance
|
|
|
|
|
};
|
|
|
|
|
instance: vendoredInstance,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Save to current app store.
|
|
|
|
|
// NOTE: This is existing behavior
|
|
|
|
|
await saveConnectionState(connectionState);
|
|
|
|
|
await saveConnectionState(connectionState)
|
|
|
|
|
|
|
|
|
|
// ALSO save to `InstanceSwitcherService` store,
|
|
|
|
|
// NOTE: This should be removed eventually,
|
|
|
|
|
// right now this is part 1/5 of HFE-864
|
|
|
|
|
try {
|
|
|
|
|
const instanceStore = new LazyStore(INSTANCE_STORE_PATH);
|
|
|
|
|
await instanceStore.init();
|
|
|
|
|
await instanceStore.set("connectionState", connectionState);
|
|
|
|
|
await instanceStore.save();
|
|
|
|
|
console.log("Successfully saved vendored state to `InstanceSwitcherService` store");
|
|
|
|
|
const instanceStore = new LazyStore(INSTANCE_STORE_PATH)
|
|
|
|
|
await instanceStore.init()
|
|
|
|
|
await instanceStore.set("connectionState", connectionState)
|
|
|
|
|
await instanceStore.save()
|
|
|
|
|
console.log(
|
|
|
|
|
"Successfully saved vendored state to `InstanceSwitcherService` store"
|
|
|
|
|
)
|
|
|
|
|
} catch (instanceStoreError) {
|
|
|
|
|
console.error("Failed to save to `InstanceSwitcherService` store:", instanceStoreError);
|
|
|
|
|
console.error(
|
|
|
|
|
"Failed to save to `InstanceSwitcherService` store:",
|
|
|
|
|
instanceStoreError
|
|
|
|
|
)
|
|
|
|
|
// Don't need to fail the flow if this fails.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log("Loading vendored app...");
|
|
|
|
|
console.log("Loading vendored app...")
|
|
|
|
|
const loadResp = await load({
|
|
|
|
|
bundleName: "Hoppscotch",
|
|
|
|
|
window: { title: "Hoppscotch" }
|
|
|
|
|
});
|
|
|
|
|
window: { title: "Hoppscotch" },
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
if (!loadResp.success) {
|
|
|
|
|
throw new Error("Failed to load Hoppscotch Vendored");
|
|
|
|
|
throw new Error("Failed to load Hoppscotch Vendored")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.log("Vendored app loaded successfully");
|
|
|
|
|
console.log("Vendored app loaded successfully")
|
|
|
|
|
} catch (err) {
|
|
|
|
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
|
|
|
console.error("Error loading vendored app:", errorMessage);
|
|
|
|
|
error.value = errorMessage;
|
|
|
|
|
const errorMessage = err instanceof Error ? err.message : String(err)
|
|
|
|
|
console.error("Error loading vendored app:", errorMessage)
|
|
|
|
|
error.value = errorMessage
|
|
|
|
|
|
|
|
|
|
await saveConnectionState({
|
|
|
|
|
status: "error",
|
|
|
|
|
target: "Vendored",
|
|
|
|
|
message: errorMessage
|
|
|
|
|
});
|
|
|
|
|
message: errorMessage,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
appState.value = AppState.ERROR;
|
|
|
|
|
appState.value = AppState.ERROR
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const initialize = async () => {
|
|
|
|
|
appState.value = AppState.LOADING;
|
|
|
|
|
error.value = "";
|
|
|
|
|
downloadProgress.value = { downloaded: 0 };
|
|
|
|
|
appState.value = AppState.LOADING
|
|
|
|
|
error.value = ""
|
|
|
|
|
downloadProgress.value = { downloaded: 0 }
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
try {
|
|
|
|
|
appVersion.value = await getVersion();
|
|
|
|
|
appVersion.value = await getVersion()
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Failed to get app version:", error);
|
|
|
|
|
appVersion.value = "unknown";
|
|
|
|
|
console.error("Failed to get app version:", error)
|
|
|
|
|
appVersion.value = "unknown"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
statusMessage.value = "Initializing stores...";
|
|
|
|
|
await appStore.init();
|
|
|
|
|
await updaterService.initialize();
|
|
|
|
|
statusMessage.value = "Initializing stores..."
|
|
|
|
|
await appStore.init()
|
|
|
|
|
await updaterService.initialize()
|
|
|
|
|
|
|
|
|
|
await setupUpdateStateWatcher();
|
|
|
|
|
await setupUpdateStateWatcher()
|
|
|
|
|
|
|
|
|
|
statusMessage.value = "Checking for updates...";
|
|
|
|
|
const checkResult = await updaterService.checkForUpdates();
|
|
|
|
|
statusMessage.value = "Checking for updates..."
|
|
|
|
|
const checkResult = await updaterService.checkForUpdates()
|
|
|
|
|
|
|
|
|
|
if (checkResult === CheckResult.AVAILABLE) {
|
|
|
|
|
console.log("Updates available, prompting for install");
|
|
|
|
|
appState.value = AppState.UPDATE_AVAILABLE;
|
|
|
|
|
return;
|
|
|
|
|
console.log("Updates available, prompting for install")
|
|
|
|
|
appState.value = AppState.UPDATE_AVAILABLE
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
await loadVendored();
|
|
|
|
|
await loadVendored()
|
|
|
|
|
} catch (err) {
|
|
|
|
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
|
|
|
console.error("Initialization error:", errorMessage);
|
|
|
|
|
error.value = errorMessage;
|
|
|
|
|
appState.value = AppState.ERROR;
|
|
|
|
|
const errorMessage = err instanceof Error ? err.message : String(err)
|
|
|
|
|
console.error("Initialization error:", errorMessage)
|
|
|
|
|
error.value = errorMessage
|
|
|
|
|
appState.value = AppState.ERROR
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
initialize();
|
|
|
|
|
});
|
|
|
|
|
initialize()
|
|
|
|
|
})
|
|
|
|
|
</script>
|
|
|
|
|
|