mirror of
https://github.com/priyanshujain/margin.git
synced 2026-10-05 04:27:03 +00:00
send app store builds to the store for updates
This commit is contained in:
1 parent
e8772e6699
commit
e8555c7ef9
10 files changed
+199
-54
No files matched your search
@@ -1,13 +1,12 @@
|
||||
import { useRef } from "react";
|
||||
import { useUpdater } from "../store/useUpdater";
|
||||
import { installUpdate, dismissUpdate } from "../updater";
|
||||
import { dismissUpdate } from "../updater";
|
||||
import { useEscapeLayer } from "../escape";
|
||||
import { useFocusTrap } from "../focus";
|
||||
import { Icon } from "./Icon";
|
||||
|
||||
const TITLES: Record<string, string> = {
|
||||
checking: "Check for Updates",
|
||||
available: "Update Available",
|
||||
downloading: "Updating margin",
|
||||
installing: "Updating margin",
|
||||
uptodate: "Check for Updates",
|
||||
@@ -16,8 +15,6 @@ const TITLES: Record<string, string> = {
|
||||
|
||||
export function UpdateDialog() {
|
||||
const phase = useUpdater((s) => s.phase);
|
||||
const version = useUpdater((s) => s.version);
|
||||
const notes = useUpdater((s) => s.notes);
|
||||
const downloaded = useUpdater((s) => s.downloaded);
|
||||
const total = useUpdater((s) => s.total);
|
||||
const error = useUpdater((s) => s.error);
|
||||
@@ -54,15 +51,6 @@ export function UpdateDialog() {
|
||||
|
||||
{phase === "uptodate" && <p className="confirm-text">margin is up to date.</p>}
|
||||
|
||||
{phase === "available" && (
|
||||
<>
|
||||
<p className="confirm-text">
|
||||
<strong>margin {version}</strong> is available.
|
||||
</p>
|
||||
{notes && <div className="update-notes">{notes}</div>}
|
||||
</>
|
||||
)}
|
||||
|
||||
{phase === "downloading" && (
|
||||
<>
|
||||
<div className={`update-progress${total > 0 ? "" : " indeterminate"}`}>
|
||||
@@ -87,17 +75,6 @@ export function UpdateDialog() {
|
||||
)}
|
||||
</div>
|
||||
|
||||
{phase === "available" && (
|
||||
<div className="panel-foot">
|
||||
<button className="btn-ghost" onClick={dismissUpdate}>
|
||||
Later
|
||||
</button>
|
||||
<button className="btn-primary" onClick={installUpdate}>
|
||||
Install & Restart
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{(phase === "uptodate" || phase === "error") && (
|
||||
<div className="panel-foot">
|
||||
<button className="btn-primary" onClick={dismissUpdate}>
|
||||
|
||||
@@ -4,7 +4,6 @@ import type { Update } from "@tauri-apps/plugin-updater";
|
||||
export type UpdatePhase =
|
||||
| "idle"
|
||||
| "checking"
|
||||
| "available"
|
||||
| "downloading"
|
||||
| "installing"
|
||||
| "uptodate"
|
||||
@@ -12,8 +11,6 @@ export type UpdatePhase =
|
||||
|
||||
interface UpdaterState {
|
||||
phase: UpdatePhase;
|
||||
version: string;
|
||||
notes: string;
|
||||
downloaded: number;
|
||||
total: number;
|
||||
error: string;
|
||||
@@ -24,8 +21,6 @@ interface UpdaterState {
|
||||
|
||||
const initial = {
|
||||
phase: "idle" as UpdatePhase,
|
||||
version: "",
|
||||
notes: "",
|
||||
downloaded: 0,
|
||||
total: 0,
|
||||
error: "",
|
||||
|
||||
+67
-14
@@ -1,8 +1,38 @@
|
||||
import { check } from "@tauri-apps/plugin-updater";
|
||||
import { relaunch } from "@tauri-apps/plugin-process";
|
||||
import { ask } from "@tauri-apps/plugin-dialog";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { getVersion } from "@tauri-apps/api/app";
|
||||
import { useUpdater } from "./store/useUpdater";
|
||||
|
||||
const DECLINED = "margin.update.declined";
|
||||
|
||||
type Channel = "direct" | "appstore" | "none";
|
||||
|
||||
let checking = false;
|
||||
let channel: Channel | null = null;
|
||||
|
||||
async function updateChannel() {
|
||||
if (!channel) channel = await invoke<Channel>("update_channel");
|
||||
return channel;
|
||||
}
|
||||
|
||||
function declined(version: string) {
|
||||
return localStorage.getItem(DECLINED) === version;
|
||||
}
|
||||
|
||||
function decline(version: string) {
|
||||
localStorage.setItem(DECLINED, version);
|
||||
}
|
||||
|
||||
function offer(version: string, current: string, okLabel: string) {
|
||||
return ask(`margin ${version} is available. You have ${current}.`, {
|
||||
title: "A new version of margin is available",
|
||||
kind: "info",
|
||||
okLabel,
|
||||
cancelLabel: "Later",
|
||||
});
|
||||
}
|
||||
|
||||
export async function checkForUpdates(silent: boolean) {
|
||||
if (checking) return;
|
||||
@@ -10,20 +40,10 @@ export async function checkForUpdates(silent: boolean) {
|
||||
const store = useUpdater.getState();
|
||||
if (!silent) store.set({ phase: "checking", error: "" });
|
||||
try {
|
||||
const update = await check();
|
||||
if (!update) {
|
||||
store.set(silent ? { phase: "idle" } : { phase: "uptodate" });
|
||||
return;
|
||||
}
|
||||
store.set({
|
||||
phase: "available",
|
||||
update,
|
||||
version: update.version,
|
||||
notes: update.body ?? "",
|
||||
downloaded: 0,
|
||||
total: 0,
|
||||
error: "",
|
||||
});
|
||||
const target = await updateChannel();
|
||||
if (target === "direct") await checkDirect(silent);
|
||||
else if (target === "appstore") await checkAppStore(silent);
|
||||
else store.set(silent ? { phase: "idle" } : { phase: "uptodate" });
|
||||
} catch (err) {
|
||||
store.set(silent ? { phase: "idle" } : { phase: "error", error: String(err) });
|
||||
} finally {
|
||||
@@ -31,6 +51,39 @@ export async function checkForUpdates(silent: boolean) {
|
||||
}
|
||||
}
|
||||
|
||||
async function checkDirect(silent: boolean) {
|
||||
const store = useUpdater.getState();
|
||||
const update = await check();
|
||||
if (!update) {
|
||||
store.set(silent ? { phase: "idle" } : { phase: "uptodate" });
|
||||
return;
|
||||
}
|
||||
if (silent && declined(update.version)) {
|
||||
store.set({ phase: "idle" });
|
||||
return;
|
||||
}
|
||||
store.set({ phase: "idle", update });
|
||||
if (await offer(update.version, update.currentVersion, "Install Update")) await installUpdate();
|
||||
else decline(update.version);
|
||||
}
|
||||
|
||||
async function checkAppStore(silent: boolean) {
|
||||
const store = useUpdater.getState();
|
||||
const release = await invoke<{ version: string; trackId: number } | null>("appstore_latest");
|
||||
if (!release) {
|
||||
store.set(silent ? { phase: "idle" } : { phase: "uptodate" });
|
||||
return;
|
||||
}
|
||||
if (silent && declined(release.version)) {
|
||||
store.set({ phase: "idle" });
|
||||
return;
|
||||
}
|
||||
store.set({ phase: "idle" });
|
||||
if (await offer(release.version, await getVersion(), "Open App Store"))
|
||||
await invoke("open_appstore", { trackId: release.trackId });
|
||||
else decline(release.version);
|
||||
}
|
||||
|
||||
export async function installUpdate() {
|
||||
const { update, phase } = useUpdater.getState();
|
||||
if (!update || phase === "downloading" || phase === "installing") return;
|
||||
|
||||
Reference in new issue
Block a user