Proper welcome modal implementation

This commit is contained in:
Elnu 2023-06-22 13:10:55 -07:00
parent 50dce8da96
commit 6b6c047b68
11 changed files with 147 additions and 14 deletions

View file

@ -9,7 +9,9 @@
<link href="/css/style.css" rel="stylesheet">
</head>
<body>
{% if user %}
{% include "modal" %}
{% endif %}
<div id="content">
<nav>
<a class="link" href="/{{ challenge - 1 }}"><svg class="svg-inline" aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><path fill="currentColor" d="M41.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l192 192c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.3 256 278.6 86.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-192 192z"></path></svg></a>
@ -26,8 +28,21 @@
<span>{{ user.username }}</span> <img src="https://cdn.discordapp.com/avatars/{{ user.id }}/{{ user.avatar }}.webp?size=1024">
</a>
<nav class="dropdown-content">
<span class="link" onclick="showServers()">
<span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="icon">
<path stroke-linecap="round" stroke-linejoin="round" d="M18 18.72a9.094 9.094 0 003.741-.479 3 3 0 00-4.682-2.72m.94 3.198l.001.031c0 .225-.012.447-.037.666A11.944 11.944 0 0112 21c-2.17 0-4.207-.576-5.963-1.584A6.062 6.062 0 016 18.719m12 0a5.971 5.971 0 00-.941-3.197m0 0A5.995 5.995 0 0012 12.75a5.995 5.995 0 00-5.058 2.772m0 0a3 3 0 00-4.681 2.72 8.986 8.986 0 003.74.477m.94-3.197a5.971 5.971 0 00-.94 3.197M15 6.75a3 3 0 11-6 0 3 3 0 016 0zm6 3a2.25 2.25 0 11-4.5 0 2.25 2.25 0 014.5 0zm-13.5 0a2.25 2.25 0 11-4.5 0 2.25 2.25 0 014.5 0z" />
</svg>
Join servers
</span>
</span>
<a href="/logout" class="link">
<span>Log out</span>
<span>
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="icon">
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 9V5.25A2.25 2.25 0 0013.5 3h-6a2.25 2.25 0 00-2.25 2.25v13.5A2.25 2.25 0 007.5 21h6a2.25 2.25 0 002.25-2.25V15M12 9l-3 3m0 0l3 3m-3-3h12.75" />
</svg>
Log out
</span>
</a>
</nav>
</div>
@ -36,7 +51,7 @@
{% endif %}
<div class="dropdown">
<span class="link">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-6 h-6" style="height: 1.5em">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="icon">
<path stroke-linecap="round" stroke-linejoin="round" d="M10.5 21l5.25-11.25L21 21m-9-3h7.5M3 5.621a48.474 48.474 0 016-.371m0 0c1.12 0 2.233.038 3.334.114M9 5.25V3m3.334 2.364C11.176 10.658 7.69 15.08 3 17.502m9.334-12.138c.896.061 1.785.147 2.666.257m-4.589 8.495a18.023 18.023 0 01-3.827-5.802" />
</svg>
</span>

View file

@ -1,14 +1,16 @@
<dialog>
<h1>Welcome to {{ "title" | i18n(lang=lang) }}!</h1>
<p>In order to participate in challenges, you must be a member of a participating Discord server.</p>
<h2>Join a participating server</h2>
<div class="welcome">
<h1>Welcome to {{ "title" | i18n(lang=lang) }}!</h1>
<p>In order to participate in challenges, you must be a member of a participating Discord server.</p>
<h2>Join a participating server</h2>
</div>
<div class="servers">
{% for guild in settings.guilds %}
{% if guild.hidden or not guild.invite %}{% continue %}{% endif %}
<div{% 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">
<div class="name">{{ guild.name }}</div>
<a href="https://discord.gg/{{ guild.invite }}">Join</a>
<a href="https://discord.gg/{{ guild.invite }}" class="joinButton">Join</a>
{% if guild.recommended %}
<div class="label-wrapper">
<div class="label">Recommended</div>
@ -19,5 +21,68 @@
</div>
</dialog>
<script>
document.querySelector("dialog").showModal();
const dialog = document.querySelector("dialog");
// Fetch guilds
let guilds = null;
const getGuilds = async () => {
if (guilds === null) {
const response = await fetch("/get_guilds");
const raw_json = await response.text()
guilds = JSON.parse(raw_json);
}
return guilds;
}
// Show server modal, both for welcome and server list
const showServers = async () => {
dialog.showModal();
// If the user is logged in, load the guild list
// and check if they have joined the available servers
const guilds = await getGuilds();
Object.keys(guilds).forEach(id => {
if (guilds[id]) {
const element = document.getElementById(id);
if (element !== null) {
const button = document.createElement("button");
button.tagName = "button";
button.className = "joinButton";
button.disabled = true;
button.innerHTML = "Joined"
element.querySelector("a").replaceWith(button);
}
}
})
};
// Check for welcomed cookie
const welcomed = () => document.cookie.split("; ").includes("welcomed=true");
// Load welcome modal, check if it is necessary
const loadServers = async () => {
if (welcomed()) {
// If already welcomed, remove welcome text
// in case user pressed Join servers button
document.querySelector("dialog .welcome").style.display = "none";
} else {
let is_in_participating_server = false;
const guilds = await getGuilds();
const ids = Object.keys(guilds);
for (let i = 0; i < ids.length; i++) {
if (guilds[ids[i]]) {
is_in_participating_server = true;
break;
}
}
if (!is_in_participating_server) {
showServers();
}
// Even if already in participating server,
// set welcomed cookie so we don't have to run this request again
document.cookie = 'welcomed=true; expires=Tue, 19 Jan 2038 03:14:07 UTC; SameSite=Strict; path=/';
}
};
if (welcomed()) {
// TODO: Remove welcome text via cookie check in template?
document.querySelector("dialog .welcome").style.display = "none";
} else {
// If not welcomed, see if welcome is necessary
loadServers();
}
</script>