+ create user, login, logout

This commit is contained in:
2026-05-06 23:17:50 +02:00
parent 424799692a
commit 5f36ff0b7d
9 changed files with 430 additions and 29 deletions

View File

@@ -1,30 +1,110 @@
import type { WebrtcProvider } from "y-webrtc";
export function StatusBar(provider: WebrtcProvider): HTMLElement {
export function StatusBar(provider: WebrtcProvider, user_provider: WebrtcProvider, onLoginLogout: (event: Event) => Promise<boolean>, onCreateUser: (event: Event) => Promise<boolean>): HTMLElement {
const el = document.createElement("div");
el.className = "status-bar";
const dot = document.createElement("span");
dot.className = "status-dot connecting";
const statusText = document.createElement("span");
statusText.className = "status-text";
statusText.textContent = "Connecting";
const statusPanel=document.createElement("div");
statusPanel.className = "status-bar";
const divider = document.createElement("span");
divider.className = "status-divider";
divider.textContent = "\u00b7";
const peerText = document.createElement("span");
peerText.className = "status-peers";
function getProviderStatus(){
el.append(dot, statusText, divider, peerText);
const dot = document.createElement("span");
dot.className = "status-dot connecting";
const statusText = document.createElement("span");
statusText.className = "status-text";
statusText.textContent = "Connecting";
const peerText = document.createElement("span");
peerText.className = "status-peers";
return { dot: dot, statusText: statusText, peerText: peerText}
}
const providerStatusPanel=document.createElement("div");
providerStatusPanel.className = "provider-status-container";
const pollProviderText = document.createElement("span");
pollProviderText.className = "status-text";
pollProviderText.textContent = "Polls: ";
const pollProviderElements = getProviderStatus()
const pollProviderStatusPanel=document.createElement("div");
pollProviderStatusPanel.className = "status-bar";
pollProviderStatusPanel.append(pollProviderText,pollProviderElements.dot, pollProviderElements.statusText, divider, pollProviderElements.peerText);
const userProviderText = document.createElement("span");
userProviderText.className = "status-text";
userProviderText.textContent = "Users: ";
const userProviderElements = getProviderStatus()
const userProviderStatusPanel=document.createElement("div");
userProviderStatusPanel.className = "status-bar";
userProviderStatusPanel.append(userProviderText,userProviderElements.dot, userProviderElements.statusText, divider, userProviderElements.peerText);
providerStatusPanel.append(userProviderStatusPanel,pollProviderStatusPanel)
const userButtons = document.createElement("div");
userButtons.className = "status-bar";
const loginLabel = document.createElement("label");
loginLabel.setAttribute("title", "Select Key File");
const loginSpan = document.createElement("span");
loginSpan.className = "add-option-btn"
loginSpan.textContent = "Login";
const loginInput = document.createElement("input");
loginInput.type = "file"
loginInput.accept = ".pem"
loginInput.hidden = true
loginLabel.append(loginSpan,loginInput)
const logoutButton = document.createElement("button");
logoutButton.className = "add-option-btn";
logoutButton.setAttribute("aria-label", "Logout");
logoutButton.innerHTML="<span>Logout</span>"
logoutButton.style.display = "none";
const createUserButton = document.createElement("button");
createUserButton.className = "add-option-btn";
createUserButton.setAttribute("aria-label", "Create User");
createUserButton.innerHTML="<span>Create User</span>"
async function onLoginLogoutResult(event: Event, loginLogout: (event: Event) => Promise<boolean>){
if(await loginLogout(event)){
console.log('created / logged in')
loginLabel.style.display = "none";
logoutButton.style.display = "block";
createUserButton.style.display = "none";
} else {
console.log('logged out')
loginLabel.style.display = "block";
logoutButton.style.display = "none";
createUserButton.hidden = false;
createUserButton.style.display = "block";
}
}
loginLabel.addEventListener("change", (e) => onLoginLogoutResult(e,onLoginLogout));
logoutButton.addEventListener("click", (e) => onLoginLogoutResult(e,onLoginLogout));
createUserButton.addEventListener("click", (e) => onLoginLogoutResult(e,onCreateUser));
userButtons.append(loginLabel,logoutButton,createUserButton)
el.append(providerStatusPanel, divider, userButtons);
// --- Connection state ---
let syncTimeout: ReturnType<typeof setTimeout> | undefined = setTimeout(() => {
statusText.textContent = "Ready";
dot.className = "status-dot ready";
pollProviderElements.statusText.textContent = "Ready";
pollProviderElements.dot.className = "status-dot ready";
}, 3000);
provider.on("synced", ({ synced }: { synced: boolean }) => {
@@ -32,18 +112,37 @@ export function StatusBar(provider: WebrtcProvider): HTMLElement {
clearTimeout(syncTimeout);
syncTimeout = undefined;
}
dot.className = `status-dot ${synced ? "connected" : "connecting"}`;
statusText.textContent = synced ? "Connected" : "Connecting";
pollProviderElements.dot.className = `status-dot ${synced ? "connected" : "connecting"}`;
pollProviderElements.statusText.textContent = synced ? "Connected" : "Connecting";
});
let syncTimeout2: ReturnType<typeof setTimeout> | undefined = setTimeout(() => {
userProviderElements.statusText.textContent = "Ready";
userProviderElements.dot.className = "status-dot ready";
}, 3000);
user_provider.on("synced", ({ synced }: { synced: boolean }) => {
if (syncTimeout2) {
clearTimeout(syncTimeout2);
syncTimeout2 = undefined;
}
userProviderElements.dot.className = `status-dot ${synced ? "connected" : "connecting"}`;
userProviderElements.statusText.textContent = synced ? "Connected" : "Connecting";
});
// Online/offline awareness
const handleOffline = () => {
dot.className = "status-dot connecting";
statusText.textContent = "Offline";
pollProviderElements.dot.className = "status-dot connecting";
pollProviderElements.statusText.textContent = "Offline";
userProviderElements.dot.className = "status-dot connecting";
userProviderElements.statusText.textContent = "Offline";
};
const handleOnline = () => {
dot.className = "status-dot connecting";
statusText.textContent = "Reconnecting";
pollProviderElements.dot.className = "status-dot connecting";
pollProviderElements.statusText.textContent = "Reconnecting";
userProviderElements.dot.className = "status-dot connecting";
userProviderElements.statusText.textContent = "Reconnecting";
};
window.addEventListener("offline", handleOffline);
@@ -54,10 +153,18 @@ export function StatusBar(provider: WebrtcProvider): HTMLElement {
function updatePeerCount() {
const total = provider.awareness.getStates().size;
const others = total - 1;
peerText.textContent =
pollProviderElements.peerText.textContent =
others === 0
? "Only you"
: `${others} other${others !== 1 ? "s" : ""}`;
const total2 = user_provider.awareness.getStates().size;
const others2 = total2 - 1;
userProviderElements.peerText.textContent =
others2 === 0
? "Only you"
: `${others2} other${others2 !== 1 ? "s" : ""}`;
}
provider.awareness.on("change", updatePeerCount);