diff --git a/public/api/specs/liljudd.json b/public/api/specs/liljudd.json index 2b35d6c..743d573 100644 --- a/public/api/specs/liljudd.json +++ b/public/api/specs/liljudd.json @@ -22,7 +22,7 @@ "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/bootConfig" + "$ref": "#/components/schemas/guildConfig" } } } @@ -382,20 +382,6 @@ }, "components": { "schemas": { - "bootConfig": { - "type": "object", - "properties": { - "guilds": { - "type": "array", - "items": { - "$ref": "#/components/schemas/guildConfig" - } - }, - "accessToken": { - "type": "string" - } - } - }, "guildConfig": { "type": "object", "properties": { @@ -520,17 +506,17 @@ "type": "array", "items": { "type": "string", - "format": "varchar(20)" - }, - "example": [ - "1234567890123456789", - "1234567890123456789", - "1234567890123456789", - "1234567890123456789", - "1234567890123456789", - "1234567890123456789", - "1234567890123456789" - ] + "format": "varchar(20)", + "example": [ + "1234567890123456789", + "1234567890123456789", + "1234567890123456789", + "1234567890123456789", + "1234567890123456789", + "1234567890123456789", + "1234567890123456789" + ] + } } } } diff --git a/src/routes/api/config/[guildId].tsx b/src/routes/api/config/[guildId].tsx deleted file mode 100644 index 53189ed..0000000 --- a/src/routes/api/config/[guildId].tsx +++ /dev/null @@ -1,111 +0,0 @@ -import { getSession } from "@auth/solid-start"; -import { APIEvent } from "@solidjs/start/server/types"; -import { eq } from "drizzle-orm"; -import moment from "moment-timezone"; -import createClient from "openapi-fetch"; -import db from "~/drizzle"; -import { accounts } from "~/drizzle/schema"; -import { authOptions } from "~/server/auth"; -import { paths } from "~/types/discord"; - -type data = { - success: boolean | null; - guild: { - id: string; - name: string | undefined; - icon: string | null | undefined; - channel: string; - channels: { - id: string; - name: string; - }[]; - }; - tzNames: string[]; -}; - -export const GET = async ( - event: APIEvent, -): Promise< - { success: false; message: string } | (data & { success: true }) -> => { - const id = event.params.guildId; - // const id = "598539452343648256"; - // const location = useLocation(); - if (!event) return { success: false, message: "No request event!" }; - - const session = await getSession(event.request, authOptions); - if (!session?.user?.id) - return { success: false, message: "No user with id!" }; - - const { DISCORD_ACCESS_TOKEN } = ( - await db - .selectDistinct({ DISCORD_ACCESS_TOKEN: accounts.access_token }) - .from(accounts) - .where(eq(accounts.userId, session.user?.id)) - .limit(1) - .execute() - )[0]; - if (!DISCORD_ACCESS_TOKEN) - return { success: false, message: "No discord access token!" }; - - const { GET } = createClient({ - baseUrl: "https://discord.com/api/v10", - }); - const guildsRequest = await GET("/users/@me/guilds", { - headers: { Authorization: `Bearer ${DISCORD_ACCESS_TOKEN}` }, - }); - const channelsRequest = await GET("/guilds/{guild_id}/channels", { - params: { - path: { - guild_id: id, - }, - }, - headers: { Authorization: `Bot ${import.meta.env.VITE_DISCORD_BOT_TOKEN}` }, - }); - - if (guildsRequest.error || channelsRequest.error) { - console.log(guildsRequest.error, channelsRequest.error, location.pathname); - return { - success: false, - message: "Error on one of the discord api requests!", - }; - } - - const guild = guildsRequest.data?.find((e) => e.id === id); - - if (!guild) - return { - success: false, - message: "User is in no such guild with requested id!", - }; - if (!(parseInt(guild.permissions) & (1 << 5))) - return { - success: false, - message: - "User is no MANAGE_GUILD permissions on this guild with requested id!", - }; - - let channels: data["guild"]["channels"] = []; - channelsRequest.data?.forEach((channel) => { - if (channel.type !== 0) return; - channels.push({ - id: channel.id, - name: channel.name, - }); - }); - - console.log("done"); - - return { - success: true, - guild: { - id: guild.id, - name: guild.name, - icon: guild.icon, - // channel: "1162917335275950180", - channel: "", - channels, - }, - tzNames: moment.tz.names(), - }; -}; diff --git a/src/routes/api/config/index.tsx b/src/routes/api/config/index.tsx deleted file mode 100644 index 1eec136..0000000 --- a/src/routes/api/config/index.tsx +++ /dev/null @@ -1,62 +0,0 @@ -import { getSession } from "@auth/solid-start"; -import { APIEvent } from "@solidjs/start/server/types"; -import { eq } from "drizzle-orm"; -import createClient from "openapi-fetch"; -import db from "~/drizzle"; -import { accounts } from "~/drizzle/schema"; -import { authOptions } from "~/server/auth"; -import { paths } from "~/types/discord"; - -type data = { - success: boolean | null; - guilds: { - id: string; - name: string; - icon: string | null | undefined; - }[]; -}; - -export const GET = async ( - event: APIEvent, -): Promise< - { success: false; message: string } | (data & { success: true }) -> => { - if (!event) return { success: false, message: "No request event!" }; - - const session = await getSession(event.request, authOptions); - if (!session?.user?.id) - return { success: false, message: "No user with id!" }; - - const { DISCORD_ACCESS_TOKEN } = ( - await db - .selectDistinct({ DISCORD_ACCESS_TOKEN: accounts.access_token }) - .from(accounts) - .where(eq(accounts.userId, session.user?.id)) - .limit(1) - .execute() - )[0]; - if (!DISCORD_ACCESS_TOKEN) - return { success: false, message: "No discord access token!" }; - - const { GET } = createClient({ - baseUrl: "https://discord.com/api/v10", - }); - const { data: guilds, error } = await GET("/users/@me/guilds", { - headers: { Authorization: `Bearer ${DISCORD_ACCESS_TOKEN}` }, - }); - - console.log("guilds", guilds); - - if (error) { - console.log(error); - return { success: false, message: "Error on discord api request!" }; - } - - return { - success: true, - guilds: - guilds - ?.filter((e) => parseInt(e.permissions) & (1 << 5)) - .map(({ id, name, icon }) => ({ id, name, icon })) ?? [], - }; -}; diff --git a/src/routes/config/[guildId].tsx b/src/routes/config/[guildId].tsx index 9e372c9..04501dc 100644 --- a/src/routes/config/[guildId].tsx +++ b/src/routes/config/[guildId].tsx @@ -1,15 +1,18 @@ +import { getSession } from "@auth/solid-start"; import { faToggleOff, faToggleOn } from "@fortawesome/pro-regular-svg-icons"; -import { useLocation, useNavigate, useParams } from "@solidjs/router"; -import { - For, - Index, - createEffect, - createResource, - createSignal, -} from "solid-js"; +import { useNavigate, useParams } from "@solidjs/router"; +import { eq } from "drizzle-orm"; +import moment from "moment-timezone"; +import createClient from "openapi-fetch"; +import { Index, createEffect, createResource, createSignal } from "solid-js"; import { createStore } from "solid-js/store"; +import { getRequestEvent } from "solid-js/web"; import { FontAwesomeIcon } from "~/components/FontAwesomeIcon"; import Layout from "~/components/Layout"; +import db from "~/drizzle"; +import { accounts } from "~/drizzle/schema"; +import { authOptions } from "~/server/auth"; +import { paths } from "~/types/discord"; import "../../styles/pages/config.scss"; const guessTZ = () => Intl.DateTimeFormat().resolvedOptions().timeZone; @@ -20,75 +23,113 @@ const initialValue = (params: ReturnType) => ({ id: params.guildId, name: undefined as string | undefined, icon: undefined as string | null | undefined, - channel: "", - channels: [] as { id: string; name: string }[], }, tzNames: [guessTZ()], }); +const getPayload = async ( + id: string, +): Promise< + | { success: false; message: string } + | (ReturnType & { success: true }) +> => { + "use server"; + const event = getRequestEvent(); + if (!event) return { success: false, message: "No request event!" }; + + const session = await getSession(event.request, authOptions); + if (!session?.user?.id) + return { success: false, message: "No user with id!" }; + + const { DISCORD_ACCESS_TOKEN } = ( + await db + .selectDistinct({ DISCORD_ACCESS_TOKEN: accounts.access_token }) + .from(accounts) + .where(eq(accounts.userId, session.user?.id)) + .limit(1) + .execute() + )[0]; + if (!DISCORD_ACCESS_TOKEN) + return { success: false, message: "No discord access token!" }; + + // const guilds = await fetch("https://discord.com/api/users/@me/guilds", { + // headers: { Authorization: `Bearer ${DISCORD_ACCESS_TOKEN}` }, + // }).then((res) => res.json()); + const { GET } = createClient({ + baseUrl: "https://discord.com/api/v10", + }); + const { data: guilds, error } = await GET("/users/@me/guilds", { + headers: { Authorization: `Bearer ${DISCORD_ACCESS_TOKEN}` }, + }); + + if (error) { + console.log(error); + return { success: false, message: "Error on discord api request!" }; + } + + const guild = guilds?.find((e) => e.id === id); + + if (!guild) + return { + success: false, + message: "User is in no such guild with requested id!", + }; + if (!(parseInt(guild.permissions) & (1 << 5))) + return { + success: false, + message: + "User is no MANAGE_GUILD permissions on this guild with requested id!", + }; + + return { + success: true, + guild: { + id: guild.id, + name: guild.name, + icon: guild.icon, + }, + // guild: guilds + // .filter((e: any) => e.permissions & (1 << 5)) + // .map((e: any) => e.name), + tzNames: moment.tz.names(), + }; +}; + function config() { const params = useParams(); const navigator = useNavigate(); - const location = useLocation(); - const [timezoneRef, setTimezoneRef] = createSignal(); - const [timePlanningRef, setTimePlanningRef] = - createSignal(); - const [channelRef, setChannelRef] = createSignal(); - const [pingableRolesRef, setPingableRolesRef] = + let [timezoneRef, setTimezoneRef] = createSignal(); + let [timePlanningRef, setTimePlanningRef] = createSignal(); + let [pingableRolesRef, setPingableRolesRef] = createSignal(); const [timezone, setTimezone] = createSignal(guessTZ()); - const [payload] = createResource( - params.guildId, - async (id) => { - const payload = await fetch(`http://localhost:3000/api/config/${id}`) - .then( - (res) => - res.json() as Promise< - | { - success: false; - message: string; - } - | (ReturnType & { - success: true; - }) - >, - ) - .catch((e) => console.warn(e, id)); + const [payload] = createResource(params.guildId, async (id) => { + const payload = await getPayload(id); - if (!payload) return initialValue(params); - - if (!payload.success) { - console.log(payload); - console.log(location.pathname, payload.message, "No success"); - // navigator("/config", { replace: false }); - return initialValue(params); - } - return payload; - }, - { initialValue: initialValue(params) }, - ); + if (!payload.success) { + console.log(payload.message, "No success"); + navigator("/config", { replace: false }); + return initialValue(params); + } + return payload; + }); + const guild = () => payload()?.guild ?? initialValue(params).guild; + const tzNames = () => payload()?.tzNames ?? []; const [config, setConfig] = createStore({ features: { timePlanning: { enabled: false, - channelId: "833442323160891452", pingableRoles: false, }, }, }); - createEffect(() => console.log(payload.loading, payload())); + createEffect(() => console.log(payload())); createEffect(() => console.log("timezone", timezone())); createEffect(() => console.log("timePlanning.enabled", config.features.timePlanning.enabled), ); - createEffect(() => - console.log( - "timePlanning.channelId", - config.features.timePlanning.channelId, - ), - ); createEffect(() => console.log( "timePlanning.pingableRoles", @@ -106,42 +147,11 @@ function config() { if (!ref) return; ref.checked = config.features.timePlanning.enabled; }); - createEffect(() => { - const channelId = payload().guild.channel; - setConfig("features", "timePlanning", "channelId", channelId); - console.log(channelId, payload()); - const ref = channelRef(); - if (!ref) return; - if ( - !ref || - !channelId || - !payload().guild.channels.find((e) => e.id === channelId) - ) - return; - ref.value = channelId; - }); createEffect(() => { const ref = pingableRolesRef(); if (!ref) return; ref.checked = config.features.timePlanning.pingableRoles; }); - createEffect(() => { - const ref = timezoneRef(); - if (!ref) return; - ref.value = timezone(); - }); - createEffect(() => { - const ref = timePlanningRef(); - if (!ref) return; - ref.checked = config.features.timePlanning.enabled; - }); - createEffect(() => { - const ref = pingableRolesRef(); - if (!ref) return; - ref.checked = config.features.timePlanning.pingableRoles; - }); - - // console.log(payload()); return ( @@ -152,15 +162,15 @@ function config() { Server pfp -

{payload().guild.name}

+

{guild()?.name ?? "li'l Judds home base"}

@@ -179,7 +189,7 @@ function config() { /> - + {(zone) => @@ -221,28 +231,12 @@ function config() { >
- + + + {(channel) => } + +
@@ -277,7 +271,6 @@ function config() {
-
diff --git a/src/routes/config/index.tsx b/src/routes/config/index.tsx index 207831a..e2de17c 100644 --- a/src/routes/config/index.tsx +++ b/src/routes/config/index.tsx @@ -1,12 +1,20 @@ +import { getSession } from "@auth/solid-start"; import { faBadgeCheck, faCircleExclamation, faPlus, } from "@fortawesome/pro-regular-svg-icons"; -import { useLocation, useNavigate } from "@solidjs/router"; -import { For, Suspense, createEffect, createResource } from "solid-js"; +import { useNavigate } from "@solidjs/router"; +import { eq } from "drizzle-orm"; +import createClient from "openapi-fetch"; +import { For, createResource } from "solid-js"; +import { getRequestEvent } from "solid-js/web"; import { FontAwesomeIcon } from "~/components/FontAwesomeIcon"; import Layout from "~/components/Layout"; +import db from "~/drizzle"; +import { accounts } from "~/drizzle/schema"; +import { authOptions } from "~/server/auth"; +import { paths } from "~/types/discord"; import "../../styles/pages/config.scss"; const initialValue = () => ({ @@ -18,40 +26,66 @@ const initialValue = () => ({ }[], }); +const getPayload = async (): Promise< + | { success: false; message: string } + | (ReturnType & { success: true }) +> => { + ("use server"); + const event = getRequestEvent(); + if (!event) return { success: false, message: "No request event!" }; + + const session = await getSession(event.request, authOptions); + if (!session?.user?.id) + return { success: false, message: "No user with id!" }; + + const { DISCORD_ACCESS_TOKEN } = ( + await db + .selectDistinct({ DISCORD_ACCESS_TOKEN: accounts.access_token }) + .from(accounts) + .where(eq(accounts.userId, session.user?.id)) + .limit(1) + .execute() + )[0]; + if (!DISCORD_ACCESS_TOKEN) + return { success: false, message: "No discord access token!" }; + + const { GET } = createClient({ + baseUrl: "https://discord.com/api/v10", + }); + const { data: guilds, error } = await GET("/users/@me/guilds", { + headers: { Authorization: `Bearer ${DISCORD_ACCESS_TOKEN}` }, + }); + + console.log("guilds", guilds); + + if (error) { + console.log(error); + return { success: false, message: "Error on discord api request!" }; + } + + return { + success: true, + guilds: + guilds + ?.filter((e) => parseInt(e.permissions) & (1 << 5)) + .map(({ id, name, icon }) => ({ id, name, icon })) ?? [], + }; +}; + function index() { const navigator = useNavigate(); - const location = useLocation(); const [payload] = createResource(async () => { - const payload = await fetch("http://localhost:3000/api/config") - .then( - (res) => - res.json() as Promise< - | { - success: false; - message: string; - } - | (ReturnType & { - success: true; - }) - >, - ) - .catch((e) => console.warn(e)); - - if (!payload) return; + const payload = await getPayload(); if (!payload.success) { - console.log(location.pathname, payload.message, "No success"); + console.log(payload.message, "No success"); navigator("/", { replace: false }); return initialValue(); } - console.log(location.pathname, "success"); + console.log("success"); return payload; }); - createEffect(() => console.log(payload()?.guilds, payload()?.guilds.length)); - // createRenderEffect(() => - // console.log(payload()?.guilds, payload()?.guilds.length), - // ); const icons = [faPlus, faCircleExclamation, faBadgeCheck]; const colors = [undefined, "orange", "green"]; @@ -60,39 +94,28 @@ function index() {

Configure li'l Judd in

- - - {(guild, i) => { - return ( - - Server pfp -

{guild.name}

- -
- ); - }} -
-
+ + {(guild, i) => ( + + Server pfp +

{guild.name}

+ +
+ )} +
);