diff --git a/index.html b/index.html
index b15c69d..765bc41 100644
--- a/index.html
+++ b/index.html
@@ -4,6 +4,7 @@
+
Synapsis
diff --git a/src/App.css b/src/App.css
index ac034e0..ec97652 100644
--- a/src/App.css
+++ b/src/App.css
@@ -12,7 +12,7 @@ input:focus-visible { outline: 0; }
.signal-panel { position: relative; min-width: 0; overflow: hidden; border-right: 1px solid rgba(255,255,255,.1); }
.signal-field { position: absolute; inset: 0; width: 100%; height: 100%; }
.signal-shade { position: absolute; inset: 0; background: radial-gradient(circle at 55% 45%, transparent 0, rgba(0,0,0,.08) 38%, rgba(0,0,0,.74) 100%), linear-gradient(180deg, rgba(0,0,0,.12), rgba(0,0,0,.4)); pointer-events: none; }
-.panel-brand, .sidebar-brand, .launch-mark { position: absolute; top: 52px; left: 48px; z-index: 2; display: flex; align-items: center; }
+.panel-brand, .sidebar-brand { position: absolute; top: 52px; left: 48px; z-index: 2; display: flex; align-items: center; }
.wordmark { display: block; width: auto; object-fit: contain; }
.panel-wordmark { width: 146px; height: 28px; }
.signal-copy { position: absolute; z-index: 2; left: 48px; right: 36px; bottom: 104px; }
@@ -65,11 +65,20 @@ label { display: block; margin: 0 0 9px; color: rgba(255,255,255,.75); font-size
.spinner.dark { width: 15px; height: 15px; border-color: rgba(0,0,0,.18); border-top-color: #111; }
@keyframes spin { to { transform: rotate(360deg); } }
-.launch-screen { position: relative; width: 100%; height: 100%; display: grid; place-items: center; background: #060707; }
-.launch-screen::after { content: ""; position: absolute; inset: 0; background: radial-gradient(circle, transparent, rgba(0,0,0,.6)); }
-.launch-mark { left: 50%; top: 50%; transform: translate(-50%, -50%); }
-.launch-wordmark { width: 176px; height: 33px; }
-.launch-screen > .spinner { position: absolute; z-index: 3; bottom: 12%; }
+.launch-screen { position: relative; width: 100%; height: 100%; display: grid; place-items: center; overflow: hidden; background: #060707; }
+.launch-screen::after { content: ""; position: absolute; inset: 0; background: radial-gradient(circle at 50% 48%, rgba(20,22,22,.18), rgba(0,0,0,.72) 72%); pointer-events: none; }
+.launch-content { position: relative; z-index: 3; width: 260px; display: flex; flex-direction: column; align-items: center; transform: translateY(-3px); }
+.launch-wordmark { width: 204px; height: 38px; }
+.connecting-dots { width: 168px; height: 34px; margin-top: 31px; overflow: visible; }
+.connecting-line { fill: none; stroke: rgba(255,255,255,.18); stroke-width: 1; stroke-dasharray: .18 .08; animation: connect-line 2.4s ease-in-out infinite; }
+.connecting-dot { fill: rgba(255,255,255,.28); transform-box: fill-box; transform-origin: center; animation: connect-dot 2.4s ease-in-out infinite; }
+.connecting-dot.dot-2 { animation-delay: .16s; }
+.connecting-dot.dot-3 { animation-delay: .32s; }
+.connecting-dot.dot-4 { animation-delay: .48s; }
+.connecting-dot.dot-5 { animation-delay: .64s; }
+.launch-content p { margin: 18px 0 0; color: rgba(255,255,255,.34); font: 500 8px/1 "Roboto Mono", monospace; letter-spacing: 2.2px; }
+@keyframes connect-line { 0%, 18% { stroke-dashoffset: 1; opacity: .24; } 58%, 78% { stroke-dashoffset: 0; opacity: .9; } 100% { stroke-dashoffset: -1; opacity: .24; } }
+@keyframes connect-dot { 0%, 16%, 100% { fill: rgba(255,255,255,.24); filter: none; transform: scale(.75); } 38%, 62% { fill: #fff; filter: drop-shadow(0 0 5px rgba(255,255,255,.9)); transform: scale(1.25); } 82% { fill: rgba(255,255,255,.42); transform: scale(.9); } }
.app-shell { width: 100%; height: 100%; display: grid; grid-template-columns: 238px 1fr; background: #0a0b0b; }
.sidebar { position: relative; display: flex; flex-direction: column; padding: 104px 18px 18px; border-right: 1px solid rgba(255,255,255,.09); background: #080909; }
diff --git a/src/App.tsx b/src/App.tsx
index 8066c53..9b360e6 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -75,6 +75,30 @@ function Wordmark({ className = "" }: { className?: string }) {
return
;
}
+function ConnectingDots() {
+ return (
+
+ );
+}
+
+function LoadingScreen() {
+ return (
+
+
+
+
+
+
CONNECTING TO YOUR NETWORK
+
+
+ );
+}
+
function SignalField() {
const canvasRef = useRef(null);
@@ -260,10 +284,12 @@ function App() {
const savedNodeUrl = savedNode;
async function restore() {
+ let handedOffToWebApp = false;
try {
const hasWebSession = await invoke("has_web_session", { nodeUrl: savedNodeUrl });
if (hasWebSession) {
await openNodeWebApp(savedNodeUrl);
+ handedOffToWebApp = true;
return;
}
@@ -273,13 +299,14 @@ function App() {
setUser(connection.user);
if (connection.user) {
await openNodeWebApp(connection.nodeUrl);
+ handedOffToWebApp = true;
} else {
setScreen("login");
}
} catch {
setScreen("node");
} finally {
- setBootstrapping(false);
+ if (!handedOffToWebApp) setBootstrapping(false);
}
}
void restore();
@@ -369,7 +396,7 @@ function App() {
}
if (bootstrapping) {
- return
;
+ return ;
}
if (screen === "home" && user) {