From 57f31d487e3ba45b0ad48caec05b686682c7750a Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sat, 31 May 2025 02:55:44 +0200 Subject: [PATCH 01/71] fix: apiBase not including api version --- layouts/auth.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/layouts/auth.vue b/layouts/auth.vue index b3e234e..1c05f2d 100644 --- a/layouts/auth.vue +++ b/layouts/auth.vue @@ -56,6 +56,7 @@ const instanceUrl = ref(null); const instanceUrlInput = ref(); const instanceError = ref(); const requestUrl = useRequestURL(); +const apiVersion = useRuntimeConfig().public.apiVersion; const apiBase = useCookie("api_base"); const gorbTxtError = ref(""); @@ -92,7 +93,7 @@ async function selectInstance(e: Event) { const parsed = parseWellKnown(res._data as string); console.log("parsed:", parsed); if (parsed.ApiBaseUrl) { - apiBase.value = parsed.ApiBaseUrl; + apiBase.value = `${parsed.ApiBaseUrl}/v${apiVersion}`; console.log("set apiBase to:", parsed.ApiBaseUrl); const origin = new URL(res.url).origin; instanceUrl.value = origin; From fe1474416f1c74059ca0185f3ceda9976fa39e0c Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sat, 31 May 2025 14:27:37 +0200 Subject: [PATCH 02/71] feat: change all occurrences of server with guild --- components/InvitePopup.vue | 2 +- layouts/client.vue | 8 ++++---- pages/servers/[serverId]/index.vue | 4 ++-- utils/fetchMember.ts | 4 ++-- utils/fetchUser.ts | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/components/InvitePopup.vue b/components/InvitePopup.vue index ee6f124..f42a659 100644 --- a/components/InvitePopup.vue +++ b/components/InvitePopup.vue @@ -20,7 +20,7 @@ const route = useRoute(); async function generateInvite(): Promise { const createdInvite: InviteResponse | undefined = await fetchWithApi( - `/servers/${route.params.serverId}/invites`, + `/guilds/${route.params.guildId}/invites`, { method: "POST", body: { custom_id: "oijewfoiewf" } } ); diff --git a/layouts/client.vue b/layouts/client.vue index 1038412..52fb3c7 100644 --- a/layouts/client.vue +++ b/layouts/client.vue @@ -10,8 +10,8 @@ -
- +
+
@@ -26,7 +26,7 @@ import type { GuildResponse } from '~/types/interfaces'; const loading = useState("loading", () => false); -const servers: GuildResponse[] | undefined = await fetchWithApi("/me/guilds"); +const guilds: GuildResponse[] | undefined = await fetchWithApi("/me/guilds"); //const servers = await fetchWithApi("/servers") as { uuid: string, name: string, description: string }[]; //console.log("servers:", servers); @@ -169,7 +169,7 @@ const members = [ padding-bottom: 1dvh; } -#servers-list { +#guilds-list { display: flex; flex-direction: column; gap: 1dvh; diff --git a/pages/servers/[serverId]/index.vue b/pages/servers/[serverId]/index.vue index ce6bea5..cc3f36a 100644 --- a/pages/servers/[serverId]/index.vue +++ b/pages/servers/[serverId]/index.vue @@ -5,8 +5,8 @@ diff --git a/utils/fetchMember.ts b/utils/fetchMember.ts index 8f4a9e4..c6eadfb 100644 --- a/utils/fetchMember.ts +++ b/utils/fetchMember.ts @@ -1,6 +1,6 @@ import type { UserResponse } from "~/types/interfaces" -export default async (serverId: string, memberId: string): Promise => { - const user = await fetchWithApi(`/guilds/${serverId}/members/${memberId}`) as UserResponse; +export default async (guildId: string, memberId: string): Promise => { + const user = await fetchWithApi(`/guilds/${guildId}/members/${memberId}`) as UserResponse; return user; } diff --git a/utils/fetchUser.ts b/utils/fetchUser.ts index d509fe0..fbd3843 100644 --- a/utils/fetchUser.ts +++ b/utils/fetchUser.ts @@ -1,6 +1,6 @@ import type { UserResponse } from "~/types/interfaces" -export default async (serverId: string, userId: string): Promise => { +export default async (guildId: string, userId: string): Promise => { const user = await fetchWithApi(`/users/${userId}`) as UserResponse; return user; } From 4eeb3a8c2a0993c2772c7181283d866ed5ed281e Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sat, 31 May 2025 14:31:32 +0200 Subject: [PATCH 03/71] fix: fetching from malformed endpoints --- pages/servers/[serverId]/channels/[channelId].vue | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pages/servers/[serverId]/channels/[channelId].vue b/pages/servers/[serverId]/channels/[channelId].vue index cdb2c94..a921b24 100644 --- a/pages/servers/[serverId]/channels/[channelId].vue +++ b/pages/servers/[serverId]/channels/[channelId].vue @@ -102,9 +102,10 @@ const members = [ onMounted(async () => { console.log("channelid: set loading to true"); - server.value = await fetchWithApi(`servers/${route.params.serverId}`); + const serverUrl = `guilds/${route.params.serverId}`; + server.value = await fetchWithApi(serverUrl); - channels.value = await fetchWithApi(`/channels`); + channels.value = await fetchWithApi(`${serverUrl}/channels`); console.log("channels:", channels.value); channel.value = await fetchWithApi(route.path); console.log("channel:", channel.value); From aa710e0a4d48a3a507a788c71ea3a70ef26b563f Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sat, 31 May 2025 14:38:49 +0200 Subject: [PATCH 04/71] feat: rename some occurrences of guild back to server --- components/InvitePopup.vue | 2 +- layouts/client.vue | 6 +++--- pages/servers/[serverId]/channels/[channelId].vue | 12 ++++++------ pages/servers/[serverId]/index.vue | 2 +- utils/fetchMember.ts | 4 ++-- utils/fetchUser.ts | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/components/InvitePopup.vue b/components/InvitePopup.vue index f42a659..262507a 100644 --- a/components/InvitePopup.vue +++ b/components/InvitePopup.vue @@ -20,7 +20,7 @@ const route = useRoute(); async function generateInvite(): Promise { const createdInvite: InviteResponse | undefined = await fetchWithApi( - `/guilds/${route.params.guildId}/invites`, + `/guilds/${route.params.serverId}/invites`, { method: "POST", body: { custom_id: "oijewfoiewf" } } ); diff --git a/layouts/client.vue b/layouts/client.vue index 52fb3c7..312b0a5 100644 --- a/layouts/client.vue +++ b/layouts/client.vue @@ -10,8 +10,8 @@ -
- +
+
@@ -169,7 +169,7 @@ const members = [ padding-bottom: 1dvh; } -#guilds-list { +#servers-list { display: flex; flex-direction: column; gap: 1dvh; diff --git a/pages/servers/[serverId]/channels/[channelId].vue b/pages/servers/[serverId]/channels/[channelId].vue index a921b24..5458088 100644 --- a/pages/servers/[serverId]/channels/[channelId].vue +++ b/pages/servers/[serverId]/channels/[channelId].vue @@ -5,7 +5,7 @@

{{ server?.name }} - @@ -20,7 +20,7 @@
+ :href="`/servers/${route.params.serverId}/channels/${channel.uuid}`" />

@@ -102,10 +102,10 @@ const members = [ onMounted(async () => { console.log("channelid: set loading to true"); - const serverUrl = `guilds/${route.params.serverId}`; - server.value = await fetchWithApi(serverUrl); + const guildUrl = `guilds/${route.params.serverId}`; + server.value = await fetchWithApi(guildUrl); - channels.value = await fetchWithApi(`${serverUrl}/channels`); + channels.value = await fetchWithApi(`${guildUrl}/channels`); console.log("channels:", channels.value); channel.value = await fetchWithApi(route.path); console.log("channel:", channel.value); @@ -114,7 +114,7 @@ onMounted(async () => { console.log("channelid: set loading to false"); }); -function showServerSettings() { } +function showGuildSettings() { } function toggleInvitePopup(e: Event) { e.preventDefault(); diff --git a/pages/servers/[serverId]/index.vue b/pages/servers/[serverId]/index.vue index cc3f36a..28ee913 100644 --- a/pages/servers/[serverId]/index.vue +++ b/pages/servers/[serverId]/index.vue @@ -5,7 +5,7 @@ diff --git a/utils/fetchMember.ts b/utils/fetchMember.ts index c6eadfb..8f4a9e4 100644 --- a/utils/fetchMember.ts +++ b/utils/fetchMember.ts @@ -1,6 +1,6 @@ import type { UserResponse } from "~/types/interfaces" -export default async (guildId: string, memberId: string): Promise => { - const user = await fetchWithApi(`/guilds/${guildId}/members/${memberId}`) as UserResponse; +export default async (serverId: string, memberId: string): Promise => { + const user = await fetchWithApi(`/guilds/${serverId}/members/${memberId}`) as UserResponse; return user; } diff --git a/utils/fetchUser.ts b/utils/fetchUser.ts index fbd3843..d509fe0 100644 --- a/utils/fetchUser.ts +++ b/utils/fetchUser.ts @@ -1,6 +1,6 @@ import type { UserResponse } from "~/types/interfaces" -export default async (guildId: string, userId: string): Promise => { +export default async (serverId: string, userId: string): Promise => { const user = await fetchWithApi(`/users/${userId}`) as UserResponse; return user; } From 3c65a700ffcc05c343e51352468054bda5024e5a Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sat, 31 May 2025 14:46:01 +0200 Subject: [PATCH 05/71] fix: fetching from malformed endpoints, again --- pages/servers/[serverId]/channels/[channelId].vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pages/servers/[serverId]/channels/[channelId].vue b/pages/servers/[serverId]/channels/[channelId].vue index 5458088..ac36105 100644 --- a/pages/servers/[serverId]/channels/[channelId].vue +++ b/pages/servers/[serverId]/channels/[channelId].vue @@ -40,7 +40,7 @@ const route = useRoute(); const loading = useState("loading"); -const channelUrlPath = `/channels/${route.params.channelId}`; +const channelUrlPath = `channels/${route.params.channelId}`; const server = ref(); const channels = ref(); @@ -107,7 +107,7 @@ onMounted(async () => { channels.value = await fetchWithApi(`${guildUrl}/channels`); console.log("channels:", channels.value); - channel.value = await fetchWithApi(route.path); + channel.value = await fetchWithApi(`/channels/${route.params.channelId}`); console.log("channel:", channel.value); console.log("channelid: channel:", channel); From 4da2ede58a9fe4faa766211fec7ca526dae933af Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sat, 31 May 2025 14:50:44 +0200 Subject: [PATCH 06/71] feat: change grouped messages being called compact to grouped --- components/Message.vue | 4 ++-- components/MessageArea.vue | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/components/Message.vue b/components/Message.vue index bf85a17..32162c1 100644 --- a/components/Message.vue +++ b/components/Message.vue @@ -18,7 +18,7 @@
-
+
@@ -42,7 +42,7 @@ const props = defineProps<{ text: string, timestamp: number, format: "12" | "24", - type: "normal" | "compact", + type: "normal" | "grouped", marginBottom: boolean }>(); diff --git a/components/MessageArea.vue b/components/MessageArea.vue index 7d3520c..1688f6d 100644 --- a/components/MessageArea.vue +++ b/components/MessageArea.vue @@ -27,12 +27,13 @@ import scrollToBottom from '~/utils/scrollToBottom'; const props = defineProps<{ channelUrl: string, amount?: number, offset?: number }>(); const messageTimestamps = ref>({}); -const messagesType = ref>({}); +const messagesType = ref>({}); const messagesRes: MessageResponse[] | undefined = await fetchWithApi( `${props.channelUrl}/messages`, { query: { "amount": props.amount ?? 100, "offset": props.offset ?? 0 } } ); + if (messagesRes) { messagesRes.reverse(); console.log("messages res:", messagesRes.map(msg => msg.message)); @@ -77,7 +78,7 @@ if (messagesRes) { continue; } console.log("RETURNING " + lessThanMax.toString().toUpperCase()); - messagesType.value[message.uuid] = "compact"; + messagesType.value[message.uuid] = "grouped"; } } From 04af2be87f3d7fe86c5b7a1507174424f8434f70 Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sat, 31 May 2025 15:28:33 +0200 Subject: [PATCH 07/71] fix: message grouping when messages are received from websocket --- components/MessageArea.vue | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/components/MessageArea.vue b/components/MessageArea.vue index 1688f6d..71629dc 100644 --- a/components/MessageArea.vue +++ b/components/MessageArea.vue @@ -28,18 +28,15 @@ const props = defineProps<{ channelUrl: string, amount?: number, offset?: number const messageTimestamps = ref>({}); const messagesType = ref>({}); +const messageGroupingMaxDifference = useRuntimeConfig().public.messageGroupingMaxDifference const messagesRes: MessageResponse[] | undefined = await fetchWithApi( `${props.channelUrl}/messages`, { query: { "amount": props.amount ?? 100, "offset": props.offset ?? 0 } } ); -if (messagesRes) { - messagesRes.reverse(); - console.log("messages res:", messagesRes.map(msg => msg.message)); - const firstMessageByUsers = ref>({}); - for (const message of messagesRes) { - messageTimestamps.value[message.uuid] = uuidToTimestamp(message.uuid); +function groupMessage(message: MessageResponse) { + messageTimestamps.value[message.uuid] = uuidToTimestamp(message.uuid); console.log("message:", message.message); const firstByUser = firstMessageByUsers.value[message.user.uuid]; @@ -50,7 +47,7 @@ if (messagesRes) { firstMessageByUsers.value[message.user.uuid] = message; console.log("RETURNING FALSE"); messagesType.value[message.uuid] = "normal"; - continue; + return; } } else { console.log("first by user doesn't exist"); @@ -58,9 +55,9 @@ if (messagesRes) { firstMessageByUsers.value[message.user.uuid] = message; console.log("RETURNING FALSE"); messagesType.value[message.uuid] = "normal"; - continue; + return; } - const messageGroupingMaxDifference = useRuntimeConfig().public.messageGroupingMaxDifference; + const prevTimestamp = messageTimestamps.value[firstByUser.uuid]; const timestamp = messageTimestamps.value[message.uuid]; console.log("first message timestamp:", prevTimestamp); @@ -75,10 +72,18 @@ if (messagesRes) { console.log(`setting first post by user ${message.user.username} to "${message.message}" with timestamp ${messageTimestamps.value[message.uuid]}`) firstMessageByUsers.value[message.user.uuid] = message; messagesType.value[message.uuid] = "normal"; - continue; + return; } console.log("RETURNING " + lessThanMax.toString().toUpperCase()); messagesType.value[message.uuid] = "grouped"; +} + +const firstMessageByUsers = ref>({}); +if (messagesRes) { + messagesRes.reverse(); + console.log("messages res:", messagesRes.map(msg => msg.message)); + for (const message of messagesRes) { + groupMessage(message); } } @@ -116,7 +121,10 @@ if (accessToken && apiBase) { console.log("event data:", event.data); console.log("message uuid:", event.data.uuid); const parsedData = JSON.parse(event.data); - messageTimestamps.value[parsedData.uuid] = uuidToTimestamp(parsedData.uuid); + + groupMessage(parsedData); + console.log("parsed message type:", messagesType.value[parsedData.uuid]); + console.log("parsed message timestamp:", messageTimestamps.value[parsedData.uuid]); messages.value.push(parsedData); await nextTick(); if (messagesElement.value) { From 310b1cc2df61d5cf9a99476fdb1c328e52d0d114 Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sat, 31 May 2025 15:28:50 +0200 Subject: [PATCH 08/71] feat: remove unnecessary log statement --- components/Message.vue | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/Message.vue b/components/Message.vue index 32162c1..941d9a8 100644 --- a/components/Message.vue +++ b/components/Message.vue @@ -75,12 +75,10 @@ if (props.format == "12") { onMounted(() => { messageElement.value?.addEventListener("mouseenter", (e: Event) => { - console.log("mouse enter"); dateHidden.value = false; }); messageElement.value?.addEventListener("mouseleave", (e: Event) => { - console.log("mouse leave"); dateHidden.value = true; }); }); From 115b7d834118aa944700f6242b02c5031be130ce Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sat, 31 May 2025 16:31:40 +0200 Subject: [PATCH 09/71] feat: remove old utils in favor of api composable --- composables/api.ts | 57 ++++++++++++++++++++++++++++++++++++++++++++ utils/fetchMember.ts | 6 ----- utils/fetchUser.ts | 6 ----- 3 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 composables/api.ts delete mode 100644 utils/fetchMember.ts delete mode 100644 utils/fetchUser.ts diff --git a/composables/api.ts b/composables/api.ts new file mode 100644 index 0000000..f1ac525 --- /dev/null +++ b/composables/api.ts @@ -0,0 +1,57 @@ +import type { ChannelResponse, GuildResponse, MessageResponse } from "~/types/interfaces"; + +export const useApi = () => { + async function fetchGuilds(guildId: string): Promise { + return await fetchWithApi(`/guilds`); + } + + async function fetchGuild(guildId: string): Promise { + return await fetchWithApi(`/guilds/${guildId}`); + } + + async function fetchChannels(guildId: string): Promise { + return await fetchWithApi(`/guilds/${guildId}/channels`); + } + + async function fetchChannel(channelId: string): Promise { + return await fetchWithApi(`/channels/${channelId}`) + } + + + async function fetchMembers(guildId: string) { + return await fetchWithApi(`/guilds/${guildId}/members`); + } + + async function fetchMember(guildId: string, memberId: string) { + return await fetchWithApi(`/guilds/${guildId}/members/${memberId}`); + } + + async function fetchUsers(userId: string) { + return await fetchWithApi(`/users`); + } + + async function fetchUser(userId: string) { + return await fetchWithApi(`/users/${userId}`); + } + + async function fetchMessages(channelId: string): Promise { + return await fetchWithApi(`/channels/${channelId}/messages`); + } + + async function fetchMessage(channelId: string, messageId: string): Promise { + return await fetchWithApi(`/channels/${channelId}/messages/${messageId}`); + } + + return { + fetchGuilds, + fetchGuild, + fetchChannels, + fetchChannel, + fetchMembers, + fetchMember, + fetchUsers, + fetchUser, + fetchMessages, + fetchMessage + } +} diff --git a/utils/fetchMember.ts b/utils/fetchMember.ts deleted file mode 100644 index 8f4a9e4..0000000 --- a/utils/fetchMember.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { UserResponse } from "~/types/interfaces" - -export default async (serverId: string, memberId: string): Promise => { - const user = await fetchWithApi(`/guilds/${serverId}/members/${memberId}`) as UserResponse; - return user; -} diff --git a/utils/fetchUser.ts b/utils/fetchUser.ts deleted file mode 100644 index d509fe0..0000000 --- a/utils/fetchUser.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { UserResponse } from "~/types/interfaces" - -export default async (serverId: string, userId: string): Promise => { - const user = await fetchWithApi(`/users/${userId}`) as UserResponse; - return user; -} From 9a84315b64fe3ed3975cc2ef566d1bbef0063ede Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sat, 31 May 2025 16:32:04 +0200 Subject: [PATCH 10/71] fix: apiBase not including api version when automatically fetched --- layouts/auth.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layouts/auth.vue b/layouts/auth.vue index 1c05f2d..f12da45 100644 --- a/layouts/auth.vue +++ b/layouts/auth.vue @@ -67,7 +67,7 @@ if (status.value == "success" && gorbTxt.value) { console.log("got gorb.txt:", gorbTxt.value); const parsed = parseWellKnown(gorbTxt.value as string); if (parsed.ApiBaseUrl) { - apiBase.value = parsed.ApiBaseUrl; + apiBase.value = `${parsed.ApiBaseUrl}/${apiVersion}`; console.log("set apiBase to:", parsed.ApiBaseUrl); } } else { From 3fd28ed3fc1c877a274c4df9272a3857c24caabe Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sat, 31 May 2025 16:32:51 +0200 Subject: [PATCH 11/71] fix: /guilds/me variable expecting wrong response object type --- layouts/client.vue | 7 +++---- types/interfaces.ts | 8 ++++++++ 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/layouts/client.vue b/layouts/client.vue index 312b0a5..6f82bf3 100644 --- a/layouts/client.vue +++ b/layouts/client.vue @@ -11,7 +11,7 @@
- +
@@ -21,12 +21,11 @@ From 00d6eb0a00d6fa57868e38128bc190ef64611b93 Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sat, 31 May 2025 17:11:08 +0200 Subject: [PATCH 14/71] fix: missing return type in some fetch functions --- composables/api.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composables/api.ts b/composables/api.ts index f1ac525..c74f8f3 100644 --- a/composables/api.ts +++ b/composables/api.ts @@ -1,7 +1,7 @@ -import type { ChannelResponse, GuildResponse, MessageResponse } from "~/types/interfaces"; +import type { ChannelResponse, GuildMemberResponse, GuildResponse, MessageResponse } from "~/types/interfaces"; export const useApi = () => { - async function fetchGuilds(guildId: string): Promise { + async function fetchGuilds(): Promise { return await fetchWithApi(`/guilds`); } @@ -18,15 +18,15 @@ export const useApi = () => { } - async function fetchMembers(guildId: string) { + async function fetchMembers(guildId: string): Promise { return await fetchWithApi(`/guilds/${guildId}/members`); } - async function fetchMember(guildId: string, memberId: string) { + async function fetchMember(guildId: string, memberId: string): Promise { return await fetchWithApi(`/guilds/${guildId}/members/${memberId}`); } - async function fetchUsers(userId: string) { + async function fetchUsers() { return await fetchWithApi(`/users`); } From 1c5b13632314156e71098a7bdc3400fd76b945ce Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sat, 31 May 2025 17:12:07 +0200 Subject: [PATCH 15/71] feat: change to fetch guild members list and improve appearance of members list --- .../[serverId]/channels/[channelId].vue | 63 ++++--------------- 1 file changed, 13 insertions(+), 50 deletions(-) diff --git a/pages/servers/[serverId]/channels/[channelId].vue b/pages/servers/[serverId]/channels/[channelId].vue index ac36105..4f3e4ec 100644 --- a/pages/servers/[serverId]/channels/[channelId].vue +++ b/pages/servers/[serverId]/channels/[channelId].vue @@ -26,9 +26,9 @@
- - - {{ member.displayName }} + + + {{ member.user.display_name ?? member.user.username }}
@@ -52,53 +52,9 @@ import type { ChannelResponse, GuildResponse, MessageResponse } from "~/types/in //const servers = await fetchWithApi("/servers") as { uuid: string, name: string, description: string }[]; //console.log("channelid: servers:", servers); -const members = [ - { - id: "3287484395", - displayName: "SauceyRed", - avatar: "" - }, - { - id: "3287484395", - displayName: "JustTemmie", - avatar: "" - }, - { - id: "3287484395", - displayName: "GOIN!!!!!!", - avatar: "" - }, - { - id: "3287484395", - displayName: "SauceyRed", - avatar: "" - }, - { - id: "3287484395", - displayName: "Hatsune Miku Official", - avatar: "" - }, - { - id: "3287484395", - displayName: "Hatsune Miku Official", - avatar: "" - }, - { - id: "3287484395", - displayName: "Hatsune Miku Official", - avatar: "" - }, - { - id: "3287484395", - displayName: "SauceyRed", - avatar: "" - }, - { - id: "3287484395", - displayName: "SauceyRed", - avatar: "" - } -]; + +const { fetchMembers } = useApi(); +const members = await fetchMembers(route.params.serverId as string); onMounted(async () => { console.log("channelid: set loading to true"); @@ -129,6 +85,7 @@ function toggleInvitePopup(e: Event) { align-items: center; margin-top: .5em; margin-bottom: .5em; + gap: .5em; } #members-list { @@ -153,4 +110,10 @@ function toggleInvitePopup(e: Event) { gap: 1dvh; } +.member-avatar { + height: 2.3em; + width: 2.3em; + border-radius: 50%; +} + \ No newline at end of file From 4b2c3af5e552eec91a027a240dd7da589916b6fb Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sat, 31 May 2025 17:13:59 +0200 Subject: [PATCH 16/71] feat: change styling of message area a bit --- components/MessageArea.vue | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/MessageArea.vue b/components/MessageArea.vue index 4259365..ff523cf 100644 --- a/components/MessageArea.vue +++ b/components/MessageArea.vue @@ -175,6 +175,8 @@ onMounted(async () => { padding-bottom: 1dvh; padding-top: 1dvh; margin-bottom: 1dvh; + margin-left: 1dvw; + margin-right: 1dvw; } #message-form { @@ -196,6 +198,8 @@ onMounted(async () => { display: flex; flex-direction: column; gap: 1dvh; + padding-left: 1dvw; + padding-right: 1dvw; } #submit-button { From 417a558109be5cba5f72a804026d7f1168c2da0b Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sun, 1 Jun 2025 00:59:50 +0200 Subject: [PATCH 17/71] feat: update /me/guilds object response type --- layouts/client.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/layouts/client.vue b/layouts/client.vue index 6f82bf3..6c629da 100644 --- a/layouts/client.vue +++ b/layouts/client.vue @@ -11,7 +11,7 @@
- +
@@ -21,11 +21,11 @@ + + \ No newline at end of file diff --git a/components/settings/user_settings/Account.vue b/components/settings/user_settings/Account.vue new file mode 100644 index 0000000..8425cd8 --- /dev/null +++ b/components/settings/user_settings/Account.vue @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/pages/settings.vue b/pages/settings.vue new file mode 100644 index 0000000..8327370 --- /dev/null +++ b/pages/settings.vue @@ -0,0 +1,145 @@ + + + + + + + + \ No newline at end of file From 705b37fa06ab647a447295e4175f00bc1309bf66 Mon Sep 17 00:00:00 2001 From: JustTemmie <47639983+JustTemmie@users.noreply.github.com> Date: Sun, 1 Jun 2025 06:13:00 +0200 Subject: [PATCH 23/71] feat: button components --- components/buttons/Button.vue | 43 ++++++++++++++++++++++++++++++ components/buttons/ButtonScary.vue | 43 ++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 components/buttons/Button.vue create mode 100644 components/buttons/ButtonScary.vue diff --git a/components/buttons/Button.vue b/components/buttons/Button.vue new file mode 100644 index 0000000..20783c0 --- /dev/null +++ b/components/buttons/Button.vue @@ -0,0 +1,43 @@ + + + + + + + \ No newline at end of file diff --git a/components/buttons/ButtonScary.vue b/components/buttons/ButtonScary.vue new file mode 100644 index 0000000..71c0bc7 --- /dev/null +++ b/components/buttons/ButtonScary.vue @@ -0,0 +1,43 @@ + + + + + + + \ No newline at end of file From 39fb0a9eab26ed8d1035ed3604b5c4cbfe775605 Mon Sep 17 00:00:00 2001 From: JustTemmie <47639983+JustTemmie@users.noreply.github.com> Date: Sun, 1 Jun 2025 07:15:20 +0200 Subject: [PATCH 24/71] feat: start of "My Account" page, need API help --- .../settings/app_settings/Appearance.vue | 1 - components/settings/app_settings/Keybinds.vue | 12 +++ components/settings/app_settings/Language.vue | 12 +++ .../settings/app_settings/Notifications.vue | 12 +++ components/settings/user_settings/Account.vue | 28 ++++- .../settings/user_settings/Connections.vue | 12 +++ components/settings/user_settings/Devices.vue | 12 +++ components/settings/user_settings/Privacy.vue | 13 +++ pages/settings.vue | 101 ++++++++++-------- 9 files changed, 156 insertions(+), 47 deletions(-) create mode 100644 components/settings/app_settings/Keybinds.vue create mode 100644 components/settings/app_settings/Language.vue create mode 100644 components/settings/app_settings/Notifications.vue create mode 100644 components/settings/user_settings/Connections.vue create mode 100644 components/settings/user_settings/Devices.vue create mode 100644 components/settings/user_settings/Privacy.vue diff --git a/components/settings/app_settings/Appearance.vue b/components/settings/app_settings/Appearance.vue index e198d64..135c0a1 100644 --- a/components/settings/app_settings/Appearance.vue +++ b/components/settings/app_settings/Appearance.vue @@ -7,7 +7,6 @@ \ No newline at end of file diff --git a/components/settings/app_settings/Language.vue b/components/settings/app_settings/Language.vue new file mode 100644 index 0000000..b1c3a8a --- /dev/null +++ b/components/settings/app_settings/Language.vue @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/components/settings/app_settings/Notifications.vue b/components/settings/app_settings/Notifications.vue new file mode 100644 index 0000000..2e6de9c --- /dev/null +++ b/components/settings/app_settings/Notifications.vue @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/components/settings/user_settings/Account.vue b/components/settings/user_settings/Account.vue index 8425cd8..e137031 100644 --- a/components/settings/user_settings/Account.vue +++ b/components/settings/user_settings/Account.vue @@ -1,11 +1,35 @@ \ No newline at end of file diff --git a/components/settings/user_settings/Devices.vue b/components/settings/user_settings/Devices.vue new file mode 100644 index 0000000..7006a12 --- /dev/null +++ b/components/settings/user_settings/Devices.vue @@ -0,0 +1,12 @@ + + + + + \ No newline at end of file diff --git a/components/settings/user_settings/Privacy.vue b/components/settings/user_settings/Privacy.vue new file mode 100644 index 0000000..b805a7c --- /dev/null +++ b/components/settings/user_settings/Privacy.vue @@ -0,0 +1,13 @@ + + + + + \ No newline at end of file diff --git a/pages/settings.vue b/pages/settings.vue index 8327370..7c68e63 100644 --- a/pages/settings.vue +++ b/pages/settings.vue @@ -2,36 +2,34 @@
- +
- \ No newline at end of file diff --git a/components/settings/user_settings/Account.vue b/components/settings/user_settings/Account.vue index e137031..9b7d044 100644 --- a/components/settings/user_settings/Account.vue +++ b/components/settings/user_settings/Account.vue @@ -3,14 +3,14 @@

My Account

- +

Password (and eventually authenticator)

- +

Account Deletion

- +
@@ -19,7 +19,9 @@ import Button from '~/components/buttons/Button.vue'; import ButtonScary from '~/components/buttons/ButtonScary.vue'; -const { user } = useAuth(); +const { user, fetchUser } = useAuth(); + +const user_me = await fetchUser() const resetPassword = async () => { @@ -27,11 +29,17 @@ const resetPassword = async () => { // await fetchWithApi(`/auth/reset-password`); } -const deleteAccount = () => { +const deleteAccount = async () => { alert("TBD") } \ No newline at end of file diff --git a/composables/auth.ts b/composables/auth.ts index 19ac694..0ac2e8b 100644 --- a/composables/auth.ts +++ b/composables/auth.ts @@ -75,7 +75,7 @@ export const useAuth = () => { async function fetchUser() { if (!accessToken.value) return; console.log("fetchuser access token:", accessToken.value); - const res = await fetchWithApi("/users/me") as UserResponse; + const res = await fetchWithApi("/me") as UserResponse; user.value = res; return user.value; } @@ -88,6 +88,20 @@ export const useAuth = () => { return user.value; } + + // as in email the password link + async function resetPassword() { + // ... + } + + async function disableAccount() { + // ... + } + + async function deleteAccount() { + // ... + } + return { accessToken, register, diff --git a/pages/settings.vue b/pages/settings.vue index 9e7d420..050c1f8 100644 --- a/pages/settings.vue +++ b/pages/settings.vue @@ -69,17 +69,34 @@ const settingsCategories = { { display_name: "Language", page_data: Language }, ] }, + app_settings2: { + display_name: "App Settings", + pages: [ + { display_name: "Appearance", page_data: Appearance }, + { display_name: "Notifications", page_data: Notifications }, + { display_name: "Keybinds", page_data: Keybinds }, + { display_name: "Language", page_data: Language }, + ] + }, + app_settings3: { + display_name: "App Settings", + pages: [ + { display_name: "Appearance", page_data: Appearance }, + { display_name: "Notifications", page_data: Notifications }, + { display_name: "Keybinds", page_data: Keybinds }, + { display_name: "Language", page_data: Language }, + ] + }, }; const categories = Object.values(settingsCategories); let currentPage = ref(categories[0].pages[0]); -let selectedPage = ref(currentPage.value.display_name); +let selectedPage = ref(currentPage.value.display_name); // used to highlight the current channel const selectCategory = (_category: Category, page: Page) => { currentPage.value = page; selectedPage.value = page.display_name; - console.log(`switching to ${page.display_name}`) }; diff --git a/types/interfaces.ts b/types/interfaces.ts index b4869e2..cd4b6dd 100644 --- a/types/interfaces.ts +++ b/types/interfaces.ts @@ -58,6 +58,7 @@ export interface UserResponse { username: string, display_name: string | null, avatar: string | null, + pronouns: string | null, email?: string, email_verified?: boolean } From 82796377ee7d68524e7f3f661f0bc18750b135db Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sun, 1 Jun 2025 16:57:56 +0200 Subject: [PATCH 31/71] feat: change non-grouped messages to have margin-top instead of margin-bottom --- components/Message.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/Message.vue b/components/Message.vue index 592a995..baf954a 100644 --- a/components/Message.vue +++ b/components/Message.vue @@ -102,8 +102,8 @@ onMounted(async () => { align-items: center; } -.message-margin-bottom { - margin-bottom: 1dvh; +.normal-message { + margin-top: 1dvh; } #last-message { From 626c1c8453703d06647783dd2658067359b98934 Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sun, 1 Jun 2025 16:58:53 +0200 Subject: [PATCH 32/71] fix: older messages loading in reverse order --- components/MessageArea.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/components/MessageArea.vue b/components/MessageArea.vue index 5ad027c..e3dcdbf 100644 --- a/components/MessageArea.vue +++ b/components/MessageArea.vue @@ -185,6 +185,7 @@ onMounted(async () => { olderMessages.reverse(); console.log("older messages:", olderMessages); if (olderMessages.length == 0) return; + olderMessages.reverse(); for (const [i, oldMessage] of olderMessages.entries()) { console.log("old message:", oldMessage); messages.value.unshift(oldMessage); From f6523ae97f92a75efeb6ede3947c0eaf99f41c04 Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sun, 1 Jun 2025 17:02:58 +0200 Subject: [PATCH 33/71] feat: remove unnecessary styles from client layout --- layouts/client.vue | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/layouts/client.vue b/layouts/client.vue index 6c629da..73a40d6 100644 --- a/layouts/client.vue +++ b/layouts/client.vue @@ -123,30 +123,6 @@ const members = [ grid-row: 1; } -#test { - grid-column: 3; - grid-row: 1; -} - -.member-item { - display: flex; - justify-content: center; - align-items: center; -} - -#message-history, -#members-list { - padding-top: 3dvh; -} - -#message-history { - display: flex; - flex-direction: column; - justify-content: space-between; - padding-left: 3dvw; - padding-right: 3dvw; -} - #left-column { display: flex; flex-direction: column; From 532aba5c21a75607075f969b0c4316a3bfb0a732 Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sun, 1 Jun 2025 17:03:19 +0200 Subject: [PATCH 34/71] feat: merge two #member-list blocks --- pages/servers/[serverId]/channels/[channelId].vue | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pages/servers/[serverId]/channels/[channelId].vue b/pages/servers/[serverId]/channels/[channelId].vue index 4f3e4ec..debe6a5 100644 --- a/pages/servers/[serverId]/channels/[channelId].vue +++ b/pages/servers/[serverId]/channels/[channelId].vue @@ -88,10 +88,6 @@ function toggleInvitePopup(e: Event) { gap: .5em; } -#members-list { - padding-top: 3dvh; -} - #middle-left-column { padding-left: 1dvw; padding-right: 1dvw; @@ -99,6 +95,7 @@ function toggleInvitePopup(e: Event) { } #members-list { + padding-top: 3dvh; padding-left: 1dvw; padding-right: 1dvw; border-left: 1px solid rgb(70, 70, 70); From e8d37af75e25cefeec153b946014125e07ce649e Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sun, 1 Jun 2025 17:35:36 +0200 Subject: [PATCH 35/71] feat: update appearance of members list --- .../[serverId]/channels/[channelId].vue | 43 +++++++++++++------ 1 file changed, 29 insertions(+), 14 deletions(-) diff --git a/pages/servers/[serverId]/channels/[channelId].vue b/pages/servers/[serverId]/channels/[channelId].vue index debe6a5..3975e5b 100644 --- a/pages/servers/[serverId]/channels/[channelId].vue +++ b/pages/servers/[serverId]/channels/[channelId].vue @@ -24,11 +24,13 @@
-
-
- - - {{ member.user.display_name ?? member.user.username }} +
+
+
+ + + {{ member.user.display_name ?? member.user.username }} +
@@ -79,14 +81,6 @@ function toggleInvitePopup(e: Event) { \ No newline at end of file From 6182e00dd94f6447728c8ad42727ca4833f0f6b9 Mon Sep 17 00:00:00 2001 From: SauceyRed Date: Sun, 1 Jun 2025 17:38:03 +0200 Subject: [PATCH 36/71] feat: decrease top padding of members container --- pages/servers/[serverId]/channels/[channelId].vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/servers/[serverId]/channels/[channelId].vue b/pages/servers/[serverId]/channels/[channelId].vue index 3975e5b..f931863 100644 --- a/pages/servers/[serverId]/channels/[channelId].vue +++ b/pages/servers/[serverId]/channels/[channelId].vue @@ -89,7 +89,7 @@ function toggleInvitePopup(e: Event) { } #members-container { - padding-top: 3dvh; + padding-top: 1dvh; padding-left: 1dvw; padding-right: 1dvw; border-left: 1px solid rgb(70, 70, 70); From 256889a573e62a45a84eebdbc828c949faef28db Mon Sep 17 00:00:00 2001 From: JustTemmie <47639983+JustTemmie@users.noreply.github.com> Date: Sun, 1 Jun 2025 17:46:09 +0200 Subject: [PATCH 37/71] feat: favicon!! --- composables/auth.ts | 1 + public/favicon.ico | Bin 4286 -> 14463 bytes types/interfaces.ts | 2 +- 3 files changed, 2 insertions(+), 1 deletion(-) diff --git a/composables/auth.ts b/composables/auth.ts index 0ac2e8b..4ec2f32 100644 --- a/composables/auth.ts +++ b/composables/auth.ts @@ -76,6 +76,7 @@ export const useAuth = () => { if (!accessToken.value) return; console.log("fetchuser access token:", accessToken.value); const res = await fetchWithApi("/me") as UserResponse; + res.avatar = res.avatar ?? "https://gorb.b-cdn.net/avatar/default-pfp.png"; user.value = res; return user.value; } diff --git a/public/favicon.ico b/public/favicon.ico index 18993ad91cfd43e03b074dd0b5cc3f37ab38e49c..b3d28fa5964b5ad48b8b2fd2fce843074b44cee3 100644 GIT binary patch literal 14463 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 literal 4286 zcmeHLOKuuL5PjK%MHWVi6lD zOGiREbCw`xmFozJ^aNatJY>w+g ze6a2@u~m#^BZm@8wco9#Crlli0uLb^3E$t2-WIc^#(?t)*@`UpuofJ(Uyh@F>b3Ph z$D^m8Xq~pTkGJ4Q`Q2)te3mgkWYZ^Ijq|hkiP^9`De={bQQ%heZC$QU2UpP(-tbl8 zPWD2abEew;oat@w`uP3J^YpsgT%~jT(Dk%oU}sa$7|n6hBjDj`+I;RX(>)%lm_7N{+B7Mu%H?422lE%MBJH!!YTN2oT7xr>>N-8OF$C&qU^ z>vLsa{$0X%q1fjOe3P1mCv#lN{xQ4_*HCSAZjTb1`}mlc+9rl8$B3OP%VT@mch_~G z7Y+4b{r>9e=M+7vSI;BgB?ryZDY4m>&wcHSn81VH1N~`0gvwH{ z8dv#hG|OK`>1;j7tM#B)Z7zDN?{6=dUal}$e Date: Sun, 1 Jun 2025 19:24:50 +0200 Subject: [PATCH 38/71] feat: profile page, EXCEPT FUCKING AVATARS AAAAAHHH --- components/Userpopup.vue | 48 ++++---- components/buttons/Button.vue | 6 +- components/buttons/ButtonScary.vue | 6 +- components/settings/user_settings/Account.vue | 115 +++++++++++++++++- composables/auth.ts | 1 - pages/settings.vue | 9 +- types/interfaces.ts | 3 +- 7 files changed, 148 insertions(+), 40 deletions(-) diff --git a/components/Userpopup.vue b/components/Userpopup.vue index 1e90026..7381637 100644 --- a/components/Userpopup.vue +++ b/components/Userpopup.vue @@ -3,8 +3,12 @@ profile avatar
-

{{ props.user.display_name || "display_name" }}

-

{{ props.user.username || "username" }}

+

+ {{ props.user.display_name || "display_name" }} +

+

+ {{ props.user.username || "username" }} - {{ props.user.pronouns || "un/defined" }} +

About me
@@ -18,15 +22,15 @@ import type { UserResponse } from '~/types/interfaces'; const { fetchMembers } = useApi(); const props = defineProps<{ - user: UserResponse, + user: UserResponse | any, // actually UserResponse | null but TS is yelling at me again }>(); \ No newline at end of file diff --git a/components/buttons/Button.vue b/components/buttons/Button.vue index 20783c0..2544fbb 100644 --- a/components/buttons/Button.vue +++ b/components/buttons/Button.vue @@ -28,11 +28,11 @@ const props = defineProps<{ background-color: #b35719; color: #ffffff; - padding: 8px 16px; - font-size: 16px; + padding: 8px 18px; + font-size: 18px; transition: background-color 0.2s; - border-radius: 16px; + border-radius: 12px; text-decoration: none; display: inline-block; } diff --git a/components/buttons/ButtonScary.vue b/components/buttons/ButtonScary.vue index 71c0bc7..1fa2c85 100644 --- a/components/buttons/ButtonScary.vue +++ b/components/buttons/ButtonScary.vue @@ -28,11 +28,11 @@ const props = defineProps<{ background-color: #f02f2f; color: #ffffff; - padding: 8px 16px; - font-size: 16px; + padding: 8px 18px; + font-size: 18px; transition: background-color 0.2s; - border-radius: 16px; + border-radius: 12px; text-decoration: none; display: inline-block; } diff --git a/components/settings/user_settings/Account.vue b/components/settings/user_settings/Account.vue index 9b7d044..74d120d 100644 --- a/components/settings/user_settings/Account.vue +++ b/components/settings/user_settings/Account.vue @@ -2,10 +2,31 @@

My Account

-
- +
+
+

AVATAR

+ + +

DISPLAY NAME

+ +

USERNAME

+ +

PRONOUNS

+ +

ABOUT ME

+

{{ user?.about_me || "TBD" }}

+ + +
+
+ +
+
+
+
+

Password (and eventually authenticator)

@@ -19,10 +40,81 @@ import Button from '~/components/buttons/Button.vue'; import ButtonScary from '~/components/buttons/ButtonScary.vue'; -const { user, fetchUser } = useAuth(); +const { fetchUser } = useAuth(); const user_me = await fetchUser() +let user_reference = Object.assign({}, user_me) +const user = user_me! +let new_pfp_file: any = null + +const saveChanges = async () => { + try { + const formData = new FormData() + + if (new_pfp_file) { + formData.append('avatar', new_pfp_file, new_pfp_file.name) + new_pfp_file = null + } + + // oh lord praise deep seek v3 + const jsonBlob = new Blob( + [JSON.stringify({ + display_name: user.display_name, + username: user.username, + pronouns: user.pronouns, + })], + { type: 'application/json' } + ); + formData.append('json', jsonBlob, 'data.json'); + + await fetchWithApi("/me", { + method: "PATCH", + body: formData + }) + + user_reference = Object.assign({}, user_me) + alert("success!!") + } catch (error: any) { + if (error?.response?.status !== 200) { + const errorData = await error?.response?.json() + + alert(`error ${error?.response?.status} met whilst trying to update profile info\n${errorData}`) + } + } +}; + + +const removeAvatar = async () => { + alert("TBD") + // await fetchWithApi(`/auth/reset-password`); +} + +const changeAvatar = async () => { + try { + let input = document.createElement('input'); + input.type = 'file'; + input.accept = 'image/*'; + + input.onchange = async(e) => { + const file = e.target.files?.[0]; + if (!file) return; + + new_pfp_file = file; + + const reader = new FileReader(); + reader.onload = (e) => { + user.avatar = e?.target?.result; + }; + reader.readAsDataURL(file); + } + + input.oncancel = () => alert("cancelled upload!"); + input.click(); + } catch (err) { + console.error('User canceled or error:', err); + } +} const resetPassword = async () => { alert("TBD") @@ -35,11 +127,24 @@ const deleteAccount = async () => { \ No newline at end of file diff --git a/composables/auth.ts b/composables/auth.ts index 4ec2f32..0ac2e8b 100644 --- a/composables/auth.ts +++ b/composables/auth.ts @@ -76,7 +76,6 @@ export const useAuth = () => { if (!accessToken.value) return; console.log("fetchuser access token:", accessToken.value); const res = await fetchWithApi("/me") as UserResponse; - res.avatar = res.avatar ?? "https://gorb.b-cdn.net/avatar/default-pfp.png"; user.value = res; return user.value; } diff --git a/pages/settings.vue b/pages/settings.vue index 050c1f8..fb66aa2 100644 --- a/pages/settings.vue +++ b/pages/settings.vue @@ -115,8 +115,8 @@ const selectCategory = (_category: Category, page: Page) => { } #sidebar { - min-width: 200px; - max-width: 200px; + min-width: 250px; + max-width: 250px; background-color: #2f3136; color: white; padding: 10px; @@ -127,7 +127,7 @@ const selectCategory = (_category: Category, page: Page) => { } #sidebar h2 { - font-size: 1.5em; + font-size: 2em; padding: 0 8px; } @@ -140,6 +140,7 @@ const selectCategory = (_category: Category, page: Page) => { #sidebar li { border-radius: 8px; padding: 8px; + font-size: 1.3em; margin: 2px 0; cursor: pointer; transition: background-color 0.3s; @@ -155,7 +156,7 @@ const selectCategory = (_category: Category, page: Page) => { #sub_page { flex-grow: 1; - max-width: 600px; + max-width: 800px; margin-left: 1.5rem; margin-right: auto; diff --git a/types/interfaces.ts b/types/interfaces.ts index a0d7d39..04da39a 100644 --- a/types/interfaces.ts +++ b/types/interfaces.ts @@ -57,8 +57,9 @@ export interface UserResponse { uuid: string, username: string, display_name: string | null, - avatar: string, + avatar: string | null, pronouns: string | null, + about_me: string | null, email?: string, email_verified?: boolean } From 0ddddd210e2c4b5be417c3ae94a5db2e24b40879 Mon Sep 17 00:00:00 2001 From: JustTemmie <47639983+JustTemmie@users.noreply.github.com> Date: Sun, 1 Jun 2025 20:19:04 +0200 Subject: [PATCH 39/71] feat: fucking explode i hate this --- components/settings/user_settings/Account.vue | 54 ++++++++----------- pages/settings.vue | 4 +- 2 files changed, 25 insertions(+), 33 deletions(-) diff --git a/components/settings/user_settings/Account.vue b/components/settings/user_settings/Account.vue index 74d120d..c1fdc77 100644 --- a/components/settings/user_settings/Account.vue +++ b/components/settings/user_settings/Account.vue @@ -1,5 +1,6 @@ \ No newline at end of file diff --git a/components/settings/user_settings/Connections.vue b/components/Settings/UserSettings/Connections.vue similarity index 100% rename from components/settings/user_settings/Connections.vue rename to components/Settings/UserSettings/Connections.vue diff --git a/components/settings/user_settings/Devices.vue b/components/Settings/UserSettings/Devices.vue similarity index 100% rename from components/settings/user_settings/Devices.vue rename to components/Settings/UserSettings/Devices.vue diff --git a/components/settings/user_settings/Privacy.vue b/components/Settings/UserSettings/Privacy.vue similarity index 70% rename from components/settings/user_settings/Privacy.vue rename to components/Settings/UserSettings/Privacy.vue index b805a7c..1e1c2a1 100644 --- a/components/settings/user_settings/Privacy.vue +++ b/components/Settings/UserSettings/Privacy.vue @@ -5,7 +5,7 @@ - - - \ No newline at end of file From 714f75ce1230e9c49ee16336859c008fef4ed7a1 Mon Sep 17 00:00:00 2001 From: Radical Date: Mon, 23 Jun 2025 19:59:52 +0200 Subject: [PATCH 68/71] feat: update button component co-authored-by: JustTemmie --- components/Button.vue | 44 ++++++++++++++ components/Buttons/Button.vue | 43 -------------- components/Buttons/ButtonScary.vue | 43 -------------- components/Settings/UserSettings/Account.vue | 13 ++--- components/Settings/UserSettings/Privacy.vue | 2 +- components/UserPopup.vue | 2 +- pages/settings.vue | 61 ++++++++++---------- 7 files changed, 82 insertions(+), 126 deletions(-) create mode 100644 components/Button.vue delete mode 100644 components/Buttons/Button.vue delete mode 100644 components/Buttons/ButtonScary.vue diff --git a/components/Button.vue b/components/Button.vue new file mode 100644 index 0000000..1374344 --- /dev/null +++ b/components/Button.vue @@ -0,0 +1,44 @@ + + + + + \ No newline at end of file diff --git a/components/Buttons/Button.vue b/components/Buttons/Button.vue deleted file mode 100644 index 2544fbb..0000000 --- a/components/Buttons/Button.vue +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/components/Buttons/ButtonScary.vue b/components/Buttons/ButtonScary.vue deleted file mode 100644 index 1fa2c85..0000000 --- a/components/Buttons/ButtonScary.vue +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/components/Settings/UserSettings/Account.vue b/components/Settings/UserSettings/Account.vue index 120ceb3..5e883f5 100644 --- a/components/Settings/UserSettings/Account.vue +++ b/components/Settings/UserSettings/Account.vue @@ -6,7 +6,7 @@

AVATAR

- + @@ -34,8 +34,7 @@ \ No newline at end of file diff --git a/components/Settings/UserSettings/Account.vue b/components/Settings/UserSettings/Account.vue index 5e883f5..0fe5013 100644 --- a/components/Settings/UserSettings/Account.vue +++ b/components/Settings/UserSettings/Account.vue @@ -2,8 +2,8 @@

My Account

-
-
+
+

AVATAR

@@ -21,14 +21,14 @@
- +
-

Password (and eventually authenticator)

+

Password (and eventually authenticator)

- +

Account Deletion

- +
@@ -39,20 +39,19 @@ import type { UserResponse } from '~/types/interfaces'; const { fetchUser } = useAuth(); -const user_me = await fetchUser() -if (user_me === undefined) { +const user: UserResponse | undefined = await fetchUser() +if (!user) { alert("could not fetch user info, aborting :(") } -let userReference = Object.assign({}, user_me) -const user: UserResponse = user_me! - -let newPfpFile: any = null +let newPfpFile: File; const saveChanges = async () => { + if (!user) return; + const formData = new FormData() - if (newPfpFile !== null) { + if (newPfpFile) { formData.append("avatar", newPfpFile) } @@ -70,7 +69,6 @@ const saveChanges = async () => { body: formData }) - userReference = Object.assign({}, await fetchUser()) alert('success!!') } catch (error: any) { if (error?.response?.status !== 200) { @@ -86,7 +84,9 @@ const removeAvatar = async () => { } const changeAvatar = async () => { - let input = document.createElement('input'); + if (!user) return; + + const input = document.createElement('input'); input.type = 'file'; input.accept = 'image/*'; @@ -98,7 +98,7 @@ const changeAvatar = async () => { newPfpFile = file const reader = new FileReader(); - reader.addEventListener("onload", (e: Event) => { + reader.addEventListener("onload", () => { if (reader.result && typeof reader.result === 'string') { user.avatar = reader.result; } @@ -121,7 +121,7 @@ const deleteAccount = async () => {