Improve UX while server statuses are loading

rust
Elnu 1 year ago
parent a8c0969a71
commit 48ac5a44e2

@ -175,7 +175,7 @@ a {
padding: 0.25em 0.5em 0.25em 0.5em; padding: 0.25em 0.5em 0.25em 0.5em;
border-radius: 2px; border-radius: 2px;
&:disabled { &:disabled, &.disabled {
background: gray; background: gray;
} }
} }
@ -206,3 +206,11 @@ a {
height: 1.5em; height: 1.5em;
vertical-align: middle; vertical-align: middle;
} }
h1 {
text-align: center;
&:first-child {
margin-top: 0;
}
}

@ -4,13 +4,20 @@
<p>In order to participate in challenges, you must be a member of a participating Discord server.</p> <p>In order to participate in challenges, you must be a member of a participating Discord server.</p>
<h2>Join a participating server</h2> <h2>Join a participating server</h2>
</div> </div>
<div class="participating">
<h1>Participating servers</h1>
</div>
<div class="servers"> <div class="servers">
{% for guild in settings.guilds %} {% for guild in settings.guilds %}
{% if guild.hidden or not guild.invite %}{% continue %}{% endif %} {% if guild.hidden or not guild.invite %}{% continue %}{% endif %}
<div id="{{ guild.id }}" {% if guild.recommended %} class="recommended"{% endif %}> <div id="{{ guild.id }}" {% if guild.recommended %} class="recommended"{% endif %}>
<img src="https://cdn.discordapp.com/icons/{{ guild.id }}/{{ guild.icon }}.webp?size=96" alt="Server icon"> <img src="https://cdn.discordapp.com/icons/{{ guild.id }}/{{ guild.icon }}.webp?size=96" alt="Server icon">
<div class="name">{{ guild.name }}</div> <div class="name">{{ guild.name }}</div>
<a href="https://discord.gg/{{ guild.invite }}" class="joinButton">Join</a> <a href="https://discord.gg/{{ guild.invite }}" class="joinButton disabled">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="icon" style="height: 1em">
<path stroke-linecap="round" stroke-linejoin="round" d="M6.75 12a.75.75 0 11-1.5 0 .75.75 0 011.5 0zM12.75 12a.75.75 0 11-1.5 0 .75.75 0 011.5 0zM18.75 12a.75.75 0 11-1.5 0 .75.75 0 011.5 0z" />
</svg>
</a>
{% if guild.recommended %} {% if guild.recommended %}
<div class="label-wrapper"> <div class="label-wrapper">
<div class="label">Recommended</div> <div class="label">Recommended</div>
@ -24,8 +31,8 @@
const dialog = document.querySelector("dialog"); const dialog = document.querySelector("dialog");
// Fetch guilds // Fetch guilds
let guilds = null; let guilds = null;
let is_in_participating_server = null;
const getGuilds = async () => { const getGuilds = async () => {
let is_in_participating_server = false;
if (guilds === null) { if (guilds === null) {
// Create the guilds dictionary object // Create the guilds dictionary object
guilds = {}; guilds = {};
@ -39,12 +46,13 @@ const getGuilds = async () => {
const [id, is_member] = event.data.split(','); const [id, is_member] = event.data.split(',');
// Add the key-value pair to the guilds dictionary // Add the key-value pair to the guilds dictionary
guilds[id] = is_member === 'true'; const joined = is_member === 'true';
guilds[id] = joined;
if (guilds[id]) { if (joined) {
setJoined(id);
is_in_participating_server = true; is_in_participating_server = true;
} }
setJoined(id, joined);
}); });
// Function to block execution until SSE events are done // Function to block execution until SSE events are done
@ -62,22 +70,17 @@ const getGuilds = async () => {
// Call the function to block execution until SSE events are done // Call the function to block execution until SSE events are done
await waitForSSE() await waitForSSE()
} }
return guilds; return is_in_participating_server;
} }
// Show server modal, both for welcome and server list // Show server modal, both for welcome and server list
const showServers = async () => { const showServers = async () => {
dialog.showModal(); dialog.showModal();
// If the user is logged in, load the guild list // If the user is logged in, load the guild list
// and check if they have joined the available servers // and check if they have joined the available servers
const guilds = await getGuilds(); await getGuilds();
Object.keys(guilds).forEach(id => {
if (guilds[id]) {
setJoined(id);
}
})
}; };
// Switch Join button to Joined for server // Switch Join button to Joined for server
const setJoined = id => { const setJoined = (id, joined) => {
element = document.getElementById(id); element = document.getElementById(id);
if (element === null) { if (element === null) {
return; return;
@ -87,12 +90,17 @@ const setJoined = id => {
if (a === null) { if (a === null) {
return; return;
} }
if (joined) {
const button = document.createElement("button"); const button = document.createElement("button");
button.tagName = "button"; button.tagName = "button";
button.className = "joinButton"; button.className = "joinButton";
button.disabled = true; button.disabled = true;
button.innerHTML = "Joined" button.innerHTML = "Joined"
element.querySelector("a").replaceWith(button); a.replaceWith(button);
} else {
a.innerHTML = "Join";
a.classList.remove("disabled");
}
} }
// Check for welcomed cookie // Check for welcomed cookie
@ -104,8 +112,7 @@ const loadServers = async () => {
// in case user pressed Join servers button // in case user pressed Join servers button
document.querySelector("dialog .welcome").style.display = "none"; document.querySelector("dialog .welcome").style.display = "none";
} else { } else {
const guilds = await getGuilds(); if (!(await getGuilds())) {
if (!is_in_participating_server) {
showServers(); showServers();
} }
// Even if already in participating server, // Even if already in participating server,
@ -117,6 +124,7 @@ if (welcomed()) {
// TODO: Remove welcome text via cookie check in template? // TODO: Remove welcome text via cookie check in template?
document.querySelector("dialog .welcome").style.display = "none"; document.querySelector("dialog .welcome").style.display = "none";
} else { } else {
document.querySelector("dialog .participating").style.display = "none";
// If not welcomed, see if welcome is necessary // If not welcomed, see if welcome is necessary
loadServers(); loadServers();
} }

Loading…
Cancel
Save