fix(desktop): window lifecycle for instance switch (#5381)
This resolves window accumulation during instance switching by implementing proper window lifecycle management using Tauri's WebviewWindow APIs. Co-authored-by: jamesgeorge007 <25279263+jamesgeorge007@users.noreply.github.com>
This commit is contained in:
parent
a23a2c657d
commit
ba700886b5
3 changed files with 56 additions and 19 deletions
|
|
@ -40,7 +40,7 @@
|
|||
"@hoppscotch/httpsnippet": "3.0.9",
|
||||
"@hoppscotch/js-sandbox": "workspace:^",
|
||||
"@hoppscotch/kernel": "workspace:^",
|
||||
"@hoppscotch/plugin-appload": "github:CuriousCorrelation/tauri-plugin-appload#e8dbe06eabf947e5efaf07d2e573238ceb11a7b1",
|
||||
"@hoppscotch/plugin-appload": "github:CuriousCorrelation/tauri-plugin-appload#e05861959938b57479a1a81fa796735ebbd08c7c",
|
||||
"@hoppscotch/ui": "0.2.5",
|
||||
"@hoppscotch/vue-toasted": "0.1.0",
|
||||
"@lezer/highlight": "1.2.1",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,17 @@ import { Service } from "dioc"
|
|||
import { BehaviorSubject, Observable } from "rxjs"
|
||||
import { computed } from "vue"
|
||||
import { LazyStore } from "@tauri-apps/plugin-store"
|
||||
import { download, load, clear, remove } from "@hoppscotch/plugin-appload"
|
||||
import {
|
||||
getCurrentWebviewWindow,
|
||||
getAllWebviewWindows,
|
||||
} from "@tauri-apps/api/webviewWindow"
|
||||
import {
|
||||
download,
|
||||
load,
|
||||
clear,
|
||||
remove,
|
||||
close,
|
||||
} from "@hoppscotch/plugin-appload"
|
||||
import { useToast } from "~/composables/toast"
|
||||
import { platform } from "~/platform"
|
||||
|
||||
|
|
@ -156,6 +166,11 @@ export class InstanceSwitcherService extends Service<ConnectionState> {
|
|||
this.getVendoredInstance().displayName
|
||||
)
|
||||
)
|
||||
|
||||
// Close current window AFTER successful load
|
||||
// NOTE: No need to await it.
|
||||
this.closeCurrentWindow()
|
||||
|
||||
return true
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
|
|
@ -234,6 +249,10 @@ export class InstanceSwitcherService extends Service<ConnectionState> {
|
|||
throw new Error("Failed to load bundle")
|
||||
}
|
||||
|
||||
// Close current window AFTER successful load
|
||||
// NOTE: No need to await it.
|
||||
this.closeCurrentWindow()
|
||||
|
||||
this.toast.success(`Connected to ${displayName}`)
|
||||
return true
|
||||
} catch (error) {
|
||||
|
|
@ -251,6 +270,33 @@ export class InstanceSwitcherService extends Service<ConnectionState> {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the current window using Tauri's window management
|
||||
*/
|
||||
private async closeCurrentWindow(): Promise<void> {
|
||||
try {
|
||||
const currentWindow = getCurrentWebviewWindow()
|
||||
const currentLabel = currentWindow.label
|
||||
|
||||
// Don't close if we're the main window or if there are no other windows
|
||||
if (currentLabel === "main") {
|
||||
const allWindows = await getAllWebviewWindows()
|
||||
if (allWindows.length <= 1) {
|
||||
// Don't close the last window
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const closeResponse = await close({ windowLabel: currentLabel })
|
||||
if (!closeResponse.success) {
|
||||
console.warn(`Failed to close window ${currentLabel}`)
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("Failed to close current window:", error)
|
||||
// Don't throw - window closing shouldn't block the operation
|
||||
}
|
||||
}
|
||||
|
||||
public async removeInstance(serverUrl: string): Promise<boolean> {
|
||||
try {
|
||||
const normalizedUrl = this.normalizeUrl(serverUrl)
|
||||
|
|
@ -285,8 +331,9 @@ export class InstanceSwitcherService extends Service<ConnectionState> {
|
|||
const displayName = this.getDisplayNameFromUrl(serverUrl)
|
||||
this.toast.success(`Removed ${displayName}`)
|
||||
|
||||
// If we're currently connected to this instance, go back to idle state
|
||||
// If we're currently connected to this instance, close the window and go to idle state
|
||||
if (this.isCurrentlyConnectedTo(serverUrl)) {
|
||||
await this.closeCurrentWindow()
|
||||
this.state$.next({ status: "idle" })
|
||||
this.emit(this.state$.value)
|
||||
await this.saveCurrentState()
|
||||
|
|
@ -301,6 +348,7 @@ export class InstanceSwitcherService extends Service<ConnectionState> {
|
|||
|
||||
public async clearCache(): Promise<boolean> {
|
||||
try {
|
||||
await this.closeCurrentWindow()
|
||||
await clear()
|
||||
this.toast.success("Cache cleared successfully")
|
||||
return true
|
||||
|
|
@ -367,19 +415,16 @@ export class InstanceSwitcherService extends Service<ConnectionState> {
|
|||
|
||||
// If it fails, fall back to the original URL with default port
|
||||
try {
|
||||
const re = withSubpath.toString().replace(/\/$/, "")
|
||||
return re
|
||||
return withSubpath.toString().replace(/\/$/, "")
|
||||
} catch {
|
||||
if (!urlObj.port) {
|
||||
urlObj.port = "3200"
|
||||
}
|
||||
const re = urlObj.toString().replace(/\/$/, "")
|
||||
return re
|
||||
return urlObj.toString().replace(/\/$/, "")
|
||||
}
|
||||
}
|
||||
|
||||
const re = urlObj.toString().replace(/\/$/, "")
|
||||
return re
|
||||
return urlObj.toString().replace(/\/$/, "")
|
||||
} catch (error) {
|
||||
return url
|
||||
}
|
||||
|
|
|
|||
|
|
@ -508,8 +508,8 @@ importers:
|
|||
specifier: workspace:^
|
||||
version: link:../hoppscotch-kernel
|
||||
'@hoppscotch/plugin-appload':
|
||||
specifier: github:CuriousCorrelation/tauri-plugin-appload#e8dbe06eabf947e5efaf07d2e573238ceb11a7b1
|
||||
version: '@CuriousCorrelation/plugin-appload@https://codeload.github.com/CuriousCorrelation/tauri-plugin-appload/tar.gz/e8dbe06eabf947e5efaf07d2e573238ceb11a7b1'
|
||||
specifier: github:CuriousCorrelation/tauri-plugin-appload#e05861959938b57479a1a81fa796735ebbd08c7c
|
||||
version: '@CuriousCorrelation/plugin-appload@https://codeload.github.com/CuriousCorrelation/tauri-plugin-appload/tar.gz/e05861959938b57479a1a81fa796735ebbd08c7c'
|
||||
'@hoppscotch/ui':
|
||||
specifier: 0.2.5
|
||||
version: 0.2.5(eslint@8.57.0)(terser@5.39.2)(typescript@5.9.2)(vite@6.3.5(@types/node@24.3.0)(jiti@2.5.1)(sass@1.91.0)(terser@5.39.2)(yaml@2.8.1))(vue@3.5.20(typescript@5.9.2))
|
||||
|
|
@ -1853,10 +1853,6 @@ packages:
|
|||
resolution: {tarball: https://codeload.github.com/CuriousCorrelation/tauri-plugin-appload/tar.gz/e05861959938b57479a1a81fa796735ebbd08c7c}
|
||||
version: 0.1.0
|
||||
|
||||
'@CuriousCorrelation/plugin-appload@https://codeload.github.com/CuriousCorrelation/tauri-plugin-appload/tar.gz/e8dbe06eabf947e5efaf07d2e573238ceb11a7b1':
|
||||
resolution: {tarball: https://codeload.github.com/CuriousCorrelation/tauri-plugin-appload/tar.gz/e8dbe06eabf947e5efaf07d2e573238ceb11a7b1}
|
||||
version: 0.1.0
|
||||
|
||||
'@CuriousCorrelation/plugin-relay@https://codeload.github.com/CuriousCorrelation/tauri-plugin-relay/tar.gz/ff18f776ddeb53dbbdeaf97e1fabc30bdc57c158':
|
||||
resolution: {tarball: https://codeload.github.com/CuriousCorrelation/tauri-plugin-relay/tar.gz/ff18f776ddeb53dbbdeaf97e1fabc30bdc57c158}
|
||||
version: 0.1.0
|
||||
|
|
@ -15542,10 +15538,6 @@ snapshots:
|
|||
dependencies:
|
||||
'@tauri-apps/api': 2.1.1
|
||||
|
||||
'@CuriousCorrelation/plugin-appload@https://codeload.github.com/CuriousCorrelation/tauri-plugin-appload/tar.gz/e8dbe06eabf947e5efaf07d2e573238ceb11a7b1':
|
||||
dependencies:
|
||||
'@tauri-apps/api': 2.1.1
|
||||
|
||||
'@CuriousCorrelation/plugin-relay@https://codeload.github.com/CuriousCorrelation/tauri-plugin-relay/tar.gz/ff18f776ddeb53dbbdeaf97e1fabc30bdc57c158':
|
||||
dependencies:
|
||||
'@tauri-apps/api': 2.1.1
|
||||
|
|
|
|||
Loading…
Reference in a new issue