This commit is contained in:
firestar5683
2026-09-14 14:32:33 -05:00
parent 2878d13c3d
commit 9e5a3e288b
3 changed files with 67 additions and 17 deletions
@@ -42,6 +42,12 @@ function postOk(url, opts = {}) {
}
export const api = {
async getGatewayDevices() {
const response = await fetch("/_gateway/devices", { cache: "no-store" })
if (!response.ok) return null
return response.json()
},
postAction(endpoint) { return request(endpoint, { method: "POST" }) },
getOptions(endpoint) { return request(endpoint) },
@@ -18,10 +18,17 @@ function toPercent(value) {
const CORE_UPDATE_BRANCHES = ["StarPilot", "Dom"]
const REBOOT_PENDING_STORAGE_KEY = "galaxy-update-reboot-pending"
const LOCAL_DEVICE_SCOPE = "local"
const DEVICE_SLUG_RE = /^[A-Za-z0-9]{16}$/
function readRebootMarker() {
function rebootStorageKey(scope = LOCAL_DEVICE_SCOPE) {
const normalizedScope = String(scope || "").trim() || LOCAL_DEVICE_SCOPE
return REBOOT_PENDING_STORAGE_KEY + ":" + normalizedScope
}
function readRebootMarker(scope = LOCAL_DEVICE_SCOPE) {
try {
const raw = localStorage.getItem(REBOOT_PENDING_STORAGE_KEY)
const raw = localStorage.getItem(rebootStorageKey(scope))
if (!raw) return null
const parsed = JSON.parse(raw)
const startedAt = Number(parsed?.startedAt)
@@ -31,12 +38,23 @@ function readRebootMarker() {
}
}
function writeRebootMarker(startedAt) {
try { localStorage.setItem(REBOOT_PENDING_STORAGE_KEY, JSON.stringify({ startedAt })) } catch (e) {}
function writeRebootMarker(scope, startedAt) {
try { localStorage.setItem(rebootStorageKey(scope), JSON.stringify({ startedAt })) } catch (e) {}
}
function clearRebootMarker() {
try { localStorage.removeItem(REBOOT_PENDING_STORAGE_KEY) } catch (e) {}
function clearRebootMarker(scope) {
try { localStorage.removeItem(rebootStorageKey(scope)) } catch (e) {}
}
async function resolveDeviceScope() {
try {
const payload = await api.getGatewayDevices()
if (!payload) return LOCAL_DEVICE_SCOPE
return DEVICE_SLUG_RE.test(payload?.activeSlug || "") ? payload.activeSlug : LOCAL_DEVICE_SCOPE
} catch (e) {
// Direct/local Galaxy instances do not have the gateway directory endpoint.
return LOCAL_DEVICE_SCOPE
}
}
export const SystemTools = {
@@ -67,8 +85,9 @@ export const SystemTools = {
isOnroad: false,
fastStatus: null,
statusUnavailable: false,
rebootPending: !!readRebootMarker(),
rebootStartedAt: readRebootMarker() || 0,
rebootStorageScope: LOCAL_DEVICE_SCOPE,
rebootPending: false,
rebootStartedAt: 0,
rebootOfflineSeen: false,
reconnectedNotice: false,
checkedForUpdates: false,
@@ -82,14 +101,35 @@ export const SystemTools = {
}
},
created() {
this.poll = usePolling(() => this.loadFastStatus(), {
interval: 1000,
enabled: () => this.statusPollingNeeded,
this.rebootScopeCancelled = false
this.rebootReady = resolveDeviceScope().then((scope) => {
if (this.rebootScopeCancelled) return
this.rebootStorageScope = scope
const marker = readRebootMarker(scope)
this.rebootPending = !!marker
this.rebootStartedAt = marker || 0
}).finally(() => {
if (this.rebootScopeCancelled) return
this.poll = usePolling(() => this.loadFastStatus(), {
interval: 1000,
enabled: () => this.statusPollingNeeded,
})
this.poll.start()
})
this.poll.start()
},
mounted() { this.loadBranches(); this.loadProfiles(); this.loadTailscale() },
beforeUnmount() { this.poll?.destroy(); this.resetVersions() },
mounted() {
this.rebootReady.then(() => {
if (this.rebootScopeCancelled) return
this.loadBranches()
this.loadProfiles()
this.loadTailscale()
})
},
beforeUnmount() {
this.rebootScopeCancelled = true
this.poll?.destroy()
this.resetVersions()
},
computed: {
primaryBranchValue() {
if (this.otherBranchesOpen) return "other:"
@@ -198,13 +238,13 @@ export const SystemTools = {
this.rebootStartedAt = Date.now()
this.rebootOfflineSeen = false
this.reconnectedNotice = false
writeRebootMarker(this.rebootStartedAt)
writeRebootMarker(this.rebootStorageScope, this.rebootStartedAt)
},
clearRebootPending(showNotice = true) {
this.rebootPending = false
this.rebootStartedAt = 0
this.rebootOfflineSeen = false
clearRebootMarker()
clearRebootMarker(this.rebootStorageScope)
if (showNotice) this.reconnectedNotice = true
},
async backupToggles() {
@@ -591,7 +591,11 @@ def test_ui_mobile_polish_regressions():
assert "Automatically Install Updates" in system
assert 'key: "AutomaticUpdates"' in system
assert "!!fastStatus?.automaticUpdates" in system
assert "isOnroad || autoUpdateBusy || !!fastStatus?.running" in system
assert "isOnroad || autoUpdateBusy || updateInProgress" in system
assert "getGatewayDevices" in _read("js/api.js")
assert "rebootStorageScope" in system
assert "writeRebootMarker(this.rebootStorageScope" in system
assert "clearRebootMarker(this.rebootStorageScope" in system
bluetooth = _read("js/components/BluetoothPanel.js")
assert "methods: {\n address," in bluetooth