feat: restructure settings into identity, server, backup and advanced tabs
Drops the per-server pin list down to the one server your account is bound to, adds an enforced network timeout, and replaces the global status toast inside settings with inline feedback and a reusable confirm dialog for rotate/log out. Mail-fetching preferences move into the server tab; the now-superseded claim/recall forms are gone since onboarding covers both.
This commit is contained in:
parent
fb0ca5c8cc
commit
84397a3fdd
6 changed files with 270 additions and 334 deletions
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
const BRIDGE = `${location.protocol === "https:" ? "wss" : "ws"}://${location.host}`;
|
||||
|
||||
export function connectStream(host, port) {
|
||||
export function connectStream(host, port, timeoutMs = 0) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const socket = new WebSocket(`${BRIDGE}/tcp/${host}/${port}`);
|
||||
socket.binaryType = "arraybuffer";
|
||||
|
|
@ -14,8 +14,15 @@ export function connectStream(host, port) {
|
|||
onData: null,
|
||||
onClose: null,
|
||||
};
|
||||
socket.onopen = () => resolve(stream);
|
||||
socket.onerror = () => reject(new Error(`cannot reach the bridge at ${BRIDGE}`));
|
||||
// Settings' timeout only governs this; the WebSocket may otherwise never
|
||||
// fire open, error, or close if something between here and the bridge
|
||||
// just drops packets.
|
||||
const timer = timeoutMs ? setTimeout(() => {
|
||||
socket.close();
|
||||
reject(new Error(`could not reach ${host}:${port} within ${timeoutMs / 1000}s`));
|
||||
}, timeoutMs) : null;
|
||||
socket.onopen = () => { clearTimeout(timer); resolve(stream); };
|
||||
socket.onerror = () => { clearTimeout(timer); reject(new Error(`cannot reach the bridge at ${BRIDGE}`)); };
|
||||
socket.onmessage = event => stream.onData?.(new Uint8Array(event.data));
|
||||
socket.onclose = () => stream.onClose?.();
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue