mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-27 00:05:39 +00:00
feat: add updater release infrastructure
This commit is contained in:
+82
@@ -1,4 +1,6 @@
|
||||
import { Gift } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "sonner";
|
||||
import { CountdownOverlay } from "./components/countdown/CountdownOverlay";
|
||||
import { LaunchWindow } from "./components/launch/LaunchWindow";
|
||||
import { SourceSelector } from "./components/launch/SourceSelector";
|
||||
@@ -9,6 +11,13 @@ import { useI18n } from "./contexts/I18nContext";
|
||||
import { ShortcutsProvider } from "./contexts/ShortcutsContext";
|
||||
import { loadAllCustomFonts } from "./lib/customFonts";
|
||||
|
||||
const UPDATE_TOAST_ID = "recordly-update-ready";
|
||||
|
||||
function formatDelayHours(delayMs: number) {
|
||||
const hours = Math.max(1, Math.round(delayMs / (60 * 60 * 1000)));
|
||||
return `${hours}h`;
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
const [windowType, setWindowType] = useState("");
|
||||
const { locale, t } = useI18n();
|
||||
@@ -40,6 +49,79 @@ export default function App() {
|
||||
windowType === "editor" ? t("app.editorTitle", "Recordly Editor") : t("app.name", "Recordly");
|
||||
}, [windowType, locale, t]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
windowType === "countdown" ||
|
||||
windowType === "source-selector" ||
|
||||
typeof window.electronAPI?.onUpdateReadyToast !== "function"
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
return window.electronAPI.onUpdateReadyToast((payload) => {
|
||||
toast.custom(
|
||||
(toastInstance) => (
|
||||
<div className="pointer-events-auto flex w-[390px] items-start gap-3 rounded-2xl border border-sky-300/20 bg-[#0d1117]/95 p-4 text-white shadow-2xl shadow-black/40 backdrop-blur-xl">
|
||||
<div className="mt-0.5 flex h-10 w-10 flex-shrink-0 items-center justify-center rounded-2xl bg-sky-400/15 text-sky-300">
|
||||
<Gift className="h-5 w-5" />
|
||||
</div>
|
||||
<div className="min-w-0 flex-1">
|
||||
<div className="flex items-center gap-2">
|
||||
<p className="text-sm font-semibold tracking-tight">
|
||||
{payload.isPreview ? "Update Toast Preview" : `Recordly ${payload.version} is ready`}
|
||||
</p>
|
||||
{payload.isPreview ? (
|
||||
<span className="rounded-full border border-sky-300/20 bg-sky-400/10 px-2 py-0.5 text-[10px] font-medium uppercase tracking-[0.18em] text-sky-200">
|
||||
Dev
|
||||
</span>
|
||||
) : null}
|
||||
</div>
|
||||
<p className="mt-1 text-sm leading-5 text-white/70">{payload.detail}</p>
|
||||
<div className="mt-3 flex flex-wrap items-center gap-2">
|
||||
<button
|
||||
type="button"
|
||||
onClick={async () => {
|
||||
toast.dismiss(toastInstance);
|
||||
if (payload.isPreview) {
|
||||
toast.success("Preview only. No real update was installed.");
|
||||
return;
|
||||
}
|
||||
|
||||
await window.electronAPI.installDownloadedUpdate();
|
||||
}}
|
||||
className="rounded-xl bg-sky-400 px-3 py-2 text-xs font-semibold text-[#031a2c] transition-colors hover:bg-sky-300"
|
||||
>
|
||||
Update Now
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={async () => {
|
||||
toast.dismiss(toastInstance);
|
||||
if (payload.isPreview) {
|
||||
toast.success(`Preview dismissed. We'll show it again in ${formatDelayHours(payload.delayMs)}.`);
|
||||
return;
|
||||
}
|
||||
|
||||
const result = await window.electronAPI.deferDownloadedUpdate(payload.delayMs);
|
||||
if (result.success) {
|
||||
toast.success(`Okay, we'll remind you in ${formatDelayHours(payload.delayMs)}.`);
|
||||
} else if (result.message) {
|
||||
toast.error(result.message);
|
||||
}
|
||||
}}
|
||||
className="rounded-xl border border-white/10 bg-white/5 px-3 py-2 text-xs font-medium text-white/85 transition-colors hover:bg-white/10"
|
||||
>
|
||||
Update Later ({formatDelayHours(payload.delayMs)})
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
{ id: UPDATE_TOAST_ID, duration: Number.POSITIVE_INFINITY },
|
||||
);
|
||||
});
|
||||
}, [windowType]);
|
||||
|
||||
switch (windowType) {
|
||||
case "hud-overlay":
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user