channel selection shows properly. loader
This commit is contained in:
parent
d0d2d50966
commit
3e4dd0fa48
@ -25,7 +25,7 @@ type Database = MySql;
|
||||
#[derive(Debug)]
|
||||
enum Error {
|
||||
SQLx(sqlx::Error),
|
||||
serenity(serenity::Error),
|
||||
Serenity(serenity::Error),
|
||||
}
|
||||
|
||||
#[catch(401)]
|
||||
|
@ -45,3 +45,37 @@ macro_rules! check_url_opt {
|
||||
check_url_opt!($($fields),+);
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! check_authorization {
|
||||
($cookies:expr, $ctx:expr, $guild:expr) => {
|
||||
use serenity::model::id::UserId;
|
||||
|
||||
let user_id = $cookies.get_private("userid").map(|c| c.value().parse::<u64>().ok()).flatten();
|
||||
|
||||
match user_id {
|
||||
Some(user_id) => {
|
||||
match GuildId($guild).to_guild_cached($ctx) {
|
||||
Some(guild) => {
|
||||
let member = guild.member($ctx, UserId(user_id)).await;
|
||||
|
||||
match member {
|
||||
Err(_) => {
|
||||
return json!({"error": "User not in guild"})
|
||||
}
|
||||
|
||||
Ok(_) => {}
|
||||
}
|
||||
}
|
||||
|
||||
None => {
|
||||
return json!({"error": "Bot not in guild"})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None => {
|
||||
return json!({"error": "User not authorized"});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -31,13 +31,15 @@ struct ChannelInfo {
|
||||
webhook_name: Option<String>,
|
||||
}
|
||||
|
||||
// todo check the user can access this guild
|
||||
#[get("/api/guild/<id>/channels")]
|
||||
pub async fn get_guild_channels(
|
||||
id: u64,
|
||||
cookies: &CookieJar<'_>,
|
||||
ctx: &State<Context>,
|
||||
pool: &State<Pool<MySql>>,
|
||||
) -> JsonValue {
|
||||
check_authorization!(cookies, ctx.inner(), id);
|
||||
|
||||
let channels_res = GuildId(id).channels(ctx.inner()).await;
|
||||
|
||||
match channels_res {
|
||||
@ -96,9 +98,10 @@ struct RoleInfo {
|
||||
name: String,
|
||||
}
|
||||
|
||||
// todo check the user can access this guild
|
||||
#[get("/api/guild/<id>/roles")]
|
||||
pub async fn get_guild_roles(id: u64, ctx: &State<Context>) -> JsonValue {
|
||||
pub async fn get_guild_roles(id: u64, cookies: &CookieJar<'_>, ctx: &State<Context>) -> JsonValue {
|
||||
check_authorization!(cookies, ctx.inner(), id);
|
||||
|
||||
let roles_res = ctx.cache.guild_roles(id);
|
||||
|
||||
match roles_res {
|
||||
@ -126,14 +129,10 @@ pub async fn create_reminder(
|
||||
serenity_context: &State<Context>,
|
||||
pool: &State<Pool<MySql>>,
|
||||
) -> JsonValue {
|
||||
// get userid from cookies
|
||||
let user_id = cookies.get_private("userid").map(|c| c.value().parse::<u64>().ok()).flatten();
|
||||
check_authorization!(cookies, serenity_context.inner(), id);
|
||||
|
||||
if user_id.is_none() {
|
||||
return json!({"error": "User not authorized"});
|
||||
}
|
||||
|
||||
let user_id = user_id.unwrap();
|
||||
let user_id =
|
||||
cookies.get_private("userid").map(|c| c.value().parse::<u64>().ok()).flatten().unwrap();
|
||||
|
||||
// validate channel
|
||||
let channel = ChannelId(reminder.channel).to_channel_cached(&serenity_context.inner());
|
||||
|
@ -106,7 +106,7 @@ async fn create_database_channel(
|
||||
let webhook = channel
|
||||
.create_webhook_with_avatar(&ctx, "Reminder", DEFAULT_AVATAR.clone())
|
||||
.await
|
||||
.map_err(|e| Error::serenity(e))?;
|
||||
.map_err(|e| Error::Serenity(e))?;
|
||||
|
||||
sqlx::query!(
|
||||
"UPDATE channels SET webhook_id = ?, webhook_token = ? WHERE channel = ?",
|
||||
@ -127,7 +127,7 @@ async fn create_database_channel(
|
||||
let webhook = channel
|
||||
.create_webhook_with_avatar(&ctx, "Reminder", DEFAULT_AVATAR.clone())
|
||||
.await
|
||||
.map_err(|e| Error::serenity(e))?;
|
||||
.map_err(|e| Error::Serenity(e))?;
|
||||
|
||||
// create database entry
|
||||
sqlx::query!(
|
||||
|
@ -54,6 +54,19 @@
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<div id="loader" class="is-hidden hero is-fullheight" style="position: fixed; background-color: white; opacity: 0.8; width: 100vw; z-index: 999;">
|
||||
<div class="hero-body">
|
||||
<div class="container has-text-centered">
|
||||
<p class="title" style="font-size: 6rem; color: #8fb677">
|
||||
<i class="fas fa-cog fa-spin"></i>
|
||||
</p>
|
||||
<p class="subtitle">
|
||||
Bear with...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- dead image used to check which other images are dead -->
|
||||
<img style="display: none;" src="" id="dead">
|
||||
|
||||
@ -158,7 +171,7 @@
|
||||
<ul class="menu-list guildList">
|
||||
|
||||
</ul>
|
||||
<div class="aside-footer" style="margin-top: auto;">
|
||||
<div class="aside-footer" style="position: fixed; bottom: 0;">
|
||||
<p class="menu-label">
|
||||
Settings
|
||||
</p>
|
||||
@ -234,24 +247,22 @@
|
||||
<section id="guild" class="is-hidden">
|
||||
{% include "reminder_dashboard/reminder_dashboard" %}
|
||||
</section>
|
||||
<section id="guild-error" class="is-hidden hero is-fullheight">
|
||||
<div class="hero-body">
|
||||
<div class="">
|
||||
<p class="title">
|
||||
We couldn't get this server's data
|
||||
</p>
|
||||
<p class="subtitle">
|
||||
Please check Reminder Bot is in the server, and has correct permissions.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<!-- /main content -->
|
||||
</div>
|
||||
|
||||
<footer class="footer">
|
||||
<div class="content has-text-centered">
|
||||
<p>
|
||||
<strong>Reminder Bot</strong>, created by <a href="https://github.com/JellyWX"><strong>JellyWX</strong></a>
|
||||
<br>
|
||||
<a href="https://patreon.com/jellywx"><strong>Patreon</strong></a> | <a
|
||||
href="https://discord.jellywx.com"><strong>Discord</strong></a> | <a
|
||||
href="https://github.com/JellyWX"><strong>GitHub</strong></a>
|
||||
<br>
|
||||
or, <a href="mailto:jude@jellywx.com">Email me</a>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<template id="embedFieldTemplate">
|
||||
<div class="embed-field-box">
|
||||
<label class="is-sr-only" for="embedFieldTitle">Field Title</label>
|
||||
@ -412,7 +423,7 @@
|
||||
let newFrame = $template.content.cloneNode(true);
|
||||
|
||||
// populate channels
|
||||
newFrame.querySelector('select.channel-selector');
|
||||
set_channels(newFrame.querySelector('select.channel-selector'))
|
||||
|
||||
// populate majority of items
|
||||
for (let prop in reminder) {
|
||||
@ -475,6 +486,7 @@
|
||||
|
||||
let colorPicker = new iro.ColorPicker('#colorpicker');
|
||||
let $discordFrame;
|
||||
const $loader = document.querySelector('#loader');
|
||||
const $colorPickerModal = document.querySelector('div#pickColorModal');
|
||||
const $colorPickerInput = $colorPickerModal.querySelector('input');
|
||||
|
||||
@ -482,6 +494,8 @@
|
||||
const browserTimezone = luxon.DateTime.now().zone.name;
|
||||
let botTimezone = 'UTC';
|
||||
|
||||
let channels;
|
||||
|
||||
document.getElementById('set-bot-timezone').addEventListener('click', () => {
|
||||
timezone = botTimezone;
|
||||
update_times();
|
||||
@ -557,6 +571,8 @@
|
||||
})
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
$loader.classList.remove('is-hidden');
|
||||
|
||||
document.querySelectorAll('.navbar-burger').forEach(el => {
|
||||
el.addEventListener('click', () => {
|
||||
const target = el.dataset.target;
|
||||
@ -616,39 +632,26 @@
|
||||
$anchor.dataset['guild'] = guild.id;
|
||||
$anchor.dataset['name'] = guild.name;
|
||||
|
||||
$anchor.addEventListener('click', (e) => {
|
||||
$anchor.addEventListener('click', async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
$loader.classList.remove('is-hidden');
|
||||
|
||||
switch_pane($anchor.dataset['pane']);
|
||||
|
||||
reset_guild_pane();
|
||||
|
||||
fetch_roles($anchor.dataset['guild']);
|
||||
|
||||
fetch(`/dashboard/api/guild/${$anchor.dataset['guild']}/channels`)
|
||||
await fetch(`/dashboard/api/guild/${$anchor.dataset['guild']}/channels`)
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (data.error) {
|
||||
show_error(data.error);
|
||||
} else {
|
||||
document.querySelectorAll('select.channel-selector').forEach((el) => {
|
||||
for (let channel of data) {
|
||||
let newOption = document.createElement('option');
|
||||
channels = data;
|
||||
|
||||
newOption.value = channel.id;
|
||||
newOption.textContent = channel.name;
|
||||
if (channel.webhook_avatar !== null) {
|
||||
newOption.dataset['webhookAvatar'] = channel.webhook_avatar;
|
||||
}
|
||||
if (channel.webhook_name !== null) {
|
||||
newOption.dataset['webhookName'] = channel.webhook_name;
|
||||
}
|
||||
|
||||
el.appendChild(newOption);
|
||||
}
|
||||
|
||||
update_select(el);
|
||||
});
|
||||
document.querySelectorAll('select.channel-selector').forEach(set_channels);
|
||||
}
|
||||
});
|
||||
|
||||
@ -664,6 +667,8 @@
|
||||
});
|
||||
$anchor.classList.add('is-active');
|
||||
resize_textareas();
|
||||
|
||||
$loader.classList.add('is-hidden');
|
||||
});
|
||||
|
||||
element.append($clone);
|
||||
@ -671,8 +676,29 @@
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$loader.classList.add('is-hidden');
|
||||
});
|
||||
|
||||
function set_channels(element) {
|
||||
for (let channel of channels) {
|
||||
let newOption = document.createElement('option');
|
||||
|
||||
newOption.value = channel.id;
|
||||
newOption.textContent = channel.name;
|
||||
if (channel.webhook_avatar !== null) {
|
||||
newOption.dataset['webhookAvatar'] = channel.webhook_avatar;
|
||||
}
|
||||
if (channel.webhook_name !== null) {
|
||||
newOption.dataset['webhookName'] = channel.webhook_name;
|
||||
}
|
||||
|
||||
element.appendChild(newOption);
|
||||
}
|
||||
|
||||
update_select(element);
|
||||
}
|
||||
|
||||
let $createReminder = document.querySelector('#reminderCreator');
|
||||
|
||||
$createReminder.querySelector('button#createReminder').addEventListener('click', () => {
|
||||
@ -711,8 +737,6 @@
|
||||
utc_time: utc_time.toFormat("yyyy-LL-dd'T'HH:mm:ss")
|
||||
}
|
||||
|
||||
console.log(reminder);
|
||||
|
||||
// send to server
|
||||
let guild = document.querySelector('.guildList a.is-active').dataset['guild'];
|
||||
|
||||
|
@ -1,13 +1,64 @@
|
||||
{% extends "base" %}
|
||||
|
||||
{% set title = "Commands" %}
|
||||
{% set page_title = "Commands" %}
|
||||
{% block init %}
|
||||
{% set title = "Support" %}
|
||||
|
||||
{% set page_title = "Reminder Bot" %}
|
||||
{% set page_subtitle = "Command Support" %}
|
||||
{% set page_emoji = "fa-life-ring" %}
|
||||
{% set show_invite = true %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<section class="section">
|
||||
<div class="container">
|
||||
<h2 class="title">Information Commands</h2>
|
||||
<section class="hero is-small">
|
||||
<div class="hero-body">
|
||||
<div class="container has-text-centered">
|
||||
<p class="title">First things first...</p>
|
||||
<p class="content">
|
||||
Use the link below to add the bot.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="hero-foot has-text-centered">
|
||||
<a class="button is-size-6 is-rounded is-success" href="https://invite.reminder-bot.com">
|
||||
<p class="is-size-6">
|
||||
Add Now <span class="icon"><i class="fas fa-chevron-right"></i></span>
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="hero">
|
||||
<div class="hero-body">
|
||||
<div class="container has-text-centered">
|
||||
<p class="title">Choose Your Timezone</p>
|
||||
<p class="content">
|
||||
Select your timezone with <code>/timezone</code>, to ensure times are correct.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="hero">
|
||||
<div class="hero-body">
|
||||
<div class="container has-text-centered">
|
||||
<p class="title">Create a Reminder</p>
|
||||
<p class="content">
|
||||
Create reminders with <code>/remind</code>!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="hero">
|
||||
<div class="hero-body">
|
||||
<div class="container has-text-centered">
|
||||
<p class="title">Delete a Reminder</p>
|
||||
<p class="content">
|
||||
Made a mistake? Delete reminders with <code>/del</code>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user