support start on reboot (#132)
* move launcher to eastier lib * support auto start after reboot
This commit is contained in:
Vendored
+6
@@ -27,6 +27,7 @@ declare global {
|
||||
const isReactive: typeof import('vue')['isReactive']
|
||||
const isReadonly: typeof import('vue')['isReadonly']
|
||||
const isRef: typeof import('vue')['isRef']
|
||||
const loadRunningInstanceIdsFromLocalStorage: typeof import('./stores/network')['loadRunningInstanceIdsFromLocalStorage']
|
||||
const mapActions: typeof import('pinia')['mapActions']
|
||||
const mapGetters: typeof import('pinia')['mapGetters']
|
||||
const mapState: typeof import('pinia')['mapState']
|
||||
@@ -58,6 +59,7 @@ declare global {
|
||||
const retainNetworkInstance: typeof import('./composables/network')['retainNetworkInstance']
|
||||
const runNetworkInstance: typeof import('./composables/network')['runNetworkInstance']
|
||||
const setActivePinia: typeof import('pinia')['setActivePinia']
|
||||
const setAutoLaunchStatus: typeof import('./composables/network')['setAutoLaunchStatus']
|
||||
const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix']
|
||||
const shallowReactive: typeof import('vue')['shallowReactive']
|
||||
const shallowReadonly: typeof import('vue')['shallowReadonly']
|
||||
@@ -116,6 +118,7 @@ declare module 'vue' {
|
||||
readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
|
||||
readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
|
||||
readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
|
||||
readonly loadRunningInstanceIdsFromLocalStorage: UnwrapRef<typeof import('./stores/network')['loadRunningInstanceIdsFromLocalStorage']>
|
||||
readonly mapActions: UnwrapRef<typeof import('pinia')['mapActions']>
|
||||
readonly mapGetters: UnwrapRef<typeof import('pinia')['mapGetters']>
|
||||
readonly mapState: UnwrapRef<typeof import('pinia')['mapState']>
|
||||
@@ -147,6 +150,7 @@ declare module 'vue' {
|
||||
readonly retainNetworkInstance: UnwrapRef<typeof import('./composables/network')['retainNetworkInstance']>
|
||||
readonly runNetworkInstance: UnwrapRef<typeof import('./composables/network')['runNetworkInstance']>
|
||||
readonly setActivePinia: UnwrapRef<typeof import('pinia')['setActivePinia']>
|
||||
readonly setAutoLaunchStatus: UnwrapRef<typeof import('./composables/network')['setAutoLaunchStatus']>
|
||||
readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']>
|
||||
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
|
||||
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
|
||||
@@ -198,6 +202,7 @@ declare module '@vue/runtime-core' {
|
||||
readonly isReactive: UnwrapRef<typeof import('vue')['isReactive']>
|
||||
readonly isReadonly: UnwrapRef<typeof import('vue')['isReadonly']>
|
||||
readonly isRef: UnwrapRef<typeof import('vue')['isRef']>
|
||||
readonly loadRunningInstanceIdsFromLocalStorage: UnwrapRef<typeof import('./stores/network')['loadRunningInstanceIdsFromLocalStorage']>
|
||||
readonly mapActions: UnwrapRef<typeof import('pinia')['mapActions']>
|
||||
readonly mapGetters: UnwrapRef<typeof import('pinia')['mapGetters']>
|
||||
readonly mapState: UnwrapRef<typeof import('pinia')['mapState']>
|
||||
@@ -229,6 +234,7 @@ declare module '@vue/runtime-core' {
|
||||
readonly retainNetworkInstance: UnwrapRef<typeof import('./composables/network')['retainNetworkInstance']>
|
||||
readonly runNetworkInstance: UnwrapRef<typeof import('./composables/network')['runNetworkInstance']>
|
||||
readonly setActivePinia: UnwrapRef<typeof import('pinia')['setActivePinia']>
|
||||
readonly setAutoLaunchStatus: UnwrapRef<typeof import('./composables/network')['setAutoLaunchStatus']>
|
||||
readonly setMapStoreSuffix: UnwrapRef<typeof import('pinia')['setMapStoreSuffix']>
|
||||
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
|
||||
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
|
||||
|
||||
@@ -20,3 +20,7 @@ export async function collectNetworkInfos() {
|
||||
export async function getOsHostname() {
|
||||
return await invoke<string>('get_os_hostname')
|
||||
}
|
||||
|
||||
export async function setAutoLaunchStatus(enable: boolean) {
|
||||
return await invoke<boolean>('set_auto_launch_status', { enable })
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'primevue/resources/themes/aura-light-green/theme.css'
|
||||
import 'primeicons/primeicons.css'
|
||||
import 'primeflex/primeflex.css'
|
||||
import { i18n, loadLanguageAsync } from '~/modules/i18n'
|
||||
import { loadAutoLaunchStatusAsync, getAutoLaunchStatusAsync } from './modules/auto_launch'
|
||||
|
||||
if (import.meta.env.PROD) {
|
||||
document.addEventListener('keydown', (event) => {
|
||||
@@ -28,6 +29,7 @@ if (import.meta.env.PROD) {
|
||||
|
||||
async function main() {
|
||||
await loadLanguageAsync(localStorage.getItem('lang') || 'en')
|
||||
await loadAutoLaunchStatusAsync(getAutoLaunchStatusAsync())
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
import { setAutoLaunchStatus } from "~/composables/network"
|
||||
|
||||
export async function loadAutoLaunchStatusAsync(enable: boolean): Promise<boolean> {
|
||||
try {
|
||||
const ret = await setAutoLaunchStatus(enable)
|
||||
localStorage.setItem('auto_launch', JSON.stringify(ret))
|
||||
return ret
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
export function getAutoLaunchStatusAsync(): boolean {
|
||||
return localStorage.getItem('auto_launch') === 'true'
|
||||
}
|
||||
@@ -10,6 +10,8 @@ import Status from '~/components/Status.vue'
|
||||
|
||||
import type { NetworkConfig } from '~/types/network'
|
||||
import { loadLanguageAsync } from '~/modules/i18n'
|
||||
import { getAutoLaunchStatusAsync as getAutoLaunchStatus, loadAutoLaunchStatusAsync } from '~/modules/auto_launch'
|
||||
import { loadRunningInstanceIdsFromLocalStorage } from '~/stores/network'
|
||||
|
||||
const { t, locale } = useI18n()
|
||||
const visible = ref(false)
|
||||
@@ -63,6 +65,7 @@ function addNewNetwork() {
|
||||
|
||||
networkStore.$subscribe(async () => {
|
||||
networkStore.saveToLocalStorage()
|
||||
networkStore.saveRunningInstanceIdsToLocalStorage()
|
||||
try {
|
||||
await parseNetworkConfig(networkStore.curNetwork)
|
||||
messageBarSeverity.value = Severity.None
|
||||
@@ -123,9 +126,16 @@ const setting_menu_items = ref([
|
||||
await loadLanguageAsync((locale.value === 'en' ? 'cn' : 'en'))
|
||||
},
|
||||
},
|
||||
{
|
||||
label: () => getAutoLaunchStatus() ? t('disable_auto_launch') : t('enable_auto_launch'),
|
||||
icon: 'pi pi-desktop',
|
||||
command: async () => {
|
||||
await loadAutoLaunchStatusAsync(!getAutoLaunchStatus())
|
||||
},
|
||||
},
|
||||
{
|
||||
label: () => t('exit'),
|
||||
icon: 'pi pi-times',
|
||||
icon: 'pi pi-power-off',
|
||||
command: async () => {
|
||||
await exit(1)
|
||||
},
|
||||
@@ -140,6 +150,16 @@ function toggle_setting_menu(event: any) {
|
||||
|
||||
onMounted(async () => {
|
||||
networkStore.loadFromLocalStorage()
|
||||
if (getAutoLaunchStatus()) {
|
||||
let prev_running_ids = loadRunningInstanceIdsFromLocalStorage()
|
||||
for (let id of prev_running_ids) {
|
||||
let cfg = networkStore.networkList.find((item) => item.instance_id === id)
|
||||
if (cfg) {
|
||||
networkStore.addNetworkInstance(cfg.instance_id)
|
||||
await runNetworkInstance(cfg)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function isRunning(id: string) {
|
||||
@@ -168,35 +188,28 @@ function isRunning(id: string) {
|
||||
<Toolbar>
|
||||
<template #start>
|
||||
<div class="flex align-items-center gap-2">
|
||||
<Button
|
||||
icon="pi pi-plus" class="mr-2" severity="primary" :label="t('add_new_network')"
|
||||
@click="addNewNetwork"
|
||||
/>
|
||||
<Button icon="pi pi-plus" class="mr-2" severity="primary" :label="t('add_new_network')"
|
||||
@click="addNewNetwork" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #center>
|
||||
<div class="min-w-80 mr-20">
|
||||
<Dropdown
|
||||
v-model="networkStore.curNetwork" :options="networkStore.networkList" :highlight-on-select="false"
|
||||
:placeholder="t('select_network')" class="w-full"
|
||||
>
|
||||
<Dropdown v-model="networkStore.curNetwork" :options="networkStore.networkList" :highlight-on-select="false"
|
||||
:placeholder="t('select_network')" class="w-full">
|
||||
<template #value="slotProps">
|
||||
<div class="flex items-start content-center">
|
||||
<div class="mr-3">
|
||||
<span>{{ slotProps.value.network_name }}</span>
|
||||
<span
|
||||
v-if="isRunning(slotProps.value.instance_id) && networkStore.instances[slotProps.value.instance_id].detail && (networkStore.instances[slotProps.value.instance_id].detail?.my_node_info.virtual_ipv4 !== '')"
|
||||
class="ml-3"
|
||||
>
|
||||
class="ml-3">
|
||||
{{ networkStore.instances[slotProps.value.instance_id].detail
|
||||
? networkStore.instances[slotProps.value.instance_id].detail?.my_node_info.virtual_ipv4 : '' }}
|
||||
</span>
|
||||
</div>
|
||||
<Tag
|
||||
class="my-auto" :severity="isRunning(slotProps.value.instance_id) ? 'success' : 'info'"
|
||||
:value="t(isRunning(slotProps.value.instance_id) ? 'network_running' : 'network_stopped')"
|
||||
/>
|
||||
<Tag class="my-auto" :severity="isRunning(slotProps.value.instance_id) ? 'success' : 'info'"
|
||||
:value="t(isRunning(slotProps.value.instance_id) ? 'network_running' : 'network_stopped')" />
|
||||
</div>
|
||||
</template>
|
||||
<template #option="slotProps">
|
||||
@@ -205,10 +218,8 @@ function isRunning(id: string) {
|
||||
<div class="mr-3">
|
||||
{{ t('network_name') }}: {{ slotProps.option.network_name }}
|
||||
</div>
|
||||
<Tag
|
||||
class="my-auto" :severity="isRunning(slotProps.option.instance_id) ? 'success' : 'info'"
|
||||
:value="t(isRunning(slotProps.option.instance_id) ? 'network_running' : 'network_stopped')"
|
||||
/>
|
||||
<Tag class="my-auto" :severity="isRunning(slotProps.option.instance_id) ? 'success' : 'info'"
|
||||
:value="t(isRunning(slotProps.option.instance_id) ? 'network_running' : 'network_stopped')" />
|
||||
</div>
|
||||
<div>{{ slotProps.option.public_server_url }}</div>
|
||||
</div>
|
||||
@@ -218,10 +229,8 @@ function isRunning(id: string) {
|
||||
</template>
|
||||
|
||||
<template #end>
|
||||
<Button
|
||||
icon="pi pi-cog" class="mr-2" severity="secondary" aria-haspopup="true" :label="t('settings')"
|
||||
aria-controls="overlay_setting_menu" @click="toggle_setting_menu"
|
||||
/>
|
||||
<Button icon="pi pi-cog" class="mr-2" severity="secondary" aria-haspopup="true" :label="t('settings')"
|
||||
aria-controls="overlay_setting_menu" @click="toggle_setting_menu" />
|
||||
<Menu id="overlay_setting_menu" ref="setting_menu" :model="setting_menu_items" :popup="true" />
|
||||
</template>
|
||||
</Toolbar>
|
||||
@@ -230,10 +239,8 @@ function isRunning(id: string) {
|
||||
<Stepper class="h-full overflow-y-auto" :active-step="activeStep">
|
||||
<StepperPanel :header="t('config_network')">
|
||||
<template #content="{ nextCallback }">
|
||||
<Config
|
||||
:instance-id="networkStore.curNetworkId" :config-invalid="messageBarSeverity !== Severity.None"
|
||||
@run-network="runNetworkCb($event, nextCallback)"
|
||||
/>
|
||||
<Config :instance-id="networkStore.curNetworkId" :config-invalid="messageBarSeverity !== Severity.None"
|
||||
@run-network="runNetworkCb($event, nextCallback)" />
|
||||
</template>
|
||||
</StepperPanel>
|
||||
<StepperPanel :header="t('running')">
|
||||
@@ -242,10 +249,8 @@ function isRunning(id: string) {
|
||||
<Status :instance-id="networkStore.curNetworkId" />
|
||||
</div>
|
||||
<div class="flex pt-4 justify-content-center">
|
||||
<Button
|
||||
:label="t('stop_network')" severity="danger" icon="pi pi-arrow-left"
|
||||
@click="stopNetworkCb(networkStore.curNetwork, prevCallback)"
|
||||
/>
|
||||
<Button :label="t('stop_network')" severity="danger" icon="pi pi-arrow-left"
|
||||
@click="stopNetworkCb(networkStore.curNetwork, prevCallback)" />
|
||||
</div>
|
||||
</template>
|
||||
</StepperPanel>
|
||||
|
||||
@@ -70,6 +70,7 @@ export const useNetworkStore = defineStore('networkStore', {
|
||||
this.instances[instanceId].error_msg = info.error_msg || ''
|
||||
this.instances[instanceId].detail = info
|
||||
}
|
||||
this.saveRunningInstanceIdsToLocalStorage()
|
||||
},
|
||||
|
||||
loadFromLocalStorage() {
|
||||
@@ -92,8 +93,22 @@ export const useNetworkStore = defineStore('networkStore', {
|
||||
saveToLocalStorage() {
|
||||
localStorage.setItem('networkList', JSON.stringify(this.networkList))
|
||||
},
|
||||
|
||||
saveRunningInstanceIdsToLocalStorage() {
|
||||
let instance_ids = Object.keys(this.instances).filter((instanceId) => this.instances[instanceId].running)
|
||||
localStorage.setItem('runningInstanceIds', JSON.stringify(instance_ids))
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
if (import.meta.hot)
|
||||
import.meta.hot.accept(acceptHMRUpdate(useNetworkStore as any, import.meta.hot))
|
||||
|
||||
export function loadRunningInstanceIdsFromLocalStorage(): string[] {
|
||||
try {
|
||||
return JSON.parse(localStorage.getItem('runningInstanceIds') || '[]')
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user