add update service

This commit is contained in:
2026-04-01 20:29:47 -07:00
parent d0863b675e
commit 58adf490cc
4 changed files with 59 additions and 18 deletions

View File

@@ -897,6 +897,7 @@ function Flow() {
const [executingNodeId, setExecutingNodeId] = useState<string | null>(null);
const [helpTabs, setHelpTabs] = useState<{ label: string; type?: string; content: string | null }[]>([]);
const [activeHelpTab, setActiveHelpTab] = useState<string | null>(null);
const [updateInfo, setUpdateInfo] = useState<{ latest: string; url: string } | null>(null);
const flowContainerRef = useRef<HTMLDivElement | null>(null);
const panTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
@@ -918,6 +919,19 @@ function Flow() {
const reactFlow = useReactFlow<TonoNode, TonoEdge>() as ReturnType<typeof useReactFlow<TonoNode, TonoEdge>> & { updateNodeInternals: (id: string) => void };
const undoRedo = useUndoRedo();
// ── Update check (native builds only) ──────────────────────────────
useEffect(() => {
if (!(window as any).pywebview) return;
fetch('/check-update')
.then((r) => r.ok ? r.json() : null)
.then((data) => {
if (data?.update_available && data.latest) {
setUpdateInfo({ latest: data.latest, url: data.url });
}
})
.catch(() => {});
}, []);
const scheduleAutoRun = useCallback(() => {
if (autoRunTimer.current) clearTimeout(autoRunTimer.current);
autoRunTimer.current = setTimeout(() => autoRunRef.current?.(), 300);
@@ -3179,6 +3193,15 @@ function Flow() {
<div className={`status-bar ${status.level}`}>{status.text}</div>
</div>
{updateInfo && (
<div className="update-banner">
tono {updateInfo.latest} is available.
{' '}
<a href={updateInfo.url} target="_blank" rel="noopener noreferrer">Download</a>
<button className="update-banner-dismiss" onClick={() => setUpdateInfo(null)} title="Dismiss"></button>
</div>
)}
{/* React Flow canvas */}
<div
ref={flowContainerRef}

View File

@@ -212,6 +212,34 @@ html, body, #root {
.status-bar.info { color: var(--accent-light); }
.status-bar.error { color: var(--error-text); background: var(--error-bg); }
.update-banner {
background: var(--accent);
color: #fff;
text-align: center;
padding: 4px 12px;
font-size: 12px;
position: relative;
}
.update-banner a {
color: #fff;
font-weight: 600;
text-decoration: underline;
}
.update-banner-dismiss {
position: absolute;
right: 8px;
top: 50%;
transform: translateY(-50%);
background: none;
border: none;
color: #fff;
cursor: pointer;
font-size: 13px;
padding: 2px 4px;
opacity: 0.7;
}
.update-banner-dismiss:hover { opacity: 1; }
/* ── React Flow container ──────────────────────────────────────────── */
.flow-container {
flex: 1;