Replace the website notification card with native desktop notification handling

Hop-State: A_06FPG6WWRGQW1NG5ZQZRSY0
Hop-Proposal: R_06FPG6WDJG2WNB21CHD30R0
Hop-Task: T_06FPG5CWT7W6DEF2HVENX20
Hop-Attempt: AT_06FPG5CWT7BEF2WDEP0BJQG
This commit is contained in:
2026-07-15 16:27:47 -07:00
committed by Hop
parent 1e36c03430
commit 4a408edce8
7 changed files with 609 additions and 18 deletions
+20 -7
View File
@@ -1,5 +1,6 @@
import { FormEvent, useEffect, useRef, useState } from "react";
import { invoke, isTauri } from "@tauri-apps/api/core";
import { isPermissionGranted, requestPermission } from "@tauri-apps/plugin-notification";
import "./App.css";
type Screen = "node" | "login" | "register" | "home";
@@ -44,6 +45,17 @@ function displayHost(url: string) {
}
}
async function openNodeWebApp(nodeUrl: string) {
try {
if (!(await isPermissionGranted())) {
await requestPermission();
}
} catch (error) {
console.warn("Could not prepare native notifications:", error);
}
await invoke("open_web_app", { nodeUrl });
}
function Icon({ name, size = 20 }: { name: string; size?: number }) {
const paths: Record<string, React.ReactNode> = {
arrow: <><path d="M5 12h14"/><path d="m13 6 6 6-6 6"/></>,
@@ -238,21 +250,22 @@ function App() {
setBootstrapping(false);
return;
}
const savedNodeUrl = savedNode;
async function restore() {
try {
const hasWebSession = await invoke<boolean>("has_web_session", { nodeUrl: savedNode });
const hasWebSession = await invoke<boolean>("has_web_session", { nodeUrl: savedNodeUrl });
if (hasWebSession) {
await invoke("open_web_app", { nodeUrl: savedNode });
await openNodeWebApp(savedNodeUrl);
return;
}
const connection = await invoke<Connection>("connect", { nodeUrl: savedNode });
const connection = await invoke<Connection>("connect", { nodeUrl: savedNodeUrl });
setNodeUrl(connection.nodeUrl);
setNode(connection.node);
setNodeInput(displayHost(connection.nodeUrl));
setUser(connection.user);
if (connection.user) {
await invoke("open_web_app", { nodeUrl: connection.nodeUrl });
await openNodeWebApp(connection.nodeUrl);
} else {
setScreen("login");
}
@@ -280,7 +293,7 @@ function App() {
setNode(connection.node);
setUser(connection.user);
if (connection.user) {
await invoke("open_web_app", { nodeUrl: connection.nodeUrl });
await openNodeWebApp(connection.nodeUrl);
} else {
setScreen("login");
}
@@ -303,7 +316,7 @@ function App() {
password: data.get("password"),
});
setUser(response.user);
await invoke("open_web_app", { nodeUrl });
await openNodeWebApp(nodeUrl);
} catch (caught) {
setError(readableError(caught));
} finally {
@@ -330,7 +343,7 @@ function App() {
password,
});
setUser(response.user);
await invoke("open_web_app", { nodeUrl });
await openNodeWebApp(nodeUrl);
} catch (caught) {
setError(readableError(caught));
} finally {