fix: bundle libodbc into macOS app and improve update UX
- Bundle libodbc.2.dylib into .app/Contents/Frameworks/ via Tauri's macOS frameworks config to fix "app can't be opened" on macOS - Replace relaunch() with exit(0) to avoid Tauri restart bug (#11392) - Lock update dialog during download and after install - Render release notes as markdown
This commit is contained in:
1 parent
d4d0bb726e
commit
4973912666
7 files changed
+47
-10
No files matched your search
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { Marked } from "marked";
|
||||
import { Loader2 } from "lucide-vue-next";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
||||
@@ -8,7 +10,7 @@ import { isTauriRuntime } from "@/lib/tauriRuntime";
|
||||
|
||||
const open = defineModel<boolean>("open", { required: true });
|
||||
|
||||
defineProps<{
|
||||
const props = defineProps<{
|
||||
updateInfo: UpdateInfo | null;
|
||||
updateCheckMessage: string;
|
||||
isDownloadingUpdate: boolean;
|
||||
@@ -24,11 +26,30 @@ const emit = defineEmits<{
|
||||
|
||||
const { t } = useI18n();
|
||||
const isDesktop = isTauriRuntime();
|
||||
|
||||
const marked = new Marked({ breaks: true, gfm: true });
|
||||
|
||||
const renderedNotes = computed(() => {
|
||||
if (!props.updateInfo?.release_notes) return "";
|
||||
return marked.parse(props.updateInfo.release_notes) as string;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Dialog v-model:open="open">
|
||||
<DialogContent class="sm:max-w-[520px]">
|
||||
<DialogContent
|
||||
class="sm:max-w-[520px]"
|
||||
@interact-outside="
|
||||
(e: Event) => {
|
||||
if (isDownloadingUpdate || updateReady) e.preventDefault();
|
||||
}
|
||||
"
|
||||
@escape-key-down="
|
||||
(e: Event) => {
|
||||
if (isDownloadingUpdate || updateReady) e.preventDefault();
|
||||
}
|
||||
"
|
||||
>
|
||||
<DialogHeader>
|
||||
<DialogTitle>{{ updateInfo?.update_available ? t("updates.availableTitle") : t("updates.title") }}</DialogTitle>
|
||||
</DialogHeader>
|
||||
@@ -46,10 +67,9 @@ const isDesktop = isTauriRuntime();
|
||||
</p>
|
||||
<div
|
||||
v-if="updateInfo?.update_available && updateInfo.release_notes"
|
||||
class="max-h-48 overflow-auto rounded-md border bg-muted/30 p-3 text-xs whitespace-pre-wrap"
|
||||
>
|
||||
{{ updateInfo.release_notes }}
|
||||
</div>
|
||||
class="max-h-48 overflow-auto rounded-md border bg-muted/30 p-3 text-xs [&_h1]:text-sm [&_h1]:font-semibold [&_h1]:mb-1 [&_h2]:text-sm [&_h2]:font-semibold [&_h2]:mb-1 [&_h3]:text-xs [&_h3]:font-semibold [&_h3]:mb-1 [&_ul]:list-disc [&_ul]:pl-4 [&_ul]:my-1 [&_ol]:list-decimal [&_ol]:pl-4 [&_ol]:my-1 [&_li]:my-0.5 [&_p]:my-1 [&_code]:bg-muted [&_code]:px-1 [&_code]:py-0.5 [&_code]:rounded [&_code]:text-[11px] [&_a]:text-primary [&_a]:underline"
|
||||
v-html="renderedNotes"
|
||||
/>
|
||||
<p v-if="!isDesktop && updateInfo?.update_available" class="text-xs text-muted-foreground">
|
||||
Docker 用户请运行
|
||||
<code class="bg-muted px-1 py-0.5 rounded text-[11px]">docker compose pull && docker compose up -d</code>
|
||||
@@ -57,11 +77,16 @@ const isDesktop = isTauriRuntime();
|
||||
</p>
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button variant="outline" @click="open = false">{{ t("dangerDialog.cancel") }}</Button>
|
||||
<Button v-if="!isDownloadingUpdate && !updateReady" variant="outline" @click="open = false">{{
|
||||
t("dangerDialog.cancel")
|
||||
}}</Button>
|
||||
<template v-if="updateInfo?.update_available">
|
||||
<Button variant="outline" @click="emit('open-latest-release')">{{ t("updates.openRelease") }}</Button>
|
||||
<template v-if="isDesktop">
|
||||
<Button v-if="updateReady" @click="emit('restart')">{{ t("updates.restart") }}</Button>
|
||||
<div v-if="updateReady" class="flex flex-col items-end gap-1">
|
||||
<Button @click="emit('restart')">{{ t("updates.exitAndUpdate") }}</Button>
|
||||
<span class="text-xs text-muted-foreground">{{ t("updates.reopenHint") }}</span>
|
||||
</div>
|
||||
<Button v-else-if="isDownloadingUpdate" disabled>
|
||||
<Loader2 class="h-4 w-4 animate-spin" />
|
||||
{{ t("updates.downloading", { progress: downloadProgress }) }}
|
||||
|
||||
@@ -91,8 +91,8 @@ export function useAppUpdater() {
|
||||
|
||||
async function restartApp() {
|
||||
if (!isTauriRuntime()) return;
|
||||
const { relaunch } = await import("@tauri-apps/plugin-process");
|
||||
await relaunch();
|
||||
const { exit } = await import("@tauri-apps/plugin-process");
|
||||
await exit(0);
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@@ -52,6 +52,8 @@ export default {
|
||||
downloading: "Downloading {progress}%",
|
||||
downloadFailed: "Update download failed: {error}",
|
||||
restart: "Restart Now",
|
||||
exitAndUpdate: "Exit & Update",
|
||||
reopenHint: "Changes will take effect when you reopen the app",
|
||||
},
|
||||
sidebar: {
|
||||
connections: "CONNECTIONS",
|
||||
|
||||
@@ -51,6 +51,8 @@ export default {
|
||||
downloading: "下载中 {progress}%",
|
||||
downloadFailed: "更新下载失败:{error}",
|
||||
restart: "立即重启",
|
||||
exitAndUpdate: "退出并更新",
|
||||
reopenHint: "更新将在重新打开应用后生效",
|
||||
},
|
||||
sidebar: {
|
||||
connections: "连接",
|
||||
|
||||
Reference in new issue
Block a user