forked from quic-issues/427e7578-d7bf-49c8-aee9-2dd999e25316
175 lines
6.4 KiB
TypeScript
175 lines
6.4 KiB
TypeScript
import type { WebrtcProvider } from "y-webrtc";
|
|
|
|
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 statusPanel=document.createElement("div");
|
|
statusPanel.className = "status-bar";
|
|
|
|
const divider = document.createElement("span");
|
|
divider.className = "status-divider";
|
|
divider.textContent = "\u00b7";
|
|
|
|
function getProviderStatus(){
|
|
|
|
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(() => {
|
|
pollProviderElements.statusText.textContent = "Ready";
|
|
pollProviderElements.dot.className = "status-dot ready";
|
|
}, 3000);
|
|
|
|
provider.on("synced", ({ synced }: { synced: boolean }) => {
|
|
if (syncTimeout) {
|
|
clearTimeout(syncTimeout);
|
|
syncTimeout = undefined;
|
|
}
|
|
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 = () => {
|
|
pollProviderElements.dot.className = "status-dot connecting";
|
|
pollProviderElements.statusText.textContent = "Offline";
|
|
userProviderElements.dot.className = "status-dot connecting";
|
|
userProviderElements.statusText.textContent = "Offline";
|
|
};
|
|
const handleOnline = () => {
|
|
pollProviderElements.dot.className = "status-dot connecting";
|
|
pollProviderElements.statusText.textContent = "Reconnecting";
|
|
userProviderElements.dot.className = "status-dot connecting";
|
|
userProviderElements.statusText.textContent = "Reconnecting";
|
|
};
|
|
|
|
window.addEventListener("offline", handleOffline);
|
|
window.addEventListener("online", handleOnline);
|
|
|
|
// --- Peer count ---
|
|
|
|
function updatePeerCount() {
|
|
const total = provider.awareness.getStates().size;
|
|
const others = total - 1;
|
|
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);
|
|
updatePeerCount();
|
|
|
|
return el;
|
|
}
|