Extend create reminder
This commit is contained in:
		@@ -48,7 +48,7 @@ export type Reminder = {
 | 
			
		||||
    utc_time: DateTime;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
type ChannelInfo = {
 | 
			
		||||
export type ChannelInfo = {
 | 
			
		||||
    id: string;
 | 
			
		||||
    name: string;
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,9 @@
 | 
			
		||||
import { useQuery } from "react-query";
 | 
			
		||||
import { useParams } from "wouter";
 | 
			
		||||
import { fetchGuildChannels } from "../../api";
 | 
			
		||||
import { useReminder } from "./ReminderContext";
 | 
			
		||||
 | 
			
		||||
export const ChannelSelector = () => {
 | 
			
		||||
export const ChannelSelector = ({ channel, setChannel }) => {
 | 
			
		||||
    const { guild } = useParams();
 | 
			
		||||
 | 
			
		||||
    const [reminder, setReminder] = useReminder();
 | 
			
		||||
 | 
			
		||||
    const { isSuccess, data } = useQuery(fetchGuildChannels(guild));
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
@@ -17,15 +13,12 @@ export const ChannelSelector = () => {
 | 
			
		||||
                    name="channel"
 | 
			
		||||
                    class="channel-selector"
 | 
			
		||||
                    onInput={(ev) => {
 | 
			
		||||
                        setReminder((reminder) => ({
 | 
			
		||||
                            ...reminder,
 | 
			
		||||
                            channel: ev.currentTarget.value,
 | 
			
		||||
                        }));
 | 
			
		||||
                        setChannel(ev.currentTarget.value);
 | 
			
		||||
                    }}
 | 
			
		||||
                >
 | 
			
		||||
                    {isSuccess &&
 | 
			
		||||
                        data.map((c) => (
 | 
			
		||||
                            <option value={c.id} selected={c.id === reminder.channel}>
 | 
			
		||||
                            <option value={c.id} selected={c.id === channel}>
 | 
			
		||||
                                {c.name}
 | 
			
		||||
                            </option>
 | 
			
		||||
                        ))}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,30 +1,30 @@
 | 
			
		||||
import { useParams } from "wouter";
 | 
			
		||||
import { useState } from "preact/hooks";
 | 
			
		||||
import { useQuery } from "react-query";
 | 
			
		||||
import { fetchUserInfo, Reminder } from "../../api";
 | 
			
		||||
import { fetchGuildChannels, Reminder } from "../../api";
 | 
			
		||||
import { DateTime } from "luxon";
 | 
			
		||||
import { CreateButtonRow } from "./ButtonRow/CreateButtonRow";
 | 
			
		||||
import { TopBar } from "./TopBar";
 | 
			
		||||
import { Message } from "./Message";
 | 
			
		||||
import { Settings } from "./Settings";
 | 
			
		||||
import { ReminderContext } from "./ReminderContext";
 | 
			
		||||
import { useQuery } from "react-query";
 | 
			
		||||
import { useParams } from "wouter";
 | 
			
		||||
 | 
			
		||||
function defaultReminder(): Reminder {
 | 
			
		||||
    return {
 | 
			
		||||
        attachment: "",
 | 
			
		||||
        attachment_name: "",
 | 
			
		||||
        avatar: "",
 | 
			
		||||
        channel: "",
 | 
			
		||||
        attachment: null,
 | 
			
		||||
        attachment_name: null,
 | 
			
		||||
        avatar: null,
 | 
			
		||||
        channel: null,
 | 
			
		||||
        content: "",
 | 
			
		||||
        embed_author: "",
 | 
			
		||||
        embed_author_url: "",
 | 
			
		||||
        embed_author_url: null,
 | 
			
		||||
        embed_color: 0,
 | 
			
		||||
        embed_description: "",
 | 
			
		||||
        embed_fields: [],
 | 
			
		||||
        embed_footer: "",
 | 
			
		||||
        embed_footer_url: "",
 | 
			
		||||
        embed_image_url: "",
 | 
			
		||||
        embed_thumbnail_url: "",
 | 
			
		||||
        embed_footer_url: null,
 | 
			
		||||
        embed_image_url: null,
 | 
			
		||||
        embed_thumbnail_url: null,
 | 
			
		||||
        embed_title: "",
 | 
			
		||||
        enabled: true,
 | 
			
		||||
        expires: null,
 | 
			
		||||
@@ -41,9 +41,20 @@ function defaultReminder(): Reminder {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const CreateReminder = () => {
 | 
			
		||||
    const [reminder, setReminder] = useState(defaultReminder);
 | 
			
		||||
    const { guild } = useParams();
 | 
			
		||||
 | 
			
		||||
    const [reminder, setReminder] = useState(defaultReminder());
 | 
			
		||||
    const [collapsed, setCollapsed] = useState(false);
 | 
			
		||||
 | 
			
		||||
    const { isSuccess, data: guildChannels } = useQuery(fetchGuildChannels(guild));
 | 
			
		||||
 | 
			
		||||
    if (isSuccess && reminder.channel === null) {
 | 
			
		||||
        setReminder((reminder) => ({
 | 
			
		||||
            ...reminder,
 | 
			
		||||
            channel: reminder.channel || guildChannels[0].id,
 | 
			
		||||
        }));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <ReminderContext.Provider value={[reminder, setReminder]}>
 | 
			
		||||
            <div class={collapsed ? "reminderContent is-collapsed" : "reminderContent"}>
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ import { Reminder } from "../../../api";
 | 
			
		||||
type Props = {
 | 
			
		||||
    name: string;
 | 
			
		||||
    icon: string;
 | 
			
		||||
    setReminder: (r: (reminder: Reminder) => void) => void;
 | 
			
		||||
    setReminder: (r: (reminder: Reminder) => Reminder) => void;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const Author = ({ name, icon, setReminder }: Props) => {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,7 @@ import { Reminder } from "../../../api";
 | 
			
		||||
 | 
			
		||||
type Props = {
 | 
			
		||||
    color: string;
 | 
			
		||||
    setReminder: (r: (reminder: Reminder) => void) => void;
 | 
			
		||||
    setReminder: (r: (reminder: Reminder) => Reminder) => void;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function colorToInt(hex: string) {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@ import { ImagePicker } from "../ImagePicker";
 | 
			
		||||
type Props = {
 | 
			
		||||
    footer: string;
 | 
			
		||||
    icon: string;
 | 
			
		||||
    setReminder: (r: (reminder: Reminder) => void) => void;
 | 
			
		||||
    setReminder: (r: (reminder: Reminder) => Reminder) => void;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const Footer = ({ footer, icon, setReminder }: Props) => (
 | 
			
		||||
 
 | 
			
		||||
@@ -5,6 +5,7 @@ import { Footer } from "./Footer";
 | 
			
		||||
import { Color } from "./Color";
 | 
			
		||||
import { Reminder } from "../../../api";
 | 
			
		||||
import { ImagePicker } from "../ImagePicker";
 | 
			
		||||
import { useReminder } from "../ReminderContext";
 | 
			
		||||
 | 
			
		||||
function intToColor(num: number) {
 | 
			
		||||
    return `#${num.toString(16).padStart(6, "0")}`;
 | 
			
		||||
@@ -12,7 +13,9 @@ function intToColor(num: number) {
 | 
			
		||||
 | 
			
		||||
const DEFAULT_COLOR = 9418359;
 | 
			
		||||
 | 
			
		||||
export const Embed = ({ reminder, setReminder }) => {
 | 
			
		||||
export const Embed = () => {
 | 
			
		||||
    const [reminder, setReminder] = useReminder();
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <div
 | 
			
		||||
            class="discord-embed"
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
import { useState } from "preact/hooks";
 | 
			
		||||
import { useEffect, useState } from "preact/hooks";
 | 
			
		||||
import { useReminder } from "./ReminderContext";
 | 
			
		||||
 | 
			
		||||
function divmod(a: number, b: number) {
 | 
			
		||||
    return [Math.floor(a / b), a % b];
 | 
			
		||||
@@ -13,16 +14,37 @@ function secondsToHMS(seconds: number) {
 | 
			
		||||
    return [hours, minutes, seconds];
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const IntervalSelector = ({ months: monthsProp, days: daysProp, seconds: secondsProp }) => {
 | 
			
		||||
export const IntervalSelector = ({
 | 
			
		||||
    months: monthsProp,
 | 
			
		||||
    days: daysProp,
 | 
			
		||||
    seconds: secondsProp,
 | 
			
		||||
    setInterval,
 | 
			
		||||
    clearInterval,
 | 
			
		||||
}) => {
 | 
			
		||||
    const [months, setMonths] = useState(monthsProp);
 | 
			
		||||
    const [days, setDays] = useState(daysProp);
 | 
			
		||||
    const [seconds, setSeconds] = useState(secondsProp);
 | 
			
		||||
 | 
			
		||||
    let [hours, minutes, secondsRem] = [0, 0, 0];
 | 
			
		||||
    if (seconds !== null) {
 | 
			
		||||
        [hours, minutes, secondsRem] = secondsToHMS(seconds);
 | 
			
		||||
    let [_hours, _minutes, _seconds] = [0, 0, 0];
 | 
			
		||||
    if (secondsProp !== null) {
 | 
			
		||||
        [_hours, _minutes, _seconds] = secondsToHMS(secondsProp);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const [seconds, setSeconds] = useState(_seconds);
 | 
			
		||||
    const [minutes, setMinutes] = useState(_minutes);
 | 
			
		||||
    const [hours, setHours] = useState(_hours);
 | 
			
		||||
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        if (seconds || minutes || hours || days || months) {
 | 
			
		||||
            setInterval({
 | 
			
		||||
                seconds: seconds + minutes * 60 + hours * 3600,
 | 
			
		||||
                days: days,
 | 
			
		||||
                months: months,
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            clearInterval();
 | 
			
		||||
        }
 | 
			
		||||
    }, [seconds, minutes, hours, days, months]);
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <div class="control intervalSelector">
 | 
			
		||||
            <div class="input interval-group">
 | 
			
		||||
@@ -38,6 +60,9 @@ export const IntervalSelector = ({ months: monthsProp, days: daysProp, seconds:
 | 
			
		||||
                                maxlength={2}
 | 
			
		||||
                                placeholder=""
 | 
			
		||||
                                value={months || ""}
 | 
			
		||||
                                onInput={(ev) => {
 | 
			
		||||
                                    setMonths(parseInt(ev.currentTarget.value));
 | 
			
		||||
                                }}
 | 
			
		||||
                            ></input>{" "}
 | 
			
		||||
                            <span class="half-rem"></span> months, <span class="half-rem"></span>
 | 
			
		||||
                        </label>
 | 
			
		||||
@@ -51,6 +76,9 @@ export const IntervalSelector = ({ months: monthsProp, days: daysProp, seconds:
 | 
			
		||||
                                maxlength={4}
 | 
			
		||||
                                placeholder=""
 | 
			
		||||
                                value={days || ""}
 | 
			
		||||
                                onInput={(ev) => {
 | 
			
		||||
                                    setDays(parseInt(ev.currentTarget.value));
 | 
			
		||||
                                }}
 | 
			
		||||
                            ></input>{" "}
 | 
			
		||||
                            <span class="half-rem"></span> days, <span class="half-rem"></span>
 | 
			
		||||
                        </label>
 | 
			
		||||
@@ -66,6 +94,9 @@ export const IntervalSelector = ({ months: monthsProp, days: daysProp, seconds:
 | 
			
		||||
                                maxlength={2}
 | 
			
		||||
                                placeholder="HH"
 | 
			
		||||
                                value={hours || ""}
 | 
			
		||||
                                onInput={(ev) => {
 | 
			
		||||
                                    setHours(parseInt(ev.currentTarget.value));
 | 
			
		||||
                                }}
 | 
			
		||||
                            ></input>
 | 
			
		||||
                            :
 | 
			
		||||
                        </label>
 | 
			
		||||
@@ -79,6 +110,9 @@ export const IntervalSelector = ({ months: monthsProp, days: daysProp, seconds:
 | 
			
		||||
                                maxlength={2}
 | 
			
		||||
                                placeholder="MM"
 | 
			
		||||
                                value={minutes || ""}
 | 
			
		||||
                                onInput={(ev) => {
 | 
			
		||||
                                    setMinutes(parseInt(ev.currentTarget.value));
 | 
			
		||||
                                }}
 | 
			
		||||
                            ></input>
 | 
			
		||||
                            :
 | 
			
		||||
                        </label>
 | 
			
		||||
@@ -91,7 +125,10 @@ export const IntervalSelector = ({ months: monthsProp, days: daysProp, seconds:
 | 
			
		||||
                                name="interval_seconds"
 | 
			
		||||
                                maxlength={2}
 | 
			
		||||
                                placeholder="SS"
 | 
			
		||||
                                value={secondsRem || ""}
 | 
			
		||||
                                value={seconds || ""}
 | 
			
		||||
                                onInput={(ev) => {
 | 
			
		||||
                                    setSeconds(parseInt(ev.currentTarget.value));
 | 
			
		||||
                                }}
 | 
			
		||||
                            ></input>
 | 
			
		||||
                        </label>
 | 
			
		||||
                    </span>
 | 
			
		||||
@@ -102,6 +139,8 @@ export const IntervalSelector = ({ months: monthsProp, days: daysProp, seconds:
 | 
			
		||||
                        setMonths(0);
 | 
			
		||||
                        setDays(0);
 | 
			
		||||
                        setSeconds(0);
 | 
			
		||||
                        setMinutes(0);
 | 
			
		||||
                        setHours(0);
 | 
			
		||||
                    }}
 | 
			
		||||
                >
 | 
			
		||||
                    <span class="is-sr-only">Clear interval</span>
 | 
			
		||||
 
 | 
			
		||||
@@ -27,17 +27,9 @@ export const Message = () => {
 | 
			
		||||
                </figure>
 | 
			
		||||
                <div class="media-content">
 | 
			
		||||
                    <div class="content">
 | 
			
		||||
                        <Username
 | 
			
		||||
                            value={reminder.username}
 | 
			
		||||
                            onInput={(username: string) => {
 | 
			
		||||
                                setReminder((reminder) => ({
 | 
			
		||||
                                    ...reminder,
 | 
			
		||||
                                    username,
 | 
			
		||||
                                }));
 | 
			
		||||
                            }}
 | 
			
		||||
                        ></Username>
 | 
			
		||||
                        <Username />
 | 
			
		||||
                        <Content />
 | 
			
		||||
                        <Embed reminder={reminder} setReminder={setReminder}></Embed>
 | 
			
		||||
                        <Embed />
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </article>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,29 @@
 | 
			
		||||
export const Name = ({ value }) => (
 | 
			
		||||
    <div class="name-bar">
 | 
			
		||||
        <div class="field">
 | 
			
		||||
            <div class="control">
 | 
			
		||||
                <label class="label sr-only">Reminder Name</label>
 | 
			
		||||
                <input
 | 
			
		||||
                    class="input"
 | 
			
		||||
                    type="text"
 | 
			
		||||
                    name="name"
 | 
			
		||||
                    placeholder="Reminder Name"
 | 
			
		||||
                    maxlength={100}
 | 
			
		||||
                    value={value}
 | 
			
		||||
                ></input>
 | 
			
		||||
import { useReminder } from "./ReminderContext";
 | 
			
		||||
 | 
			
		||||
export const Name = () => {
 | 
			
		||||
    const [reminder, setReminder] = useReminder();
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <div class="name-bar">
 | 
			
		||||
            <div class="field">
 | 
			
		||||
                <div class="control">
 | 
			
		||||
                    <label class="label sr-only">Reminder Name</label>
 | 
			
		||||
                    <input
 | 
			
		||||
                        class="input"
 | 
			
		||||
                        type="text"
 | 
			
		||||
                        name="name"
 | 
			
		||||
                        placeholder="Reminder Name"
 | 
			
		||||
                        maxlength={100}
 | 
			
		||||
                        value={reminder.name}
 | 
			
		||||
                        onInput={(ev) => {
 | 
			
		||||
                            setReminder((reminder) => ({
 | 
			
		||||
                                ...reminder,
 | 
			
		||||
                                name: ev.currentTarget.value,
 | 
			
		||||
                            }));
 | 
			
		||||
                        }}
 | 
			
		||||
                    ></input>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
);
 | 
			
		||||
    );
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,15 @@ export const Settings = () => {
 | 
			
		||||
                        Channel*
 | 
			
		||||
                    </label>
 | 
			
		||||
                </div>
 | 
			
		||||
                <ChannelSelector />
 | 
			
		||||
                <ChannelSelector
 | 
			
		||||
                    channel={reminder.channel}
 | 
			
		||||
                    setChannel={(channel: string) => {
 | 
			
		||||
                        setReminder((reminder) => ({
 | 
			
		||||
                            ...reminder,
 | 
			
		||||
                            channel: channel,
 | 
			
		||||
                        }));
 | 
			
		||||
                    }}
 | 
			
		||||
                />
 | 
			
		||||
            </div>
 | 
			
		||||
 | 
			
		||||
            <div class="field">
 | 
			
		||||
@@ -65,6 +73,22 @@ export const Settings = () => {
 | 
			
		||||
                                months={reminder.interval_months}
 | 
			
		||||
                                days={reminder.interval_days}
 | 
			
		||||
                                seconds={reminder.interval_seconds}
 | 
			
		||||
                                setInterval={({ seconds, days, months }) => {
 | 
			
		||||
                                    setReminder((reminder) => ({
 | 
			
		||||
                                        ...reminder,
 | 
			
		||||
                                        interval_months: months,
 | 
			
		||||
                                        interval_days: days,
 | 
			
		||||
                                        interval_seconds: seconds,
 | 
			
		||||
                                    }));
 | 
			
		||||
                                }}
 | 
			
		||||
                                clearInterval={() => {
 | 
			
		||||
                                    setReminder((reminder) => ({
 | 
			
		||||
                                        ...reminder,
 | 
			
		||||
                                        interval_months: null,
 | 
			
		||||
                                        interval_days: null,
 | 
			
		||||
                                        interval_seconds: null,
 | 
			
		||||
                                    }));
 | 
			
		||||
                                }}
 | 
			
		||||
                            ></IntervalSelector>
 | 
			
		||||
                        </div>
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,13 +10,15 @@ export const TopBar = ({ toggleCollapsed }) => {
 | 
			
		||||
 | 
			
		||||
    const { isSuccess, data: guildChannels } = useQuery(fetchGuildChannels(guild));
 | 
			
		||||
 | 
			
		||||
    const channelName = (reminder: Reminder) =>
 | 
			
		||||
        guildChannels.find((c) => c.id === reminder.channel);
 | 
			
		||||
    const channelName = (reminder: Reminder) => {
 | 
			
		||||
        const channel = guildChannels.find((c) => c.id === reminder.channel);
 | 
			
		||||
        return channel === undefined ? "" : channel.name;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <div class="columns is-mobile column reminder-topbar">
 | 
			
		||||
            {isSuccess && <div class="invert-collapses channel-bar">#{channelName(reminder)}</div>}
 | 
			
		||||
            <Name value={reminder.name}></Name>
 | 
			
		||||
            <Name />
 | 
			
		||||
            <div class="hide-button-bar">
 | 
			
		||||
                <button class="button hide-box" onClick={toggleCollapsed}>
 | 
			
		||||
                    <span class="is-sr-only">Hide reminder</span>
 | 
			
		||||
 
 | 
			
		||||
@@ -1,4 +1,8 @@
 | 
			
		||||
export const Username = ({ value, onInput }) => {
 | 
			
		||||
import { useReminder } from "./ReminderContext";
 | 
			
		||||
 | 
			
		||||
export const Username = () => {
 | 
			
		||||
    const [reminder, setReminder] = useReminder();
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <div class="discord-message-header">
 | 
			
		||||
            <label class="is-sr-only">Username Override</label>
 | 
			
		||||
@@ -7,9 +11,12 @@ export const Username = ({ value, onInput }) => {
 | 
			
		||||
                placeholder="Username Override"
 | 
			
		||||
                maxlength={32}
 | 
			
		||||
                name="username"
 | 
			
		||||
                value={value}
 | 
			
		||||
                value={reminder.username}
 | 
			
		||||
                onInput={(ev) => {
 | 
			
		||||
                    onInput(ev.currentTarget.value);
 | 
			
		||||
                    setReminder((reminder) => ({
 | 
			
		||||
                        ...reminder,
 | 
			
		||||
                        username: ev.currentTarget.value,
 | 
			
		||||
                    }));
 | 
			
		||||
                }}
 | 
			
		||||
            ></input>
 | 
			
		||||
        </div>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user