feat(front): check update at startup

This commit is contained in:
AkiChase 2024-05-06 19:43:27 +08:00
parent 35e2609db2
commit d07ef6f642
5 changed files with 97 additions and 76 deletions

View File

@ -123,4 +123,10 @@ onMounted(async () => {
.n-scrollbar-content { .n-scrollbar-content {
height: 100%; height: 100%;
} }
.n-spin-content,
.n-spin-container {
width: 100%;
height: 100%;
}
</style> </style>

View File

@ -1,6 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { onActivated } from "vue"; import { h, onActivated, onMounted } from "vue";
import { NDialog, useMessage } from "naive-ui"; import { NDialog, useDialog, useMessage } from "naive-ui";
import { useGlobalStore } from "../store/global"; import { useGlobalStore } from "../store/global";
import { onBeforeRouteLeave, useRouter } from "vue-router"; import { onBeforeRouteLeave, useRouter } from "vue-router";
import { import {
@ -11,10 +11,14 @@ import {
updateScreenSizeAndMaskArea, updateScreenSizeAndMaskArea,
} from "../hotkey"; } from "../hotkey";
import { KeySteeringWheel } from "../keyMappingConfig"; import { KeySteeringWheel } from "../keyMappingConfig";
import { getVersion } from "@tauri-apps/api/app";
import { fetch } from "@tauri-apps/plugin-http";
import { open } from "@tauri-apps/plugin-shell";
const store = useGlobalStore(); const store = useGlobalStore();
const router = useRouter(); const router = useRouter();
const message = useMessage(); const message = useMessage();
const dialog = useDialog();
onBeforeRouteLeave(() => { onBeforeRouteLeave(() => {
if (store.controledDevice) { if (store.controledDevice) {
@ -45,9 +49,54 @@ onActivated(async () => {
} }
}); });
onMounted(() => {
store.checkUpdate = checkUpdate;
checkUpdate();
});
function toStartServer() { function toStartServer() {
router.replace({ name: "device" }); router.replace({ name: "device" });
} }
function renderUpdateInfo(content: string) {
const pList = content.split("\r\n").map((line: string) => h("p", line));
return h("div", { style: "margin: 20px 0" }, pList);
}
async function checkUpdate() {
try {
const curVersion = await getVersion();
const res = await fetch(
"https://api.github.com/repos/AkiChase/scrcpy-mask/releases/latest",
{
connectTimeout: 5000,
}
);
if (res.status !== 200) {
message.error("检查更新失败");
} else {
const data = await res.json();
const latestVersion = (data.tag_name as string).slice(1);
if (latestVersion <= curVersion) {
message.success(`最新版本: ${latestVersion},当前已是最新版本`);
return;
}
const body = data.body as string;
dialog.info({
title: `最新版本:${data.tag_name}`,
content: () => renderUpdateInfo(body),
positiveText: "前往发布页",
negativeText: "取消",
onPositiveClick: () => {
open(data.html_url);
},
});
}
} catch (e) {
console.error(e);
message.error("检查更新失败");
}
}
</script> </script>
<template> <template>
@ -184,3 +233,4 @@ function toStartServer() {
} }
} }
</style> </style>
h, import { getVersion } from "@tauri-apps/api/app";

View File

@ -1,22 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { import { NFlex, NH4, NButton, NIcon, NP } from "naive-ui";
NFlex,
NH4,
NButton,
NIcon,
NP,
useMessage,
useDialog,
} from "naive-ui";
import { LogoGithub, Planet } from "@vicons/ionicons5"; import { LogoGithub, Planet } from "@vicons/ionicons5";
import { open } from "@tauri-apps/plugin-shell"; import { open } from "@tauri-apps/plugin-shell";
import { fetch } from "@tauri-apps/plugin-http";
import { getVersion } from "@tauri-apps/api/app"; import { getVersion } from "@tauri-apps/api/app";
import { h, onMounted, ref } from "vue"; import { onMounted, ref } from "vue";
import { useGlobalStore } from "../../store/global"; import { useGlobalStore } from "../../store/global";
const message = useMessage();
const dialog = useDialog();
const store = useGlobalStore(); const store = useGlobalStore();
const appVersion = ref(""); const appVersion = ref("");
@ -28,46 +17,10 @@ function opendWebsite(url: string) {
open(url); open(url);
} }
function renderUpdateInfo(content: string) {
const pList = content.split("\r\n").map((line: string) => h("p", line));
return h("div", { style: "margin: 20px 0" }, pList);
}
async function checkUpdate() { async function checkUpdate() {
store.showLoading(); store.showLoading();
try { await store.checkUpdate();
const res = await fetch(
"https://api.github.com/repos/AkiChase/scrcpy-mask/releases/latest",
{
connectTimeout: 5000,
}
);
store.hideLoading(); store.hideLoading();
if (res.status !== 200) {
message.error("检查更新失败");
} else {
const data = await res.json();
const latestVersion = (data.tag_name as string).slice(1);
if (latestVersion <= appVersion.value) {
message.success(`最新版本: ${latestVersion},当前已是最新版本`);
return;
}
const body = data.body as string;
dialog.info({
title: `最新版本:${data.tag_name}`,
content: () => renderUpdateInfo(body),
positiveText: "前往发布页",
negativeText: "取消",
onPositiveClick: () => {
opendWebsite(data.html_url);
},
});
}
} catch (e) {
store.hideLoading();
console.error(e);
message.error("检查更新失败");
}
} }
</script> </script>

View File

@ -3,11 +3,15 @@ import Basic from "./Basic.vue";
import Script from "./Script.vue"; import Script from "./Script.vue";
import Mask from "./Mask.vue"; import Mask from "./Mask.vue";
import About from "./About.vue"; import About from "./About.vue";
import { NTabs, NTabPane, NScrollbar } from "naive-ui"; import { NTabs, NTabPane, NScrollbar, NSpin } from "naive-ui";
import { useGlobalStore } from "../../store/global";
const store = useGlobalStore();
</script> </script>
<template> <template>
<div class="setting"> <div class="setting">
<NSpin :show="store.showLoadingRef">
<NTabs type="line" animated placement="left" default-value="basic"> <NTabs type="line" animated placement="left" default-value="basic">
<NTabPane tab="基本设置" name="basic"> <NTabPane tab="基本设置" name="basic">
<NScrollbar> <NScrollbar>
@ -30,6 +34,7 @@ import { NTabs, NTabPane, NScrollbar } from "naive-ui";
</NScrollbar> </NScrollbar>
</NTabPane> </NTabPane>
</NTabs> </NTabs>
</NSpin>
</div> </div>
</template> </template>
@ -41,6 +46,10 @@ import { NTabs, NTabPane, NScrollbar } from "naive-ui";
overflow-y: auto; overflow-y: auto;
display: flex; display: flex;
.n-tabs{
height: 100%;
}
.n-tab-pane { .n-tab-pane {
padding: 0; padding: 0;
} }

View File

@ -39,6 +39,8 @@ export const useGlobalStore = defineStore("global", () => {
show: true, show: true,
}); });
let checkUpdate: () => Promise<void> = async () => {};
function applyEditKeyMappingList(): boolean { function applyEditKeyMappingList(): boolean {
const set = new Set<string>(); const set = new Set<string>();
for (const keyMapping of editKeyMappingList.value) { for (const keyMapping of editKeyMappingList.value) {
@ -91,5 +93,6 @@ export const useGlobalStore = defineStore("global", () => {
applyEditKeyMappingList, applyEditKeyMappingList,
resetEditKeyMappingList, resetEditKeyMappingList,
setKeyMappingIndex, setKeyMappingIndex,
checkUpdate,
}; };
}); });