fix(desktop): align connected instance with launch (#5132)

This commit is contained in:
Shreyas 2025-06-10 13:21:54 +05:30 committed by GitHub
parent 011c8090aa
commit b63c707624
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 126 additions and 32 deletions

View file

@ -22,11 +22,23 @@
:on-shown="() => instanceSwitcherRef.focus()"
>
<div class="flex items-center cursor-pointer">
<span
class="!font-bold uppercase tracking-wide !text-secondaryDark pr-1"
>
{{ instanceDisplayName }}
</span>
<div class="flex">
<span
class="!font-bold uppercase tracking-wide !text-secondaryDark pr-1"
>
{{ instanceDisplayName }}
</span>
<span
v-if="
currentState.status === 'connected' &&
'type' in currentState.instance &&
currentState.instance.type === 'vendored'
"
class="!font-bold uppercase tracking-wide !text-secondaryDark pr-1"
>
{{ platform.instance.displayConfig.description }}
</span>
</div>
<IconChevronDown class="h-4 w-4 text-secondaryDark" />
</div>
<template #content="{ hide }">

View file

@ -11,9 +11,27 @@
<div class="flex items-center gap-4">
<IconLucidePackage />
<div class="flex flex-col">
<span class="font-semibold uppercase">Hoppscotch</span>
<span class="font-semibold uppercase">{{
platform.instance.displayConfig.displayName
}}</span>
<div class="flex items-center gap-1">
<span class="text-xs">On-prem</span>
<!-- NOTE:
If this is set to `platform.instance.displayConfig.description`
it'll be bound to app's perspective, i.e.
when in vendored cloud app, it'll show `Cloud`
and in vendored self-hosted app, it'll show `On-Prem`
even tho both are actually pointing to the same bundle.
Essentially switching instance is a **perspective shift**
for the underlying desktop app launcher.
The best way to solve this would be to make instance information
into "links" to the bundles hosted by the `appload` plugin,
which is already underway in HFE-829.
This is a workaround for the time being. See `Header.vue`
for code that maintains backwards compatibility.
-->
<span class="text-xs">Default</span>
<span class="text-xs"> app </span>
</div>
</div>
@ -235,6 +253,7 @@ import {
InstanceSwitcherService,
InstanceType,
} from "~/services/instance-switcher.service"
import { platform } from "~/platform"
import IconLucideGlobe from "~icons/lucide/globe"
import IconLucideCheck from "~icons/lucide/check"
@ -285,7 +304,7 @@ const connectionError = computed(() => {
})
const isVendored = computed(() => {
return currentInstance.value?.type === "vendored"
return currentInstance.value?.type === platform.instance.instanceType
})
const isValidUrl = computed(() => {

View file

@ -21,6 +21,7 @@ import { BackendPlatformDef } from "./backend"
import { OrganizationPlatformDef } from "./organization"
import { KernelIO } from "./kernel-io"
import { AdditionalLinksPlatformDef } from "./additionalLinks"
import { InstancePlatformDef } from "./instance"
export type PlatformDef = {
ui?: UIPlatformDef
@ -31,6 +32,7 @@ export type PlatformDef = {
// NOTE: To be deprecated
// io: IOPlatformDef
kernelIO: KernelIO
instance: InstancePlatformDef
sync: {
environments: EnvironmentsPlatformDef
collections: CollectionsPlatformDef

View file

@ -0,0 +1,10 @@
export type InstancePlatformDef = {
instanceType: "vendored"
displayConfig: {
displayName: string
description: string
version: string
connectingMessage: string
connectedMessage: string
}
}

View file

@ -4,6 +4,7 @@ import { computed } from "vue"
import { LazyStore } from "@tauri-apps/plugin-store"
import { download, load, clear, remove } from "@hoppscotch/plugin-appload"
import { useToast } from "~/composables/toast"
import { platform } from "~/platform"
const STORE_PATH = "hopp.store.json"
const MAX_RECENT_INSTANCES = 10
@ -39,21 +40,26 @@ export class InstanceSwitcherService extends Service<ConnectionState> {
private store!: LazyStore
private toast = useToast()
public getVendoredInstance(): VendoredInstance {
const { instanceType, displayConfig } = platform.instance
const { displayName, version } = displayConfig
return {
type: instanceType,
displayName,
version,
}
}
override async onServiceInit(): Promise<void> {
this.store = new LazyStore(STORE_PATH)
await this.store.init()
await this.loadRecentInstances()
if (this.inVendoredEnvironment()) {
const instance: VendoredInstance = {
type: "vendored",
displayName: "Hoppscotch",
version: "25.5.1",
}
this.state$.next({
status: "connected",
instance,
instance: this.getVendoredInstance(),
})
this.emit(this.state$.value)
} else {
@ -113,26 +119,25 @@ export class InstanceSwitcherService extends Service<ConnectionState> {
this.state$.next({
status: "connecting",
target: "Vendored",
target: this.getVendoredInstance().displayName,
})
this.emit(this.state$.value)
try {
const instance: VendoredInstance = {
type: "vendored",
displayName: "Hoppscotch",
version: "25.5.1",
}
this.state$.next({
status: "connected",
instance,
instance: this.getVendoredInstance(),
})
this.emit(this.state$.value)
await this.saveCurrentState()
this.toast.success("Connecting to Vendored")
this.toast.success(
platform.instance.displayConfig.connectingMessage.replace(
"{instanceName}",
this.getVendoredInstance().displayName
)
)
const loadResponse = await load({
bundleName: "Hoppscotch",
@ -140,17 +145,24 @@ export class InstanceSwitcherService extends Service<ConnectionState> {
})
if (!loadResponse.success) {
throw new Error("Failed to load vendored bundle")
throw new Error(
`Failed to load ${this.getVendoredInstance().type} bundle`
)
}
this.toast.success("Connected to Vendored")
this.toast.success(
platform.instance.displayConfig.connectedMessage.replace(
"{instanceName}",
this.getVendoredInstance().displayName
)
)
return true
} catch (error) {
const errorMessage =
error instanceof Error ? error.message : String(error)
this.state$.next({
status: "error",
target: "Vendored",
target: this.getVendoredInstance().displayName,
message: errorMessage,
})
this.emit(this.state$.value)
@ -325,7 +337,10 @@ export class InstanceSwitcherService extends Service<ConnectionState> {
public isCurrentlyVendored(): boolean {
const state = this.state$.value
return state.status === "connected" && state.instance.type === "vendored"
return (
state.status === "connected" &&
state.instance.type === this.getVendoredInstance().type
)
}
public isCurrentlyConnectedTo(serverUrl: string): boolean {

View file

@ -105,6 +105,11 @@ import IconLucideDownload from "~icons/lucide/download";
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";
enum AppState {
LOADING = "loading",
UPDATE_AVAILABLE = "update_available",
@ -214,16 +219,37 @@ const loadVendored = async () => {
try {
statusMessage.value = "Loading application...";
// Standardized vendored instance data.
// NOTE: This should be removed eventually,
// right now this is part 1/5 of HFE-864
const vendoredInstance: VendoredInstance = {
type: "vendored",
displayName: "Vendored",
version: "vendored"
displayName: "Hoppscotch",
version: "25.5.1"
};
await saveConnectionState({
const connectionState: ConnectionState = {
status: "connected",
instance: vendoredInstance
});
};
// Save to current app store.
// NOTE: This is existing behavior
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");
} catch (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...");
const loadResp = await load({

View file

@ -78,6 +78,16 @@ async function initApp() {
},
auth: platformDefs.auth.get(kernelMode),
kernelIO,
instance: {
instanceType: 'vendored',
displayConfig: {
displayName: 'Hoppscotch',
description: 'On-Prem',
version: '25.5.1',
connectingMessage: 'Connecting to On-prem',
connectedMessage: 'Connected to On-prem'
}
},
sync: {
environments: platformDefs.environments.get(kernelMode),
collections: platformDefs.collections.get(kernelMode),