Skip to content

Commit 5cb1ec0

Browse files
committed
don't show login when reloginToken exists
1 parent f779c11 commit 5cb1ec0

4 files changed

Lines changed: 85 additions & 7 deletions

File tree

frontend/src/app.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { useEffect } from "preact/hooks";
2-
import { connect, currentUser, fetchTeams } from "./store";
2+
import { connect, currentUser, fetchTeams, authError } from "./store";
33
import { Auth } from "./components/Auth";
44
import { TalkList } from "./components/TalkList";
5+
import { Loading } from "./components/Loading";
56
import "./mopad.css";
67

78
export function App() {
@@ -10,5 +11,12 @@ export function App() {
1011
connect();
1112
}, []);
1213

14+
const hasToken = !!localStorage.getItem("reloginToken");
15+
const isRestoring = hasToken && !currentUser.value && !authError.value;
16+
17+
if (isRestoring) {
18+
return <Loading />;
19+
}
20+
1321
return <>{currentUser.value ? <TalkList /> : <Auth />}</>;
1422
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export function Loading() {
2+
return (
3+
<div id="loading" className="center">
4+
<h1>MOPAD</h1>
5+
<div className="spinner"></div>
6+
<div>Booting chestboard...</div>
7+
</div>
8+
);
9+
}

frontend/src/mopad.css

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,3 +598,43 @@ body.center,
598598
width: calc((96rem - 7rem) / 6);
599599
}
600600
}
601+
602+
#loading {
603+
display: flex;
604+
flex-direction: column;
605+
align-items: center;
606+
justify-content: center; /* Added for better centering */
607+
padding: 2rem 1rem;
608+
height: 100vh; /* Full height for the loading screen */
609+
610+
& h1 {
611+
font-size: 3rem;
612+
font-weight: 500;
613+
margin-bottom: 1rem;
614+
}
615+
& div {
616+
font-size: 0.85rem;
617+
color: var(--text-muted);
618+
font-weight: 500;
619+
}
620+
}
621+
622+
/* Add this NEW class for the spinner */
623+
.spinner {
624+
width: 3rem;
625+
height: 3rem;
626+
border: 0.25rem solid var(--color-primary-light);
627+
border-top: 0.25rem solid var(--color-primary);
628+
border-radius: 50%;
629+
animation: spin 1s linear infinite;
630+
margin-bottom: 1rem;
631+
}
632+
633+
@keyframes spin {
634+
0% {
635+
transform: rotate(0deg);
636+
}
637+
100% {
638+
transform: rotate(360deg);
639+
}
640+
}

frontend/src/store.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,32 @@ setInterval(() => {
1616
}, 60000);
1717

1818
let socket: WebSocket | null = null;
19+
let pendingAuthCommand: AuthCommand | null = null;
1920

2021
export function connect() {
22+
// 1. Clean up existing connection to prevent phantom "disconnected" events
23+
if (socket) {
24+
socket.onclose = null; // Remove listener so we don't trigger state change
25+
socket.close();
26+
socket = null;
27+
}
28+
29+
connectionStatus.value = "connecting";
30+
2131
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
2232
socket = new WebSocket(`${protocol}//${window.location.host}/api`);
2333

2434
socket.onopen = () => {
2535
connectionStatus.value = "connected";
36+
37+
// Priority 1: Manual Login/Register
38+
if (pendingAuthCommand) {
39+
sendAuth(pendingAuthCommand);
40+
pendingAuthCommand = null;
41+
return;
42+
}
43+
44+
// Priority 2: Auto-Relogin
2645
const token = localStorage.getItem("reloginToken");
2746
if (token) {
2847
sendAuth({ Relogin: { token } });
@@ -40,12 +59,18 @@ export function connect() {
4059
};
4160
}
4261

62+
export function loginOrRegister(cmd: AuthCommand) {
63+
// Queue the command and force a fresh connection
64+
localStorage.removeItem("reloginToken");
65+
pendingAuthCommand = cmd;
66+
authError.value = null;
67+
connect();
68+
}
69+
4370
function handleMessage(msg: any) {
4471
if (msg.AuthenticationSuccess) {
4572
const { user_id, roles, token } = msg.AuthenticationSuccess;
4673
localStorage.setItem("reloginToken", token);
47-
// We need to wait for the Users update to fully hydrate the current user object
48-
// But we can store the ID for now or handle it when users arrive
4974
effect(() => {
5075
if (users.value[user_id]) {
5176
currentUser.value = { ...users.value[user_id], roles };
@@ -56,10 +81,7 @@ function handleMessage(msg: any) {
5681
localStorage.removeItem("reloginToken");
5782
} else if (msg.Users) {
5883
const newUsers: Record<number, User> = {};
59-
// Rust BTreeMap serializes to a JSON Object, not an Array.
60-
// We use Object.values() to iterate over the users.
6184
Object.values(msg.Users.users).forEach((u: any) => {
62-
// u is the User object { id: 1, name: "...", team: "..." }
6385
newUsers[u.id] = { ...u, roles: [] };
6486
});
6587
users.value = newUsers;
@@ -115,7 +137,6 @@ function patchTalk(id: number, changes: Partial<Talk>) {
115137
}
116138

117139
export function sendAuth(cmd: AuthCommand) {
118-
console.log(cmd);
119140
socket?.send(JSON.stringify(cmd));
120141
}
121142

0 commit comments

Comments
 (0)