Update schemas and resolve some warnings
This commit is contained in:
parent
54ee3594eb
commit
febd04c374
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -2645,9 +2645,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rocket_dyn_templates"
|
name = "rocket_dyn_templates"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "04bfc006e547e4f72b760ab861f5943b688aed8a82c4977b5500c98f5d17dbfa"
|
checksum = "5bbab919c9e67df3f7ac6624a32ef897df4cd61c0969f4d66f3ced0534660d7a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"normpath",
|
"normpath",
|
||||||
"notify",
|
"notify",
|
||||||
|
@ -30,7 +30,7 @@ secrecy = "0.8.0"
|
|||||||
futures = "0.3.30"
|
futures = "0.3.30"
|
||||||
prometheus = "0.13.3"
|
prometheus = "0.13.3"
|
||||||
rocket = { version = "0.5.0", features = ["tls", "secrets", "json"] }
|
rocket = { version = "0.5.0", features = ["tls", "secrets", "json"] }
|
||||||
rocket_dyn_templates = { version = "0.1.0", features = ["tera"] }
|
rocket_dyn_templates = { version = "0.2.0", features = ["tera"] }
|
||||||
serenity = { version = "0.12", default-features = false, features = ["builder", "cache", "client", "gateway", "http", "model", "utils", "rustls_backend"] }
|
serenity = { version = "0.12", default-features = false, features = ["builder", "cache", "client", "gateway", "http", "model", "utils", "rustls_backend"] }
|
||||||
oauth2 = "4"
|
oauth2 = "4"
|
||||||
csv = "1.2"
|
csv = "1.2"
|
||||||
|
@ -136,9 +136,9 @@ CREATE TABLE reminders (
|
|||||||
set_by INT UNSIGNED,
|
set_by INT UNSIGNED,
|
||||||
|
|
||||||
PRIMARY KEY (id),
|
PRIMARY KEY (id),
|
||||||
FOREIGN KEY (message_id) REFERENCES messages(id) ON DELETE RESTRICT,
|
CONSTRAINT `reminder_message_fk` FOREIGN KEY (message_id) REFERENCES messages(id) ON DELETE RESTRICT,
|
||||||
FOREIGN KEY (channel_id) REFERENCES channels(id) ON DELETE CASCADE,
|
CONSTRAINT `reminder_channel_fk` FOREIGN KEY (channel_id) REFERENCES channels(id) ON DELETE CASCADE,
|
||||||
FOREIGN KEY (set_by) REFERENCES users(id) ON DELETE SET NULL
|
CONSTRAINT `reminder_user_fk` FOREIGN KEY (set_by) REFERENCES users(id) ON DELETE SET NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TRIGGER message_cleanup AFTER DELETE ON reminders
|
CREATE TRIGGER message_cleanup AFTER DELETE ON reminders
|
||||||
@ -157,9 +157,9 @@ CREATE TABLE todos (
|
|||||||
value VARCHAR(2000) NOT NULL,
|
value VARCHAR(2000) NOT NULL,
|
||||||
|
|
||||||
PRIMARY KEY (id),
|
PRIMARY KEY (id),
|
||||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL,
|
CONSTRAINT todos_ibfk_5 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL,
|
||||||
FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE,
|
CONSTRAINT todos_ibfk_4 FOREIGN KEY (guild_id) REFERENCES guilds(id) ON DELETE CASCADE,
|
||||||
FOREIGN KEY (channel_id) REFERENCES channels(id) ON DELETE SET NULL
|
CONSTRAINT todos_ibfk_3 FOREIGN KEY (channel_id) REFERENCES channels(id) ON DELETE SET NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE command_restrictions (
|
CREATE TABLE command_restrictions (
|
||||||
|
@ -46,7 +46,7 @@ CREATE TABLE reminders_new (
|
|||||||
PRIMARY KEY (id),
|
PRIMARY KEY (id),
|
||||||
|
|
||||||
FOREIGN KEY (`channel_id`) REFERENCES channels (`id`) ON DELETE CASCADE,
|
FOREIGN KEY (`channel_id`) REFERENCES channels (`id`) ON DELETE CASCADE,
|
||||||
FOREIGN KEY (`set_by`) REFERENCES users (`id`) ON DELETE SET NULL
|
CONSTRAINT `reminders_ibfk_2` FOREIGN KEY (`set_by`) REFERENCES `users` (`id`) ON DELETE SET NULL
|
||||||
|
|
||||||
# disallow having a reminder as restartable if it has no interval
|
# disallow having a reminder as restartable if it has no interval
|
||||||
-- , CONSTRAINT restartable_interval_mutex CHECK (`restartable` = 0 OR `interval` IS NULL)
|
-- , CONSTRAINT restartable_interval_mutex CHECK (`restartable` = 0 OR `interval` IS NULL)
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
-- Tables no longer needed as old dashboard is decomm.
|
||||||
|
DROP TABLE guild_users;
|
||||||
|
DROP TABLE events;
|
||||||
|
|
||||||
ALTER TABLE users ADD COLUMN `reset_inputs_on_create` BOOLEAN NOT NULL DEFAULT 0;
|
ALTER TABLE users ADD COLUMN `reset_inputs_on_create` BOOLEAN NOT NULL DEFAULT 0;
|
||||||
ALTER TABLE users ADD COLUMN `use_browser_timezone` BOOLEAN NOT NULL DEFAULT 1;
|
ALTER TABLE users ADD COLUMN `use_browser_timezone` BOOLEAN NOT NULL DEFAULT 1;
|
||||||
ALTER TABLE users ADD COLUMN `dashboard_color_scheme` ENUM('system', 'light', 'dark') NOT NULL DEFAULT 'system';
|
ALTER TABLE users ADD COLUMN `dashboard_color_scheme` ENUM('system', 'light', 'dark') NOT NULL DEFAULT 'system';
|
||||||
@ -7,4 +11,14 @@ ALTER TABLE users DROP COLUMN `patreon`;
|
|||||||
ALTER TABLE users DROP COLUMN `name`;
|
ALTER TABLE users DROP COLUMN `name`;
|
||||||
|
|
||||||
ALTER TABLE users DROP PRIMARY KEY, ADD PRIMARY KEY (`user`);
|
ALTER TABLE users DROP PRIMARY KEY, ADD PRIMARY KEY (`user`);
|
||||||
|
|
||||||
|
ALTER TABLE todos DROP CONSTRAINT todos_ibfk_5, MODIFY COLUMN user_id BIGINT UNSIGNED;
|
||||||
|
UPDATE todos SET user_id = (SELECT user FROM users WHERE id = user_id);
|
||||||
|
ALTER TABLE todos ADD CONSTRAINT todos_user_fk FOREIGN KEY (user_id) REFERENCES users(user);
|
||||||
|
|
||||||
|
ALTER TABLE reminders DROP CONSTRAINT reminders_ibfk_2, MODIFY COLUMN set_by BIGINT UNSIGNED;
|
||||||
|
UPDATE reminders SET set_by = (SELECT user FROM users WHERE id = set_by);
|
||||||
|
ALTER TABLE reminders ADD CONSTRAINT reminder_user_fk FOREIGN KEY (set_by) REFERENCES users(user);
|
||||||
|
|
||||||
|
ALTER TABLE users DROP COLUMN `id`;
|
||||||
ALTER TABLE users RENAME COLUMN `user` TO `id`;
|
ALTER TABLE users RENAME COLUMN `user` TO `id`;
|
||||||
|
@ -22,7 +22,6 @@
|
|||||||
<title>Reminder Bot | Dashboard</title>
|
<title>Reminder Bot | Dashboard</title>
|
||||||
|
|
||||||
<!-- styles -->
|
<!-- styles -->
|
||||||
<link rel="stylesheet" href="/static/css/bulma.min.css">
|
|
||||||
<link rel="stylesheet" href="/static/css/fa.css">
|
<link rel="stylesheet" href="/static/css/fa.css">
|
||||||
<link rel="stylesheet" href="/static/css/font.css">
|
<link rel="stylesheet" href="/static/css/font.css">
|
||||||
<link rel="stylesheet" href="/static/css/style.css">
|
<link rel="stylesheet" href="/static/css/style.css">
|
||||||
|
@ -1,10 +1,27 @@
|
|||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
|
|
||||||
|
enum ColorScheme {
|
||||||
|
System = "system",
|
||||||
|
Dark = "dark",
|
||||||
|
Light = "light",
|
||||||
|
}
|
||||||
|
|
||||||
type UserInfo = {
|
type UserInfo = {
|
||||||
name: string;
|
name: string;
|
||||||
patreon: boolean;
|
patreon: boolean;
|
||||||
|
preferences: {
|
||||||
timezone: string | null;
|
timezone: string | null;
|
||||||
reset_inputs_on_create: boolean;
|
reset_inputs_on_create: boolean;
|
||||||
|
dashboard_color_scheme: ColorScheme;
|
||||||
|
use_browser_timezone: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
type UpdateUserInfo = {
|
||||||
|
timezone?: string;
|
||||||
|
reset_inputs_on_create?: boolean;
|
||||||
|
dashboard_color_scheme?: ColorScheme;
|
||||||
|
use_browser_timezone?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type GuildInfo = {
|
export type GuildInfo = {
|
||||||
@ -110,7 +127,7 @@ export const fetchUserInfo = () => ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
export const patchUserInfo = () => ({
|
export const patchUserInfo = () => ({
|
||||||
mutationFn: (timezone: string) => axios.patch(`/dashboard/api/user`, { timezone }),
|
mutationFn: (userInfo: UpdateUserInfo) => axios.patch(`/dashboard/api/user`, userInfo),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const fetchUserGuilds = () => ({
|
export const fetchUserGuilds = () => ({
|
||||||
|
@ -1,15 +1,27 @@
|
|||||||
import { createContext } from "preact";
|
import { createContext } from "preact";
|
||||||
import { useContext } from "preact/compat";
|
import { useContext } from "preact/compat";
|
||||||
import { useState } from "preact/hooks";
|
import { useEffect, useState } from "preact/hooks";
|
||||||
import { DateTime } from "luxon";
|
import { DateTime } from "luxon";
|
||||||
|
import { fetchUserInfo } from "../../api";
|
||||||
|
import { useQuery } from "react-query";
|
||||||
|
|
||||||
type TTimezoneContext = [string, (tz: string) => void];
|
type TTimezoneContext = [string, (tz: string) => void];
|
||||||
|
|
||||||
const TimezoneContext = createContext(["UTC", () => {}] as TTimezoneContext);
|
const TimezoneContext = createContext(["UTC", () => {}] as TTimezoneContext);
|
||||||
|
|
||||||
export const TimezoneProvider = ({ children }) => {
|
export const TimezoneProvider = ({ children }) => {
|
||||||
|
const { data } = useQuery({ ...fetchUserInfo() });
|
||||||
|
|
||||||
const [timezone, setTimezone] = useState(DateTime.now().zoneName);
|
const [timezone, setTimezone] = useState(DateTime.now().zoneName);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setTimezone(
|
||||||
|
data === undefined || data.preferences.use_browser_timezone
|
||||||
|
? DateTime.now().zoneName
|
||||||
|
: data.preferences.timezone,
|
||||||
|
);
|
||||||
|
}, [data]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<TimezoneContext.Provider value={[timezone, setTimezone]}>
|
<TimezoneContext.Provider value={[timezone, setTimezone]}>
|
||||||
{children}
|
{children}
|
||||||
|
@ -13,14 +13,14 @@ export function App() {
|
|||||||
const queryClient = new QueryClient();
|
const queryClient = new QueryClient();
|
||||||
|
|
||||||
let scheme = "light";
|
let scheme = "light";
|
||||||
if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
// if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
||||||
scheme = "dark";
|
// scheme = "dark";
|
||||||
}
|
// }
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<QueryClientProvider client={queryClient}>
|
||||||
<TimezoneProvider>
|
<TimezoneProvider>
|
||||||
<FlashProvider>
|
<FlashProvider>
|
||||||
<QueryClientProvider client={queryClient}>
|
|
||||||
<Router base={"/dashboard"}>
|
<Router base={"/dashboard"}>
|
||||||
<div class={`columns is-gapless dashboard-frame scheme-${scheme}`}>
|
<div class={`columns is-gapless dashboard-frame scheme-${scheme}`}>
|
||||||
<Sidebar />
|
<Sidebar />
|
||||||
@ -52,8 +52,8 @@ export function App() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Router>
|
</Router>
|
||||||
</QueryClientProvider>
|
|
||||||
</FlashProvider>
|
</FlashProvider>
|
||||||
</TimezoneProvider>
|
</TimezoneProvider>
|
||||||
|
</QueryClientProvider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import { useGuild } from "../App/useGuild";
|
|||||||
|
|
||||||
export const Settings = () => {
|
export const Settings = () => {
|
||||||
const guild = useGuild();
|
const guild = useGuild();
|
||||||
const { isSuccess: userFetched, data: userInfo } = useQuery(fetchUserInfo());
|
const { isSuccess: userFetched, data: userInfo } = useQuery({ ...fetchUserInfo() });
|
||||||
|
|
||||||
const [reminder, setReminder] = useReminder();
|
const [reminder, setReminder] = useReminder();
|
||||||
|
|
||||||
|
@ -26,3 +26,11 @@
|
|||||||
textarea.autoresize {
|
textarea.autoresize {
|
||||||
resize: vertical !important;
|
resize: vertical !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.reminderContent {
|
||||||
|
margin-top: 10px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
padding: 14px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
@ -24,7 +24,7 @@ const SidebarContent = ({ guilds }: ContentProps) => {
|
|||||||
<Brand />
|
<Brand />
|
||||||
</a>
|
</a>
|
||||||
<Wave />
|
<Wave />
|
||||||
<aside class="menu">
|
<aside class="menu theme-dark">
|
||||||
<ul class="menu-list">
|
<ul class="menu-list">
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
@ -44,7 +44,6 @@ const SidebarContent = ({ guilds }: ContentProps) => {
|
|||||||
style={{
|
style={{
|
||||||
position: "sticky",
|
position: "sticky",
|
||||||
bottom: "0px",
|
bottom: "0px",
|
||||||
backgroundColor: "rgb(54, 54, 54)",
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<p class="menu-label">Options</p>
|
<p class="menu-label">Options</p>
|
||||||
|
@ -39,7 +39,7 @@ aside.menu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.dashboard-sidebar {
|
.dashboard-sidebar {
|
||||||
display: flex;
|
display: flex !important;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background-color: #363636;
|
background-color: #363636;
|
||||||
width: 230px !important;
|
width: 230px !important;
|
||||||
@ -49,3 +49,19 @@ aside.menu {
|
|||||||
.aside-footer {
|
.aside-footer {
|
||||||
justify-self: end;
|
justify-self: end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.menu a {
|
||||||
|
color: #fff !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu a:hover {
|
||||||
|
color: #424242 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu .menu-label {
|
||||||
|
color: #bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
@ -53,10 +53,10 @@ export const TimezonePicker = () => {
|
|||||||
|
|
||||||
const TimezoneModal = ({ setModalOpen }) => {
|
const TimezoneModal = ({ setModalOpen }) => {
|
||||||
const browserTimezone = DateTime.now().zoneName;
|
const browserTimezone = DateTime.now().zoneName;
|
||||||
const [selectedZone] = useTimezone();
|
const [selectedZone, setTimezone] = useTimezone();
|
||||||
|
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
const { isLoading, isError, data } = useQuery(fetchUserInfo());
|
const { isLoading, isError, data } = useQuery({ ...fetchUserInfo() });
|
||||||
const userInfoMutation = useMutation({
|
const userInfoMutation = useMutation({
|
||||||
...patchUserInfo(),
|
...patchUserInfo(),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
@ -79,7 +79,7 @@ const TimezoneModal = ({ setModalOpen }) => {
|
|||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<i className="fas fa-cog fa-spin"></i>
|
<i className="fas fa-cog fa-spin"></i>
|
||||||
) : (
|
) : (
|
||||||
<TimezoneDisplay timezone={data.timezone || "UTC"}></TimezoneDisplay>
|
<TimezoneDisplay timezone={data.preferences.timezone || "UTC"} />
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
@ -93,10 +93,29 @@ const TimezoneModal = ({ setModalOpen }) => {
|
|||||||
margin: "2px",
|
margin: "2px",
|
||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
userInfoMutation.mutate(browserTimezone);
|
userInfoMutation.mutate({ timezone: browserTimezone });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Set Bot Timezone
|
Set bot timezone
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="button is-success is-outlined"
|
||||||
|
id="update-bot-timezone"
|
||||||
|
style={{
|
||||||
|
margin: "2px",
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
userInfoMutation.mutate({
|
||||||
|
use_browser_timezone: !data.preferences.use_browser_timezone,
|
||||||
|
});
|
||||||
|
setTimezone(
|
||||||
|
data.preferences.use_browser_timezone
|
||||||
|
? data.preferences.timezone
|
||||||
|
: DateTime.now().zoneName,
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Use {data.preferences.use_browser_timezone ? "bot" : "browser"} timezone
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</Modal>
|
</Modal>
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
@import "node_modules/bulma/bulma";
|
||||||
|
|
||||||
/* override styles for when the div is collapsed */
|
/* override styles for when the div is collapsed */
|
||||||
div.reminderContent.is-collapsed .column.discord-frame {
|
div.reminderContent.is-collapsed .column.discord-frame {
|
||||||
display: none;
|
display: none;
|
||||||
@ -47,3 +49,11 @@ div.reminderContent.is-collapsed .hide-box {
|
|||||||
div.reminderContent.is-collapsed .hide-box i {
|
div.reminderContent.is-collapsed .hide-box i {
|
||||||
transform: rotate(90deg);
|
transform: rotate(90deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button.is-success:not(.is-outlined) {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button.is-outlined.is-success:not(.is-focused, :hover, :focus) {
|
||||||
|
background-color: white;
|
||||||
|
}
|
||||||
|
13
reminder-dashboard/src/vars.scss
Normal file
13
reminder-dashboard/src/vars.scss
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
$primary-background-light: #ffffff;
|
||||||
|
$secondary-background-light: #f5f5f5;
|
||||||
|
$contrast-background-light: #363636;
|
||||||
|
$primary-text-light: #4a4a4a;
|
||||||
|
$secondary-text-light: #4a4a4a;
|
||||||
|
$contrast-text-light: #ffffff;
|
||||||
|
|
||||||
|
$primary-background-dark: #363636;
|
||||||
|
$secondary-background-dark: #424242;
|
||||||
|
$contrast-background-dark: #242424;
|
||||||
|
$primary-text-dark: #ffffff;
|
||||||
|
$secondary-text-dark: #ffffff;
|
||||||
|
$contrast-text-dark: #ffffff;
|
@ -17,10 +17,7 @@ impl Recordable for Options {
|
|||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
"
|
"
|
||||||
INSERT INTO todos (user_id, value)
|
INSERT INTO todos (user_id, value)
|
||||||
VALUES (
|
VALUES (?, ?)
|
||||||
(SELECT id FROM users WHERE user = ?),
|
|
||||||
?
|
|
||||||
)
|
|
||||||
",
|
",
|
||||||
ctx.author().id.get(),
|
ctx.author().id.get(),
|
||||||
self.task
|
self.task
|
||||||
|
@ -14,8 +14,7 @@ impl Recordable for Options {
|
|||||||
let values = sqlx::query!(
|
let values = sqlx::query!(
|
||||||
"
|
"
|
||||||
SELECT todos.id, value FROM todos
|
SELECT todos.id, value FROM todos
|
||||||
INNER JOIN users ON todos.user_id = users.id
|
WHERE user_id = ?
|
||||||
WHERE users.user = ?
|
|
||||||
",
|
",
|
||||||
ctx.author().id.get(),
|
ctx.author().id.get(),
|
||||||
)
|
)
|
||||||
|
@ -191,8 +191,7 @@ impl ComponentDataModel {
|
|||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
"
|
"
|
||||||
SELECT todos.id, value FROM todos
|
SELECT todos.id, value FROM todos
|
||||||
INNER JOIN users ON todos.user_id = users.id
|
WHERE user_id = ?
|
||||||
WHERE users.user = ?
|
|
||||||
",
|
",
|
||||||
uid,
|
uid,
|
||||||
)
|
)
|
||||||
@ -286,8 +285,7 @@ impl ComponentDataModel {
|
|||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
"
|
"
|
||||||
SELECT todos.id, value FROM todos
|
SELECT todos.id, value FROM todos
|
||||||
INNER JOIN users ON todos.user_id = users.id
|
WHERE user_id = ?
|
||||||
WHERE users.user = ?
|
|
||||||
",
|
",
|
||||||
uid,
|
uid,
|
||||||
)
|
)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use poise::{
|
use poise::{
|
||||||
serenity_prelude as serenity,
|
serenity_prelude as serenity,
|
||||||
serenity_prelude::{ActivityData, CreateEmbed, CreateMessage, FullEvent},
|
serenity_prelude::{CreateEmbed, CreateMessage, FullEvent},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use poise::{serenity_prelude::model::channel::Channel, CommandInteractionType, CreateReply};
|
use poise::{CommandInteractionType, CreateReply};
|
||||||
|
|
||||||
use crate::{consts::MACRO_MAX_COMMANDS, models::command_macro::RecordedCommand, Context, Error};
|
use crate::{consts::MACRO_MAX_COMMANDS, models::command_macro::RecordedCommand, Context, Error};
|
||||||
|
|
||||||
|
@ -85,17 +85,13 @@ impl Reminder {
|
|||||||
reminders.enabled,
|
reminders.enabled,
|
||||||
reminders.content,
|
reminders.content,
|
||||||
reminders.embed_description,
|
reminders.embed_description,
|
||||||
users.user AS set_by
|
reminders.set_by
|
||||||
FROM
|
FROM
|
||||||
reminders
|
reminders
|
||||||
INNER JOIN
|
INNER JOIN
|
||||||
channels
|
channels
|
||||||
ON
|
ON
|
||||||
reminders.channel_id = channels.id
|
reminders.channel_id = channels.id
|
||||||
LEFT JOIN
|
|
||||||
users
|
|
||||||
ON
|
|
||||||
reminders.set_by = users.id
|
|
||||||
WHERE
|
WHERE
|
||||||
reminders.uid = ?
|
reminders.uid = ?
|
||||||
",
|
",
|
||||||
@ -122,17 +118,13 @@ impl Reminder {
|
|||||||
reminders.enabled,
|
reminders.enabled,
|
||||||
reminders.content,
|
reminders.content,
|
||||||
reminders.embed_description,
|
reminders.embed_description,
|
||||||
users.user AS set_by
|
reminders.set_by
|
||||||
FROM
|
FROM
|
||||||
reminders
|
reminders
|
||||||
INNER JOIN
|
INNER JOIN
|
||||||
channels
|
channels
|
||||||
ON
|
ON
|
||||||
reminders.channel_id = channels.id
|
reminders.channel_id = channels.id
|
||||||
LEFT JOIN
|
|
||||||
users
|
|
||||||
ON
|
|
||||||
reminders.set_by = users.id
|
|
||||||
WHERE
|
WHERE
|
||||||
reminders.id = ?
|
reminders.id = ?
|
||||||
",
|
",
|
||||||
@ -166,17 +158,13 @@ impl Reminder {
|
|||||||
reminders.enabled,
|
reminders.enabled,
|
||||||
reminders.content,
|
reminders.content,
|
||||||
reminders.embed_description,
|
reminders.embed_description,
|
||||||
users.user AS set_by
|
reminders.set_by
|
||||||
FROM
|
FROM
|
||||||
reminders
|
reminders
|
||||||
INNER JOIN
|
INNER JOIN
|
||||||
channels
|
channels
|
||||||
ON
|
ON
|
||||||
reminders.channel_id = channels.id
|
reminders.channel_id = channels.id
|
||||||
LEFT JOIN
|
|
||||||
users
|
|
||||||
ON
|
|
||||||
reminders.set_by = users.id
|
|
||||||
WHERE
|
WHERE
|
||||||
`status` = 'pending' AND
|
`status` = 'pending' AND
|
||||||
channels.channel = ? AND
|
channels.channel = ? AND
|
||||||
@ -230,17 +218,13 @@ impl Reminder {
|
|||||||
reminders.enabled,
|
reminders.enabled,
|
||||||
reminders.content,
|
reminders.content,
|
||||||
reminders.embed_description,
|
reminders.embed_description,
|
||||||
users.user AS set_by
|
reminders.set_by
|
||||||
FROM
|
FROM
|
||||||
reminders
|
reminders
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
channels
|
channels
|
||||||
ON
|
ON
|
||||||
channels.id = reminders.channel_id
|
channels.id = reminders.channel_id
|
||||||
LEFT JOIN
|
|
||||||
users
|
|
||||||
ON
|
|
||||||
reminders.set_by = users.id
|
|
||||||
WHERE
|
WHERE
|
||||||
`status` = 'pending' AND
|
`status` = 'pending' AND
|
||||||
FIND_IN_SET(channels.channel, ?)
|
FIND_IN_SET(channels.channel, ?)
|
||||||
@ -266,17 +250,13 @@ impl Reminder {
|
|||||||
reminders.enabled,
|
reminders.enabled,
|
||||||
reminders.content,
|
reminders.content,
|
||||||
reminders.embed_description,
|
reminders.embed_description,
|
||||||
users.user AS set_by
|
reminders.set_by
|
||||||
FROM
|
FROM
|
||||||
reminders
|
reminders
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
channels
|
channels
|
||||||
ON
|
ON
|
||||||
channels.id = reminders.channel_id
|
channels.id = reminders.channel_id
|
||||||
LEFT JOIN
|
|
||||||
users
|
|
||||||
ON
|
|
||||||
reminders.set_by = users.id
|
|
||||||
WHERE
|
WHERE
|
||||||
`status` = 'pending' AND
|
`status` = 'pending' AND
|
||||||
channels.guild_id = (SELECT id FROM guilds WHERE guild = ?)
|
channels.guild_id = (SELECT id FROM guilds WHERE guild = ?)
|
||||||
@ -303,20 +283,16 @@ impl Reminder {
|
|||||||
reminders.enabled,
|
reminders.enabled,
|
||||||
reminders.content,
|
reminders.content,
|
||||||
reminders.embed_description,
|
reminders.embed_description,
|
||||||
users.user AS set_by
|
reminders.set_by
|
||||||
FROM
|
FROM
|
||||||
reminders
|
reminders
|
||||||
INNER JOIN
|
INNER JOIN
|
||||||
channels
|
channels
|
||||||
ON
|
ON
|
||||||
channels.id = reminders.channel_id
|
channels.id = reminders.channel_id
|
||||||
LEFT JOIN
|
|
||||||
users
|
|
||||||
ON
|
|
||||||
reminders.set_by = users.id
|
|
||||||
WHERE
|
WHERE
|
||||||
`status` = 'pending' AND
|
`status` = 'pending' AND
|
||||||
channels.id = (SELECT dm_channel FROM users WHERE user = ?)
|
channels.id = (SELECT dm_channel FROM users WHERE id = ?)
|
||||||
",
|
",
|
||||||
user.get()
|
user.get()
|
||||||
)
|
)
|
||||||
|
@ -16,17 +16,15 @@ pub async fn get_guild_roles(id: u64, cookies: &CookieJar<'_>, ctx: &State<Conte
|
|||||||
offline!(Ok(json!(vec![RoleInfo { name: "@everyone".to_string(), id: "1".to_string() }])));
|
offline!(Ok(json!(vec![RoleInfo { name: "@everyone".to_string(), id: "1".to_string() }])));
|
||||||
check_authorization(cookies, ctx.inner(), id).await?;
|
check_authorization(cookies, ctx.inner(), id).await?;
|
||||||
|
|
||||||
let roles_res = ctx.cache.guild_roles(id);
|
let roles_res = ctx.cache.guild(id).map(|g| {
|
||||||
|
g.roles
|
||||||
match roles_res {
|
|
||||||
Some(roles) => {
|
|
||||||
let roles = roles
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(_, r)| RoleInfo { id: r.id.to_string(), name: r.name.to_string() })
|
.map(|(_, r)| RoleInfo { id: r.id.to_string(), name: r.name.to_string() })
|
||||||
.collect::<Vec<RoleInfo>>();
|
.collect::<Vec<RoleInfo>>()
|
||||||
|
});
|
||||||
|
|
||||||
Ok(json!(roles))
|
match roles_res {
|
||||||
}
|
Some(roles) => Ok(json!(roles)),
|
||||||
None => {
|
None => {
|
||||||
warn!("Could not fetch roles from {}", id);
|
warn!("Could not fetch roles from {}", id);
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ use std::env;
|
|||||||
|
|
||||||
use chrono_tz::Tz;
|
use chrono_tz::Tz;
|
||||||
pub use guilds::*;
|
pub use guilds::*;
|
||||||
|
use log::warn;
|
||||||
pub use reminders::*;
|
pub use reminders::*;
|
||||||
use rocket::{
|
use rocket::{
|
||||||
get,
|
get,
|
||||||
@ -57,7 +58,7 @@ pub async fn get_user_info(
|
|||||||
patreon: true,
|
patreon: true,
|
||||||
preferences: UserPreferences {
|
preferences: UserPreferences {
|
||||||
timezone: "UTC".to_string(),
|
timezone: "UTC".to_string(),
|
||||||
use_browser_timezone: false,
|
use_browser_timezone: true,
|
||||||
dashboard_color_scheme: "system".to_string(),
|
dashboard_color_scheme: "system".to_string(),
|
||||||
reset_inputs_on_create: false,
|
reset_inputs_on_create: false,
|
||||||
}
|
}
|
||||||
@ -70,10 +71,10 @@ pub async fn get_user_info(
|
|||||||
.member(&ctx.inner(), user_id)
|
.member(&ctx.inner(), user_id)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
let prefs = sqlx::query!(
|
let preferences = sqlx::query!(
|
||||||
"
|
"
|
||||||
SELECT
|
SELECT
|
||||||
IFNULL(timezone, 'UTC') AS timezone,
|
timezone,
|
||||||
use_browser_timezone,
|
use_browser_timezone,
|
||||||
dashboard_color_scheme,
|
dashboard_color_scheme,
|
||||||
reset_inputs_on_create
|
reset_inputs_on_create
|
||||||
@ -84,7 +85,20 @@ pub async fn get_user_info(
|
|||||||
)
|
)
|
||||||
.fetch_one(pool.inner())
|
.fetch_one(pool.inner())
|
||||||
.await
|
.await
|
||||||
.map_or(None, |q| Some(q.timezone));
|
.map_or(
|
||||||
|
UserPreferences {
|
||||||
|
timezone: "UTC".to_string(),
|
||||||
|
use_browser_timezone: false,
|
||||||
|
dashboard_color_scheme: "system".to_string(),
|
||||||
|
reset_inputs_on_create: false,
|
||||||
|
},
|
||||||
|
|q| UserPreferences {
|
||||||
|
timezone: q.timezone,
|
||||||
|
use_browser_timezone: q.use_browser_timezone != 0,
|
||||||
|
dashboard_color_scheme: q.dashboard_color_scheme,
|
||||||
|
reset_inputs_on_create: q.reset_inputs_on_create != 0,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
let user_info = UserInfo {
|
let user_info = UserInfo {
|
||||||
name: cookies
|
name: cookies
|
||||||
@ -95,12 +109,7 @@ pub async fn get_user_info(
|
|||||||
.roles
|
.roles
|
||||||
.contains(&RoleId::new(env::var("PATREON_ROLE_ID").unwrap().parse().unwrap()))
|
.contains(&RoleId::new(env::var("PATREON_ROLE_ID").unwrap().parse().unwrap()))
|
||||||
}),
|
}),
|
||||||
preferences: UserPreferences {
|
preferences,
|
||||||
timezone: prefs.timezone,
|
|
||||||
use_browser_timezone: prefs.use_browser_timezone,
|
|
||||||
dashboard_color_scheme: prefs.dashboard_color_scheme,
|
|
||||||
reset_inputs_on_create: prefs.reset_inputs_on_create,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
json!(user_info)
|
json!(user_info)
|
||||||
@ -137,7 +146,7 @@ pub async fn update_user_info(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(dashboard_color_scheme) = &preferences.dashboard_color_scheme {
|
if let Some(dashboard_color_scheme) = &preferences.dashboard_color_scheme {
|
||||||
if vec!["system", "light", "dark"].contains(dashboard_color_scheme) {
|
if vec!["system", "light", "dark"].contains(&dashboard_color_scheme.as_str()) {
|
||||||
let _ = sqlx::query!(
|
let _ = sqlx::query!(
|
||||||
"
|
"
|
||||||
UPDATE users
|
UPDATE users
|
||||||
@ -154,10 +163,42 @@ pub async fn update_user_info(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo handle other two options
|
if let Some(reset_inputs_on_create) = &preferences.reset_inputs_on_create {
|
||||||
|
let _ = sqlx::query!(
|
||||||
|
"
|
||||||
|
UPDATE users
|
||||||
|
SET reset_inputs_on_create = ?
|
||||||
|
WHERE id = ?
|
||||||
|
",
|
||||||
|
reset_inputs_on_create,
|
||||||
|
user_id,
|
||||||
|
)
|
||||||
|
.execute(transaction.executor())
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
transaction.commit().await;
|
if let Some(use_browser_timezone) = &preferences.use_browser_timezone {
|
||||||
json!({})
|
let _ = sqlx::query!(
|
||||||
|
"
|
||||||
|
UPDATE users
|
||||||
|
SET use_browser_timezone = ?
|
||||||
|
WHERE id = ?
|
||||||
|
",
|
||||||
|
use_browser_timezone,
|
||||||
|
user_id,
|
||||||
|
)
|
||||||
|
.execute(transaction.executor())
|
||||||
|
.await;
|
||||||
|
}
|
||||||
|
|
||||||
|
match transaction.commit().await {
|
||||||
|
Ok(_) => json!({}),
|
||||||
|
Err(e) => {
|
||||||
|
warn!("Error updating user preferences for {}: {:?}", user_id, e);
|
||||||
|
|
||||||
|
json!({"error": "Couldn't update preferences"})
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
json!({"error": "Not authorized"})
|
json!({"error": "Not authorized"})
|
||||||
}
|
}
|
||||||
|
@ -593,18 +593,11 @@ pub(crate) async fn create_reminder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn check_channel_matches_guild(ctx: &Context, channel_id: ChannelId, guild_id: GuildId) -> bool {
|
fn check_channel_matches_guild(ctx: &Context, channel_id: ChannelId, guild_id: GuildId) -> bool {
|
||||||
// validate channel
|
return match ctx.cache.guild(guild_id) {
|
||||||
let channel = channel_id.to_channel_cached(&ctx.cache);
|
Some(guild) => guild.channels.get(&channel_id).is_some(),
|
||||||
let channel_exists = channel.is_some();
|
|
||||||
|
|
||||||
if !channel_exists {
|
None => false,
|
||||||
return false;
|
};
|
||||||
}
|
|
||||||
|
|
||||||
let channel_matches_guild =
|
|
||||||
channel.map_or(false, |c| c.guild(&ctx.cache).map_or(false, |g| g.id == guild_id));
|
|
||||||
|
|
||||||
channel_matches_guild
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn create_database_channel(
|
async fn create_database_channel(
|
||||||
|
@ -100,14 +100,6 @@ div.split-controls {
|
|||||||
flex-basis: 50%;
|
flex-basis: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.reminderContent {
|
|
||||||
margin-top: 10px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
padding: 14px;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left-pad {
|
.left-pad {
|
||||||
padding-left: 1rem;
|
padding-left: 1rem;
|
||||||
padding-right: 0.2rem;
|
padding-right: 0.2rem;
|
||||||
@ -214,18 +206,6 @@ div.dashboard-frame {
|
|||||||
min-width: auto;
|
min-width: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu a {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu .menu-label {
|
|
||||||
color: #bbb;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu {
|
|
||||||
padding-left: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dashboard-navbar {
|
.dashboard-navbar {
|
||||||
background-color: #8fb677 !important;
|
background-color: #8fb677 !important;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -680,14 +660,6 @@ div.reminderError .reminderMessage {
|
|||||||
margin: 0 12px 12px 12px;
|
margin: 0 12px 12px 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button.is-success:not(.is-outlined) {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button.is-outlined.is-success {
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
a.switch-pane {
|
a.switch-pane {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -733,27 +705,3 @@ a.switch-pane.is-active ~ .guild-submenu {
|
|||||||
.is-locked .field:last-of-type {
|
.is-locked .field:last-of-type {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.stat-row {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-box {
|
|
||||||
flex-grow: 1;
|
|
||||||
border-radius: 6px;
|
|
||||||
background-color: #fcfcfc;
|
|
||||||
border-color: #efefef;
|
|
||||||
border-style: solid;
|
|
||||||
border-width: 1px;
|
|
||||||
margin: 4px;
|
|
||||||
padding: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.figure {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.figure-num {
|
|
||||||
font-size: 2rem;
|
|
||||||
}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user