diff --git a/.prettierrc.toml b/.prettierrc.toml new file mode 100644 index 0000000..3d14781 --- /dev/null +++ b/.prettierrc.toml @@ -0,0 +1 @@ +tabWidth = 4 diff --git a/web/static/js/main.js b/web/static/js/main.js index c504ceb..5dc4b61 100644 --- a/web/static/js/main.js +++ b/web/static/js/main.js @@ -1,26 +1,28 @@ -let colorPicker = new iro.ColorPicker('#colorpicker'); +let colorPicker = new iro.ColorPicker("#colorpicker"); let $discordFrame; -const $loader = document.querySelector('#loader'); -const $colorPickerModal = document.querySelector('div#pickColorModal'); -const $colorPickerInput = $colorPickerModal.querySelector('input'); +const $loader = document.querySelector("#loader"); +const $colorPickerModal = document.querySelector("div#pickColorModal"); +const $colorPickerInput = $colorPickerModal.querySelector("input"); let timezone = luxon.DateTime.now().zone.name; const browserTimezone = luxon.DateTime.now().zone.name; -let botTimezone = 'UTC'; +let botTimezone = "UTC"; let channels; let roles; +const remindersLoadedEvent = new Event("remindersLoaded"); + function colorToInt(r, g, b) { - return (r << 16) + (g << 8) + (b); + return (r << 16) + (g << 8) + b; } function resize_textareas() { - document.querySelectorAll('textarea.autoresize').forEach((element) => { + document.querySelectorAll("textarea.autoresize").forEach((element) => { element.style.height = ""; element.style.height = element.scrollHeight + 3 + "px"; - element.addEventListener('input', () => { + element.addEventListener("input", () => { element.style.height = ""; element.style.height = element.scrollHeight + 3 + "px"; }); @@ -28,83 +30,92 @@ function resize_textareas() { } function switch_pane(selector) { - document.querySelectorAll('aside a').forEach((el) => { - el.classList.remove('is-active'); + document.querySelectorAll("aside a").forEach((el) => { + el.classList.remove("is-active"); }); - document.querySelectorAll('div.is-main-content > section').forEach((el) => { - el.classList.add('is-hidden'); + document.querySelectorAll("div.is-main-content > section").forEach((el) => { + el.classList.add("is-hidden"); }); - document.getElementById(selector).classList.remove('is-hidden'); + document.getElementById(selector).classList.remove("is-hidden"); resize_textareas(); } function update_select(sel) { - if (sel.selectedOptions[0].dataset['webhookAvatar']) { + if (sel.selectedOptions[0].dataset["webhookAvatar"]) { sel - .closest('div.reminderContent') - .querySelector('img.discord-avatar') - .src = sel.selectedOptions[0].dataset['webhookAvatar']; + .closest("div.reminderContent") + .querySelector("img.discord-avatar").src = + sel.selectedOptions[0].dataset["webhookAvatar"]; } else { sel - .closest('div.reminderContent') - .querySelector('img.discord-avatar') - .src = ''; + .closest("div.reminderContent") + .querySelector("img.discord-avatar").src = ""; } - if (sel.selectedOptions[0].dataset['webhookName']) { + if (sel.selectedOptions[0].dataset["webhookName"]) { sel - .closest('div.reminderContent') - .querySelector('input.discord-username') - .value = sel.selectedOptions[0].dataset['webhookName']; + .closest("div.reminderContent") + .querySelector("input.discord-username").value = + sel.selectedOptions[0].dataset["webhookName"]; } else { sel - .closest('div.reminderContent') - .querySelector('input.discord-username') - .value = ''; + .closest("div.reminderContent") + .querySelector("input.discord-username").value = ""; } } function reset_guild_pane() { - document.querySelectorAll('select.channel-selector option').forEach((opt) => opt.remove()); + document + .querySelectorAll("select.channel-selector option") + .forEach((opt) => opt.remove()); } function fetch_roles(guild_id) { fetch(`/dashboard/api/guild/${guild_id}/roles`) - .then(response => response.json()) - .then(data => { + .then((response) => response.json()) + .then((data) => { if (data.error) { show_error(data.error); } else { roles = data; } - }) + }); } async function fetch_reminders(guild_id) { // fetch dm reminders instead if (guild_id === undefined) { - const $reminderBox = document.querySelector('div#personalReminders'); + const $reminderBox = document.querySelector("div#personalReminders"); // reset div contents - $reminderBox.innerHTML = ''; + $reminderBox.innerHTML = ""; // fetch reminders - await fetch('dashboard/api/user/reminders') - .then(response => response.json()) - .then(data => { + await fetch("dashboard/api/user/reminders") + .then((response) => response.json()) + .then((data) => { if (data.error) { show_error(data.error); } else { - const $template = document.querySelector('template#personalReminder'); + const $template = document.querySelector( + "template#personalReminder" + ); for (let reminder of data) { let newFrame = $template.content.cloneNode(true); for (let prop in reminder) { - if (reminder.hasOwnProperty(prop) && reminder[prop] !== null) { - let $input = newFrame.querySelector(`*[name="${prop}"]`); - let $image = newFrame.querySelector(`img.${prop}`); + if ( + reminder.hasOwnProperty(prop) && + reminder[prop] !== null + ) { + let $input = newFrame.querySelector( + `*[name="${prop}"]` + ); + let $image = newFrame.querySelector( + `img.${prop}` + ); if ($input !== null) { $input.value = reminder[prop]; @@ -119,35 +130,47 @@ async function fetch_reminders(guild_id) { } }); } else { - const $reminderBox = document.querySelector('div#guildReminders'); + const $reminderBox = document.querySelector("div#guildReminders"); // reset div contents - $reminderBox.innerHTML = ''; + $reminderBox.innerHTML = ""; // fetch reminders await fetch(`dashboard/api/guild/${guild_id}/reminders`) - .then(response => response.json()) - .then(data => { + .then((response) => response.json()) + .then((data) => { if (data.error) { show_error(data.error); } else { console.log(data); - const $template = document.querySelector('template#guildReminder'); + const $template = document.querySelector( + "template#guildReminder" + ); for (let reminder of data) { let newFrame = $template.content.cloneNode(true); - newFrame.querySelector('.reminderContent').dataset.uid = reminder['uid']; + newFrame.querySelector(".reminderContent").dataset.uid = + reminder["uid"]; // populate channels - set_channels(newFrame.querySelector('select.channel-selector')) + set_channels( + newFrame.querySelector("select.channel-selector") + ); // populate majority of items for (let prop in reminder) { - if (reminder.hasOwnProperty(prop) && reminder[prop] !== null) { - let $input = newFrame.querySelector(`*[name="${prop}"]`); - let $image = newFrame.querySelector(`img.${prop}`); + if ( + reminder.hasOwnProperty(prop) && + reminder[prop] !== null + ) { + let $input = newFrame.querySelector( + `*[name="${prop}"]` + ); + let $image = newFrame.querySelector( + `img.${prop}` + ); if ($input !== null) { $input.value = reminder[prop]; @@ -157,24 +180,34 @@ async function fetch_reminders(guild_id) { } } - let guild = document.querySelector('.guildList a.is-active').dataset['guild']; + let guild = document.querySelector( + ".guildList a.is-active" + ).dataset["guild"]; - let $enableBtn = newFrame.querySelector('.disable-enable'); + let $enableBtn = + newFrame.querySelector(".disable-enable"); - $enableBtn.textContent = reminder['enabled'] ? 'Disable' : 'Enable'; - $enableBtn.addEventListener('click', () => { + $enableBtn.textContent = reminder["enabled"] + ? "Disable" + : "Enable"; + $enableBtn.addEventListener("click", () => { fetch(`/dashboard/api/guild/${guild}/reminders`, { - method: 'PATCH', + method: "PATCH", body: JSON.stringify({ - uid: reminder['uid'], - enabled: false - }) - }) - }) + uid: reminder["uid"], + enabled: false, + }), + }); + }); - let timeInput = newFrame.querySelector('input[name="time"]'); - let localTime = luxon.DateTime.fromISO(reminder["utc_time"]).setZone(timezone); - timeInput.value = localTime.toFormat("yyyy-LL-dd'T'HH:mm:ss"); + let timeInput = + newFrame.querySelector('input[name="time"]'); + let localTime = luxon.DateTime.fromISO( + reminder["utc_time"] + ).setZone(timezone); + timeInput.value = localTime.toFormat( + "yyyy-LL-dd'T'HH:mm:ss" + ); $reminderBox.appendChild(newFrame); } @@ -182,65 +215,74 @@ async function fetch_reminders(guild_id) { }); } + document.dispatchEvent(remindersLoadedEvent); register_interval_hide(); } function show_error(error) { - document.getElementById('errors').querySelector('span.error-message').textContent = error; - document.getElementById('errors').classList.add('is-active'); + document + .getElementById("errors") + .querySelector("span.error-message").textContent = error; + document.getElementById("errors").classList.add("is-active"); window.setTimeout(() => { - document.getElementById('errors').classList.remove('is-active'); + document.getElementById("errors").classList.remove("is-active"); }, 5000); } function update_times() { - document.querySelectorAll('span.set-timezone').forEach((element) => { + document.querySelectorAll("span.set-timezone").forEach((element) => { element.textContent = timezone; }); - document.querySelectorAll('span.set-time').forEach((element) => { - element.textContent = luxon.DateTime.now().setZone(timezone).toFormat('HH:mm'); + document.querySelectorAll("span.set-time").forEach((element) => { + element.textContent = luxon.DateTime.now() + .setZone(timezone) + .toFormat("HH:mm"); }); - document.querySelectorAll('span.browser-timezone').forEach((element) => { + document.querySelectorAll("span.browser-timezone").forEach((element) => { element.textContent = browserTimezone; }); - document.querySelectorAll('span.browser-time').forEach((element) => { - element.textContent = luxon.DateTime.now().toFormat('HH:mm'); + document.querySelectorAll("span.browser-time").forEach((element) => { + element.textContent = luxon.DateTime.now().toFormat("HH:mm"); }); - document.querySelectorAll('span.bot-timezone').forEach((element) => { + document.querySelectorAll("span.bot-timezone").forEach((element) => { element.textContent = botTimezone; }); - document.querySelectorAll('span.bot-time').forEach((element) => { - element.textContent = luxon.DateTime.now().setZone(botTimezone).toFormat('HH:mm'); + document.querySelectorAll("span.bot-time").forEach((element) => { + element.textContent = luxon.DateTime.now() + .setZone(botTimezone) + .toFormat("HH:mm"); }); } window.setInterval(() => { update_times(); -}, 30000) +}, 30000); -document.getElementById('set-bot-timezone').addEventListener('click', () => { +document.getElementById("set-bot-timezone").addEventListener("click", () => { timezone = botTimezone; update_times(); }); -document.getElementById('set-browser-timezone').addEventListener('click', () => { +document + .getElementById("set-browser-timezone") + .addEventListener("click", () => { + timezone = browserTimezone; + update_times(); + }); +document.getElementById("update-bot-timezone").addEventListener("click", () => { timezone = browserTimezone; - update_times(); -}); -document.getElementById('update-bot-timezone').addEventListener('click', () => { - timezone = browserTimezone; - fetch('/dashboard/api/user', { - method: 'PATCH', + fetch("/dashboard/api/user", { + method: "PATCH", headers: { - 'Accept': 'application/json', - 'Content-Type': 'application/json' + Accept: "application/json", + "Content-Type": "application/json", }, - body: JSON.stringify({timezone: timezone}) + body: JSON.stringify({ timezone: timezone }), }) - .then(response => response.json()) - .then(data => { + .then((response) => response.json()) + .then((data) => { if (data.error) { - show_error(data.error) + show_error(data.error); } else { botTimezone = browserTimezone; update_times(); @@ -250,83 +292,101 @@ document.getElementById('update-bot-timezone').addEventListener('click', () => { $colorPickerInput.value = colorPicker.color.hexString; -$colorPickerInput.addEventListener('input', () => { +$colorPickerInput.addEventListener("input", () => { if (/^#[0-9a-fA-F]{6}$/.test($colorPickerInput.value) === true) { colorPicker.color.hexString = $colorPickerInput.value; } }); -colorPicker.on('color:change', function (color) { +colorPicker.on("color:change", function (color) { $colorPickerInput.value = color.hexString; }); -document.querySelectorAll('.discord-embed').forEach((element) => { - element.addEventListener('click', (e) => { - if (e.offsetX < parseInt(window.getComputedStyle(element).borderLeftWidth)) { +document.querySelectorAll(".discord-embed").forEach((element) => { + element.addEventListener("click", (e) => { + if ( + e.offsetX < + parseInt(window.getComputedStyle(element).borderLeftWidth) + ) { $discordFrame = element; - $colorPickerModal.classList.toggle('is-active'); - colorPicker.color.rgbString = window.getComputedStyle($discordFrame).borderLeftColor; + $colorPickerModal.classList.toggle("is-active"); + colorPicker.color.rgbString = + window.getComputedStyle($discordFrame).borderLeftColor; } - }) + }); }); -document.querySelectorAll('.set-color').forEach((element) => { - element.addEventListener('click', (e) => { +document.querySelectorAll(".set-color").forEach((element) => { + element.addEventListener("click", (e) => { e.preventDefault(); - $discordFrame = element.closest('div.reminderContent').querySelector('div.discord-embed'); - $colorPickerModal.classList.toggle('is-active'); - colorPicker.color.rgbString = window.getComputedStyle($discordFrame).borderLeftColor; - }) + $discordFrame = element + .closest("div.reminderContent") + .querySelector("div.discord-embed"); + $colorPickerModal.classList.toggle("is-active"); + colorPicker.color.rgbString = + window.getComputedStyle($discordFrame).borderLeftColor; + }); }); -$colorPickerModal.querySelector('button.is-success').addEventListener('click', () => { - $discordFrame.style.borderLeftColor = colorPicker.color.rgbString; +$colorPickerModal + .querySelector("button.is-success") + .addEventListener("click", () => { + $discordFrame.style.borderLeftColor = colorPicker.color.rgbString; - $colorPickerModal.classList.remove('is-active') -}); + $colorPickerModal.classList.remove("is-active"); + }); -document.querySelectorAll('a.show-modal').forEach((element) => { - element.addEventListener('click', (e) => { +document.querySelectorAll("a.show-modal").forEach((element) => { + element.addEventListener("click", (e) => { e.preventDefault(); - document.getElementById(element.dataset['modal']).classList.toggle('is-active'); - }) -}) + document + .getElementById(element.dataset["modal"]) + .classList.toggle("is-active"); + }); +}); -document.addEventListener('DOMContentLoaded', () => { - $loader.classList.remove('is-hidden'); +document.addEventListener("DOMContentLoaded", () => { + $loader.classList.remove("is-hidden"); - document.querySelectorAll('.navbar-burger').forEach(el => { - el.addEventListener('click', () => { + document.querySelectorAll(".navbar-burger").forEach((el) => { + el.addEventListener("click", () => { const target = el.dataset.target; const $target = document.getElementById(target); - el.classList.toggle('is-active'); - $target.classList.toggle('is-active'); + el.classList.toggle("is-active"); + $target.classList.toggle("is-active"); }); }); - fetch('/dashboard/api/user') - .then(response => response.json()) - .then(data => { + fetch("/dashboard/api/user") + .then((response) => response.json()) + .then((data) => { if (data.error) { show_error(data.error); } else { - document.querySelectorAll('a.switch-pane').forEach((element) => { - element.innerHTML = element.innerHTML.replace('%username%', data.name); + document + .querySelectorAll("a.switch-pane") + .forEach((element) => { + element.innerHTML = element.innerHTML.replace( + "%username%", + data.name + ); - element.addEventListener('click', (e) => { - e.preventDefault(); + element.addEventListener("click", (e) => { + e.preventDefault(); - switch_pane(element.dataset['pane']); + switch_pane(element.dataset["pane"]); - element.classList.add('is-active'); + element.classList.add("is-active"); - document.querySelectorAll('p.pageTitle').forEach((el) => { - el.textContent = 'Your Reminders'; + document + .querySelectorAll("p.pageTitle") + .forEach((el) => { + el.textContent = "Your Reminders"; + }); }); }); - }); if (data.timezone !== null) { botTimezone = data.timezone; @@ -336,86 +396,105 @@ document.addEventListener('DOMContentLoaded', () => { } }); - fetch('/dashboard/api/user/guilds') - .then(response => response.json()) - .then(data => { + fetch("/dashboard/api/user/guilds") + .then((response) => response.json()) + .then((data) => { if (data.error) { show_error(data.error); } else { - const $template = document.getElementById('guildListEntry'); + const $template = document.getElementById("guildListEntry"); for (let guild of data) { - document.querySelectorAll('.guildList').forEach((element) => { - const $clone = $template.content.cloneNode(true); - const $anchor = $clone.querySelector('a'); + document + .querySelectorAll(".guildList") + .forEach((element) => { + const $clone = $template.content.cloneNode(true); + const $anchor = $clone.querySelector("a"); - $anchor.innerHTML = $clone.querySelector('a').innerHTML.replace('%guildname%', guild.name); - $anchor.dataset['guild'] = guild.id; - $anchor.dataset['name'] = guild.name; + $anchor.innerHTML = $clone + .querySelector("a") + .innerHTML.replace("%guildname%", guild.name); + $anchor.dataset["guild"] = guild.id; + $anchor.dataset["name"] = guild.name; - $anchor.addEventListener('click', async (e) => { - e.preventDefault(); + $anchor.addEventListener("click", async (e) => { + e.preventDefault(); - $loader.classList.remove('is-hidden'); + $loader.classList.remove("is-hidden"); - switch_pane($anchor.dataset['pane']); + switch_pane($anchor.dataset["pane"]); - reset_guild_pane(); + reset_guild_pane(); - fetch_roles($anchor.dataset['guild']); + fetch_roles($anchor.dataset["guild"]); - await fetch(`/dashboard/api/guild/${$anchor.dataset['guild']}/channels`) - .then(response => response.json()) - .then(data => { - if (data.error) { - if (data.error === "Bot not in guild") { - switch_pane('guild-error'); + await fetch( + `/dashboard/api/guild/${$anchor.dataset["guild"]}/channels` + ) + .then((response) => response.json()) + .then((data) => { + if (data.error) { + if ( + data.error === + "Bot not in guild" + ) { + switch_pane("guild-error"); + } else { + show_error(data.error); + } } else { - show_error(data.error); + channels = data; + + document + .querySelectorAll( + "select.channel-selector" + ) + .forEach(set_channels); } - } else { - channels = data; + }); - document.querySelectorAll('select.channel-selector').forEach(set_channels); - } - }); + fetch_reminders($anchor.dataset["guild"]); - fetch_reminders($anchor.dataset['guild']); + document + .querySelectorAll("p.pageTitle") + .forEach((el) => { + el.textContent = + $anchor.dataset["name"] + + " Reminders"; + }); + document + .querySelectorAll("select.channel-selector") + .forEach((el) => { + el.addEventListener("change", (e) => { + update_select(e.target); + }); + }); + $anchor.classList.add("is-active"); + resize_textareas(); - document.querySelectorAll('p.pageTitle').forEach((el) => { - el.textContent = $anchor.dataset['name'] + ' Reminders'; + $loader.classList.add("is-hidden"); }); - document.querySelectorAll('select.channel-selector').forEach((el) => { - el.addEventListener('change', (e) => { - update_select(e.target); - }) - }); - $anchor.classList.add('is-active'); - resize_textareas(); - $loader.classList.add('is-hidden'); + element.append($clone); }); - - element.append($clone); - }); } } }); - $loader.classList.add('is-hidden'); + $loader.classList.add("is-hidden"); }); function set_channels(element) { for (let channel of channels) { - let newOption = document.createElement('option'); + let newOption = document.createElement("option"); newOption.value = channel.id; newOption.textContent = channel.name; if (channel.webhook_avatar !== null) { - newOption.dataset['webhookAvatar'] = channel.webhook_avatar; + newOption.dataset["webhookAvatar"] = channel.webhook_avatar; } if (channel.webhook_name !== null) { - newOption.dataset['webhookName'] = channel.webhook_name; + newOption.dataset["webhookName"] = channel.webhook_name; } element.appendChild(newOption); @@ -424,165 +503,225 @@ function set_channels(element) { update_select(element); } -let $createReminder = document.querySelector('#reminderCreator'); +let $createReminder = document.querySelector("#reminderCreator"); -$createReminder.querySelector('button#createReminder').addEventListener('click', () => { - // create reminder object - let seconds = parseInt($createReminder.querySelector('input[name="interval_seconds"]').value) || null; - let months = parseInt($createReminder.querySelector('input[name="interval_months"]').value) || null; +$createReminder + .querySelector("button#createReminder") + .addEventListener("click", () => { + // create reminder object + let seconds = + parseInt( + $createReminder.querySelector('input[name="interval_seconds"]') + .value + ) || null; + let months = + parseInt( + $createReminder.querySelector('input[name="interval_months"]') + .value + ) || null; - let rgb_color = window.getComputedStyle($createReminder.querySelector('div.discord-embed')).borderLeftColor; - let rgb = rgb_color.match(/\d+/g); - let color = colorToInt(parseInt(rgb[0]), parseInt(rgb[1]), parseInt(rgb[2])); + let rgb_color = window.getComputedStyle( + $createReminder.querySelector("div.discord-embed") + ).borderLeftColor; + let rgb = rgb_color.match(/\d+/g); + let color = colorToInt( + parseInt(rgb[0]), + parseInt(rgb[1]), + parseInt(rgb[2]) + ); - let utc_time = luxon.DateTime.fromISO($createReminder.querySelector('input[name="time"]').value).setZone('UTC'); + let utc_time = luxon.DateTime.fromISO( + $createReminder.querySelector('input[name="time"]').value + ).setZone("UTC"); - let reminder = { - avatar: $createReminder.querySelector('img.discord-avatar').src, - channel: $createReminder.querySelector('select.channel-selector').value, - content: $createReminder.querySelector('textarea#messageContent').value, - embed_author_url: $createReminder.querySelector('img.embed_author_url').src, - embed_author: $createReminder.querySelector('textarea#embedAuthor').value, - embed_color: color, - embed_description: $createReminder.querySelector('textarea#embedDescription').value, - embed_footer: $createReminder.querySelector('textarea#embedFooter').value, - embed_footer_url: $createReminder.querySelector('img.embed_footer_url').src, - embed_image_url: $createReminder.querySelector('img.embed_image_url').src, - embed_thumbnail_url: $createReminder.querySelector('img.embed_thumbnail_url').src, - embed_title: $createReminder.querySelector('textarea#embedTitle').value, - enabled: true, - expires: null, - interval_seconds: seconds, - interval_months: months, - name: $createReminder.querySelector('input[name="name"]').value, - pin: $createReminder.querySelector('input[name="pin"]').checked, - restartable: false, - tts: $createReminder.querySelector('input[name="tts"]').checked, - username: $createReminder.querySelector('input#reminderUsername').value, - utc_time: utc_time.toFormat("yyyy-LL-dd'T'HH:mm:ss") - } + let reminder = { + avatar: $createReminder.querySelector("img.discord-avatar").src, + channel: $createReminder.querySelector("select.channel-selector") + .value, + content: $createReminder.querySelector("textarea#messageContent") + .value, + embed_author_url: $createReminder.querySelector( + "img.embed_author_url" + ).src, + embed_author: $createReminder.querySelector("textarea#embedAuthor") + .value, + embed_color: color, + embed_description: $createReminder.querySelector( + "textarea#embedDescription" + ).value, + embed_footer: $createReminder.querySelector("textarea#embedFooter") + .value, + embed_footer_url: $createReminder.querySelector( + "img.embed_footer_url" + ).src, + embed_image_url: $createReminder.querySelector( + "img.embed_image_url" + ).src, + embed_thumbnail_url: $createReminder.querySelector( + "img.embed_thumbnail_url" + ).src, + embed_title: $createReminder.querySelector("textarea#embedTitle") + .value, + enabled: true, + expires: null, + interval_seconds: seconds, + interval_months: months, + name: $createReminder.querySelector('input[name="name"]').value, + pin: $createReminder.querySelector('input[name="pin"]').checked, + restartable: false, + tts: $createReminder.querySelector('input[name="tts"]').checked, + username: $createReminder.querySelector("input#reminderUsername") + .value, + utc_time: utc_time.toFormat("yyyy-LL-dd'T'HH:mm:ss"), + }; - // send to server - let guild = document.querySelector('.guildList a.is-active').dataset['guild']; + // send to server + let guild = document.querySelector(".guildList a.is-active").dataset[ + "guild" + ]; - fetch(`/dashboard/api/guild/${guild}/reminders`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json' - }, - body: JSON.stringify(reminder) - }).then(response => response.json()).then(data => console.log(data)) + fetch(`/dashboard/api/guild/${guild}/reminders`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(reminder), + }) + .then((response) => response.json()) + .then((data) => console.log(data)); - // process response + // process response - // reset inputs -}); + // reset inputs + }); -document.querySelectorAll('textarea.autoresize').forEach((element) => { - element.addEventListener('input', () => { +document.querySelectorAll("textarea.autoresize").forEach((element) => { + element.addEventListener("input", () => { element.style.height = ""; element.style.height = element.scrollHeight + 3 + "px"; }); }); let $img; -const $urlModal = document.querySelector('div#addImageModal'); -const $urlInput = $urlModal.querySelector('input'); +const $urlModal = document.querySelector("div#addImageModal"); +const $urlInput = $urlModal.querySelector("input"); -$urlModal.querySelector('button.is-success').addEventListener('click', () => { +$urlModal.querySelector("button.is-success").addEventListener("click", () => { $img.src = $urlInput.value; - $urlInput.value = ''; - $urlModal.classList.remove('is-active') + $urlInput.value = ""; + $urlModal.classList.remove("is-active"); }); -document.querySelectorAll('button.close-modal').forEach((element) => { - element.addEventListener('click', () => { - let $modal = element.closest('div.modal'); +document.querySelectorAll("button.close-modal").forEach((element) => { + element.addEventListener("click", () => { + let $modal = element.closest("div.modal"); - $urlInput.value = ''; + $urlInput.value = ""; - $modal.classList.remove('is-active') + $modal.classList.remove("is-active"); }); }); -document.querySelectorAll('.customizable').forEach((element) => { - element.querySelector('a').addEventListener('click', (e) => { +document.querySelectorAll(".customizable").forEach((element) => { + element.querySelector("a").addEventListener("click", (e) => { e.preventDefault(); - $img = element.querySelector('img'); + $img = element.querySelector("img"); - $urlModal.classList.toggle('is-active') + $urlModal.classList.toggle("is-active"); }); }); -document.querySelectorAll('a.icon-toggle').forEach((element) => { - element.addEventListener('click', (e) => { +document.querySelectorAll("a.icon-toggle").forEach((element) => { + element.addEventListener("click", (e) => { e.preventDefault(); - element.classList.toggle('is-active'); - }) + element.classList.toggle("is-active"); + }); }); -let $showButton = document.querySelector('button#showReminderCreator'); +let $showButton = document.querySelector("button#showReminderCreator"); -$showButton.addEventListener('click', () => { - $showButton.querySelector('span.icon i').classList.toggle('fa-chevron-right'); - $showButton.querySelector('span.icon i').classList.toggle('fa-chevron-down'); - document.querySelector('div#reminderCreator').classList.toggle('is-hidden'); +$showButton.addEventListener("click", () => { + $showButton + .querySelector("span.icon i") + .classList.toggle("fa-chevron-right"); + $showButton + .querySelector("span.icon i") + .classList.toggle("fa-chevron-down"); + document.querySelector("div#reminderCreator").classList.toggle("is-hidden"); }); function register_interval_hide() { - let $showInterval = document.querySelectorAll('a.intervalLabel'); + let $showInterval = document.querySelectorAll("a.intervalLabel"); $showInterval.forEach((element) => { - element.addEventListener('click', () => { - element.querySelector('i').classList.toggle('fa-chevron-right'); - element.querySelector('i').classList.toggle('fa-chevron-down'); - element.nextElementSibling.classList.toggle('is-hidden'); + element.addEventListener("click", () => { + element.querySelector("i").classList.toggle("fa-chevron-right"); + element.querySelector("i").classList.toggle("fa-chevron-down"); + element.nextElementSibling.classList.toggle("is-hidden"); }); }); } -const fileInput = document.querySelectorAll('input[type=file]'); +const fileInput = document.querySelectorAll("input[type=file]"); fileInput.forEach((element) => { - element.addEventListener('change', () => { + element.addEventListener("change", () => { if (element.files.length > 0) { - const fileName = element.parentElement.querySelector('.file-label'); + const fileName = element.parentElement.querySelector(".file-label"); fileName.textContent = element.files[0].name; } - }) + }); }); function check_embed_fields() { - document.querySelectorAll('.discord-field-title').forEach((element) => { - const $template = document.querySelector('template#embedFieldTemplate'); - const $complement = element.parentElement.querySelector('.discord-field-value'); + document.querySelectorAll(".discord-field-title").forEach((element) => { + const $template = document.querySelector("template#embedFieldTemplate"); + const $complement = element.parentElement.querySelector( + ".discord-field-value" + ); // when the user clicks out of the field title and if the field title/value are empty, remove the field - element.addEventListener('blur', () => { - if (element.value === '' && $complement.value === '' && element.parentElement.nextElementSibling !== null) { + element.addEventListener("blur", () => { + if ( + element.value === "" && + $complement.value === "" && + element.parentElement.nextElementSibling !== null + ) { element.parentElement.remove(); } }); - $complement.addEventListener('blur', () => { - if (element.value === '' && $complement.value === '' && element.parentElement.nextElementSibling !== null) { + $complement.addEventListener("blur", () => { + if ( + element.value === "" && + $complement.value === "" && + element.parentElement.nextElementSibling !== null + ) { element.parentElement.remove(); } }); // when the user inputs into the end field, create a new field after it - element.addEventListener('input', () => { - if (element.value !== '' && $complement.value !== '' && element.parentElement.nextElementSibling === null) { + element.addEventListener("input", () => { + if ( + element.value !== "" && + $complement.value !== "" && + element.parentElement.nextElementSibling === null + ) { const $clone = $template.content.cloneNode(true); element.parentElement.parentElement.append($clone); } }); - $complement.addEventListener('input', () => { - if (element.value !== '' && $complement.value !== '' && element.parentElement.nextElementSibling === null) { + $complement.addEventListener("input", () => { + if ( + element.value !== "" && + $complement.value !== "" && + element.parentElement.nextElementSibling === null + ) { const $clone = $template.content.cloneNode(true); element.parentElement.parentElement.append($clone); } @@ -590,12 +729,14 @@ function check_embed_fields() { }); } -document.addEventListener('DOMNodeInserted', () => { - document.querySelectorAll('div.mobile-sidebar a').forEach((element) => { - element.addEventListener('click', (e) => { - document.getElementById('mobileSidebar').classList.remove('is-active'); - document.querySelectorAll('.navbar-burger').forEach((el) => { - el.classList.remove('is-active'); +document.addEventListener("DOMNodeInserted", () => { + document.querySelectorAll("div.mobile-sidebar a").forEach((element) => { + element.addEventListener("click", (e) => { + document + .getElementById("mobileSidebar") + .classList.remove("is-active"); + document.querySelectorAll(".navbar-burger").forEach((el) => { + el.classList.remove("is-active"); }); }); }); diff --git a/web/static/js/sort.js b/web/static/js/sort.js new file mode 100644 index 0000000..17b468c --- /dev/null +++ b/web/static/js/sort.js @@ -0,0 +1,52 @@ +let guildReminders = document.querySelector("#guildReminders"); + +function sort_by(cond) { + if (cond === "channel") { + [...guildReminders.children] + .sort((a, b) => { + let channel1 = a.querySelector("select.channel-selector").value; + let channel2 = b.querySelector("select.channel-selector").value; + + return channel1 > channel2 ? 1 : -1; + }) + .forEach((node) => guildReminders.appendChild(node)); + + // go through and add channel categories + for (let child in guildReminders.children) { + } + } else { + if (cond === "time") { + [...guildReminders.children] + .sort((a, b) => { + let time1 = luxon.DateTime.fromISO( + a.querySelector('input[name="time"]').value + ); + let time2 = luxon.DateTime.fromISO( + b.querySelector('input[name="time"]').value + ); + + return time1 > time2 ? 1 : -1; + }) + .forEach((node) => guildReminders.appendChild(node)); + } else { + [...guildReminders.children] + .sort((a, b) => { + let name1 = a.querySelector('input[name="name"]').value; + let name2 = b.querySelector('input[name="name"]').value; + + return name1 > name2 ? 1 : -1; + }) + .forEach((node) => guildReminders.appendChild(node)); + } + } +} + +document.querySelector("#orderBy").addEventListener("change", (element) => { + sort_by(element.value); +}); + +document.addEventListener("remindersLoaded", () => { + let select = document.querySelector("#orderBy"); + + sort_by(select.value); +}); diff --git a/web/templates/reminder_dashboard/reminder_dashboard.html.tera b/web/templates/reminder_dashboard/reminder_dashboard.html.tera index 3e3736b..b8b8f5d 100644 --- a/web/templates/reminder_dashboard/reminder_dashboard.html.tera +++ b/web/templates/reminder_dashboard/reminder_dashboard.html.tera @@ -9,11 +9,19 @@ {% set creating = false %} -
- - - - +
+
+
+ +
+
+ +
+
@@ -21,3 +29,5 @@
+ +