From 1dfc9c266c315d008fa19ee1b2e789d16c5209ab Mon Sep 17 00:00:00 2001 From: JustTemmie <47639983+JustTemmie@users.noreply.github.com> Date: Thu, 3 Jul 2025 20:29:15 +0200 Subject: [PATCH 01/32] feat: dynamically load pfp when uploading a new one --- components/Settings/UserSettings/Profile.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/Settings/UserSettings/Profile.vue b/components/Settings/UserSettings/Profile.vue index ed7da0a..0e648c6 100644 --- a/components/Settings/UserSettings/Profile.vue +++ b/components/Settings/UserSettings/Profile.vue @@ -31,6 +31,7 @@ import type { UserResponse } from '~/types/interfaces'; const { fetchUser } = useAuth(); + const user: UserResponse | undefined = await fetchUser() if (!user) { alert("could not fetch user info, aborting :(") @@ -90,7 +91,7 @@ async function changeAvatar() { newPfpFile = file const reader = new FileReader(); - reader.addEventListener("onload", () => { + reader.addEventListener("load", () => { if (reader.result && typeof reader.result === 'string') { user.avatar = reader.result; } From 3c5525d294461fe04ef64685f9c5bada10ebcee2 Mon Sep 17 00:00:00 2001 From: JustTemmie <47639983+JustTemmie@users.noreply.github.com> Date: Thu, 3 Jul 2025 20:33:33 +0200 Subject: [PATCH 02/32] feat: display proper error messages when the client fails to update profile info --- components/Settings/UserSettings/Profile.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/Settings/UserSettings/Profile.vue b/components/Settings/UserSettings/Profile.vue index 0e648c6..13a717a 100644 --- a/components/Settings/UserSettings/Profile.vue +++ b/components/Settings/UserSettings/Profile.vue @@ -65,7 +65,7 @@ async function saveChanges() { alert('success!!') } catch (error: any) { if (error?.response?.status !== 200) { - alert(`error ${error?.response?.status} met whilst trying to update profile info`) + alert(`error ${error?.response?.status} met whilst trying to update profile info\n"${error?.response._data?.message}"`) } } }; From 873f1c81a91d2aeaa176b286c8f67fd94ab66f6d Mon Sep 17 00:00:00 2001 From: JustTemmie <47639983+JustTemmie@users.noreply.github.com> Date: Fri, 4 Jul 2025 06:34:15 +0200 Subject: [PATCH 03/32] fix: remove weird spacing due to weird profile popup inheritance --- components/MemberEntry.vue | 7 +------ components/Settings/UserSettings/Account.vue | 4 ---- components/Settings/UserSettings/Profile.vue | 4 ++-- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/components/MemberEntry.vue b/components/MemberEntry.vue index 3eed3c5..c77c429 100644 --- a/components/MemberEntry.vue +++ b/components/MemberEntry.vue @@ -3,7 +3,7 @@ {{ props.member.user.display_name ?? props.member.user.username }} - + @@ -32,9 +32,4 @@ const hidePopup = () => { .member-item { position: relative; /* Set the position to relative for absolute positioning of the popup */ } - -.profile-popup { - position: absolute; /* Use absolute positioning */ - left: -100px; /* Adjust this value to position the popup to the left */ -} diff --git a/components/Settings/UserSettings/Account.vue b/components/Settings/UserSettings/Account.vue index 85589e7..ffbb9d7 100644 --- a/components/Settings/UserSettings/Account.vue +++ b/components/Settings/UserSettings/Account.vue @@ -93,8 +93,4 @@ async function deleteAccount() { color: var(--text-color); background-color: var(--accent-color); } - -.profile-popup { - margin-left: 2dvw; -} \ No newline at end of file diff --git a/components/Settings/UserSettings/Profile.vue b/components/Settings/UserSettings/Profile.vue index 13a717a..f1a550b 100644 --- a/components/Settings/UserSettings/Profile.vue +++ b/components/Settings/UserSettings/Profile.vue @@ -20,7 +20,7 @@ - + @@ -133,7 +133,7 @@ async function changeAvatar() { background-color: var(--accent-color); } -.profile-popup { +#profile-popup { margin-left: 2dvw; } \ No newline at end of file From 3c4965c06f96ee215834dc2ea1fb14f0037d600d Mon Sep 17 00:00:00 2001 From: JustTemmie <47639983+JustTemmie@users.noreply.github.com> Date: Fri, 4 Jul 2025 08:04:50 +0200 Subject: [PATCH 04/32] feat: start implementing image cropping when uploading pfp still need to fix the selection to within the canvas boundries, and fix theming --- components/CropPopup.vue | 61 ++++++++++ components/Settings/UserSettings/Profile.vue | 37 ++++++- package.json | 1 + pnpm-lock.yaml | 110 +++++++++++++++++++ 4 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 components/CropPopup.vue diff --git a/components/CropPopup.vue b/components/CropPopup.vue new file mode 100644 index 0000000..2e1a6b1 --- /dev/null +++ b/components/CropPopup.vue @@ -0,0 +1,61 @@ + + + + + diff --git a/components/Settings/UserSettings/Profile.vue b/components/Settings/UserSettings/Profile.vue index f1a550b..1df8c44 100644 --- a/components/Settings/UserSettings/Profile.vue +++ b/components/Settings/UserSettings/Profile.vue @@ -21,12 +21,23 @@ + + + +
+
diff --git a/components/Settings/UserSettings/Profile.vue b/components/Settings/UserSettings/Profile.vue index 1df8c44..e9542c9 100644 --- a/components/Settings/UserSettings/Profile.vue +++ b/components/Settings/UserSettings/Profile.vue @@ -22,16 +22,15 @@ - - -
+
+
@@ -101,8 +100,6 @@ async function changeAvatar() { const file = input.files[0]; if (!file) return; - newPfpFile = file - const reader = new FileReader(); reader.addEventListener("load", () => { if (reader.result && typeof reader.result === 'string') { @@ -171,4 +168,21 @@ function closeCropPopup() { #profile-popup { margin-left: 2dvw; } + +#crop-popup-container { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 10; + background: rgba(0,0,0,0.5); +} + +#crop-popup-preview { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} \ No newline at end of file From 181fcd04dbdc1a3bb66557a88c071a908582404b Mon Sep 17 00:00:00 2001 From: JustTemmie <47639983+JustTemmie@users.noreply.github.com> Date: Fri, 4 Jul 2025 09:27:51 +0200 Subject: [PATCH 06/32] feat: ensure there's a background colour for the user popup's avatar --- components/UserPopup.vue | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/UserPopup.vue b/components/UserPopup.vue index 3a65cf0..a3a15cb 100644 --- a/components/UserPopup.vue +++ b/components/UserPopup.vue @@ -59,12 +59,14 @@ const props = defineProps<{ width: 96px; height: 96px; border: 5px solid #4b3018; + background-color: var(--secondary-color); border-radius: 100%; position: absolute; left: 16px; top: 16px; } + #display-name { margin-top: 60px; margin-bottom: 0; From d9c6faa6ab4a2aad29189a03e855e0461c9eb969 Mon Sep 17 00:00:00 2001 From: JustTemmie <47639983+JustTemmie@users.noreply.github.com> Date: Fri, 4 Jul 2025 09:43:05 +0200 Subject: [PATCH 07/32] refactor: move stuff from profile to within the crop popup itself --- components/CropPopup.vue | 32 ++++++++++++++------ components/Settings/UserSettings/Profile.vue | 31 ++++--------------- 2 files changed, 29 insertions(+), 34 deletions(-) diff --git a/components/CropPopup.vue b/components/CropPopup.vue index 7671e4d..8321cb1 100644 --- a/components/CropPopup.vue +++ b/components/CropPopup.vue @@ -1,8 +1,10 @@ @@ -60,12 +62,24 @@ function closePopup() { diff --git a/components/Settings/UserSettings/Profile.vue b/components/Settings/UserSettings/Profile.vue index e9542c9..302c4c0 100644 --- a/components/Settings/UserSettings/Profile.vue +++ b/components/Settings/UserSettings/Profile.vue @@ -24,14 +24,12 @@
-
- -
+ \ No newline at end of file From 768b011961d52159500be5c7b2f7328d9a2d11ef Mon Sep 17 00:00:00 2001 From: JustTemmie <47639983+JustTemmie@users.noreply.github.com> Date: Sat, 5 Jul 2025 17:02:22 +0200 Subject: [PATCH 17/32] feat: add theme previews --- .../Settings/AppSettings/Appearance.vue | 58 ++++++++++++++++++- nuxt.config.ts | 3 + public/themes/ash.css | 19 ++++++ public/themes/ash.json | 6 ++ public/themes/dark.json | 6 ++ public/themes/default-themes.json | 4 -- public/themes/light.json | 6 ++ 7 files changed, 96 insertions(+), 6 deletions(-) create mode 100644 public/themes/ash.css create mode 100644 public/themes/ash.json create mode 100644 public/themes/dark.json delete mode 100644 public/themes/default-themes.json create mode 100644 public/themes/light.json diff --git a/components/Settings/AppSettings/Appearance.vue b/components/Settings/AppSettings/Appearance.vue index 51b06ee..59e417c 100644 --- a/components/Settings/AppSettings/Appearance.vue +++ b/components/Settings/AppSettings/Appearance.vue @@ -1,12 +1,66 @@ \ No newline at end of file + display: inline-block; + text-align: center; + align-content: center; +} + +.theme-title { + font-size: .8em; + line-height: 6em; /* same height as the parent to centre it vertically */ +} + diff --git a/nuxt.config.ts b/nuxt.config.ts index 05a40fa..489e1b8 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -30,6 +30,9 @@ export default defineNuxtConfig({ messageGroupingMaxDifference: 300000, buildTimeString: new Date().toISOString(), gitHash: process.env.GIT_SHORT_REV || "N/A", + defaultThemes: [ + "light", "ash", "dark" + ] } }, /* nitro: { diff --git a/public/themes/ash.css b/public/themes/ash.css new file mode 100644 index 0000000..b685551 --- /dev/null +++ b/public/themes/ash.css @@ -0,0 +1,19 @@ +:root { + --text-color: #f0e5e0; + --secondary-text-color: #e8e0db; + + --chat-background-color: #2f2e2d; + --chat-highlighted-background-color: #3f3b38; + --sidebar-background-color: #3e3a37; + --sidebar-highlighted-background-color: #46423b; + --topbar-background-color: #3a3733; + + --padding-color: #e0e0e0; + + --primary-color: #f07028; + --primary-highlighted-color: #f28f4b; + --secondary-color: #683820; + --secondary-highlighted-color: #885830; + --accent-color: #a04b24; + --accent-highlighted-color: #b86038; +} \ No newline at end of file diff --git a/public/themes/ash.json b/public/themes/ash.json new file mode 100644 index 0000000..fb9cc93 --- /dev/null +++ b/public/themes/ash.json @@ -0,0 +1,6 @@ +{ + "displayName": "Ash", + "previewGradient": "45deg, #2f2e2d, #46423b", + "complementaryColor": "white", + "themeData": "ash.css" +} \ No newline at end of file diff --git a/public/themes/dark.json b/public/themes/dark.json new file mode 100644 index 0000000..3cecba6 --- /dev/null +++ b/public/themes/dark.json @@ -0,0 +1,6 @@ +{ + "displayName": "Dark", + "previewGradient": "45deg, #1f1e1d, #36322b", + "complementaryColor": "white", + "themeData": "dark.css" +} \ No newline at end of file diff --git a/public/themes/default-themes.json b/public/themes/default-themes.json deleted file mode 100644 index fb9478d..0000000 --- a/public/themes/default-themes.json +++ /dev/null @@ -1,4 +0,0 @@ -[ - "dark.css", - "light.css" -] \ No newline at end of file diff --git a/public/themes/light.json b/public/themes/light.json new file mode 100644 index 0000000..fe0b678 --- /dev/null +++ b/public/themes/light.json @@ -0,0 +1,6 @@ +{ + "displayName": "Light", + "previewGradient": "45deg, #f0ebe8, #d4d0ca", + "complementaryColor": "black", + "themeData": "light.css" +} \ No newline at end of file From c03f72ceccf81f7501b4ae71d711959bdf66465d Mon Sep 17 00:00:00 2001 From: JustTemmie <47639983+JustTemmie@users.noreply.github.com> Date: Sat, 5 Jul 2025 17:05:40 +0200 Subject: [PATCH 18/32] feat: implement "hash navigation" for settings --- pages/settings.vue | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pages/settings.vue b/pages/settings.vue index 0f297e3..01b78d7 100644 --- a/pages/settings.vue +++ b/pages/settings.vue @@ -40,10 +40,10 @@ From 441dc0c15cdb3391db283e89ec678970ca9e6b1c Mon Sep 17 00:00:00 2001 From: JustTemmie <47639983+JustTemmie@users.noreply.github.com> Date: Sat, 5 Jul 2025 17:36:08 +0200 Subject: [PATCH 20/32] feat: actually add theme switching :mind_blown: --- .../Settings/AppSettings/Appearance.vue | 29 ++++++++++++++++++- public/themes/ash.json | 2 +- public/themes/dark.json | 2 +- public/themes/light.json | 2 +- 4 files changed, 31 insertions(+), 4 deletions(-) diff --git a/components/Settings/AppSettings/Appearance.vue b/components/Settings/AppSettings/Appearance.vue index 68759d9..0f7b504 100644 --- a/components/Settings/AppSettings/Appearance.vue +++ b/components/Settings/AppSettings/Appearance.vue @@ -5,7 +5,11 @@

THEMES

- + {{ theme.displayName }} @@ -25,23 +29,45 @@ const runtimeConfig = useRuntimeConfig() const defaultThemes = runtimeConfig.public.defaultThemes const baseURL = runtimeConfig.app.baseURL; +let themeLinkElement: HTMLLinkElement | null = null; const themes: Array = [] interface Theme { + ID: string displayName: string previewGradient: string complementaryColor: string themeURL: string } +function changeTheme(ID: string, URL: string) { + if (themeLinkElement && themeLinkElement.getAttribute('href') === `${baseURL}themes/${URL}`) { + return; + } + + localStorage.setItem("selectedTheme", ID); + + // if the theme didn't originally load for some reason, create it + if (!themeLinkElement) { + themeLinkElement = document.createElement('link'); + themeLinkElement.rel = 'stylesheet'; + document.head.appendChild(themeLinkElement); + } + + themeLinkElement.href = `${baseURL}themes/${URL}`; +} const fetchThemes = async () => { for (const theme of defaultThemes) { const themeConfig = await fetch(`${baseURL}themes/${theme}.json`) const themeConfigJson = await themeConfig.json() as Theme + themeConfigJson.ID = theme + themes.push(themeConfigJson) } + + console.log(themes) } await fetchThemes() @@ -67,6 +93,7 @@ await fetchThemes() display: inline-block; text-align: center; align-content: center; + cursor: pointer; } .theme-title { diff --git a/public/themes/ash.json b/public/themes/ash.json index fb9cc93..1bd7670 100644 --- a/public/themes/ash.json +++ b/public/themes/ash.json @@ -2,5 +2,5 @@ "displayName": "Ash", "previewGradient": "45deg, #2f2e2d, #46423b", "complementaryColor": "white", - "themeData": "ash.css" + "themeURL": "ash.css" } \ No newline at end of file diff --git a/public/themes/dark.json b/public/themes/dark.json index 3cecba6..0ff69be 100644 --- a/public/themes/dark.json +++ b/public/themes/dark.json @@ -2,5 +2,5 @@ "displayName": "Dark", "previewGradient": "45deg, #1f1e1d, #36322b", "complementaryColor": "white", - "themeData": "dark.css" + "themeURL": "dark.css" } \ No newline at end of file diff --git a/public/themes/light.json b/public/themes/light.json index fe0b678..3745abb 100644 --- a/public/themes/light.json +++ b/public/themes/light.json @@ -2,5 +2,5 @@ "displayName": "Light", "previewGradient": "45deg, #f0ebe8, #d4d0ca", "complementaryColor": "black", - "themeData": "light.css" + "themeURL": "light.css" } \ No newline at end of file From 6abfd8e44bcf8f232e251e64269e7532612ec42f Mon Sep 17 00:00:00 2001 From: JustTemmie <47639983+JustTemmie@users.noreply.github.com> Date: Sat, 5 Jul 2025 19:02:57 +0200 Subject: [PATCH 21/32] chore: pascalCase --- components/Settings/AppSettings/Appearance.vue | 16 ++++++++-------- public/themes/ash.json | 2 +- public/themes/dark.json | 2 +- public/themes/light.json | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/components/Settings/AppSettings/Appearance.vue b/components/Settings/AppSettings/Appearance.vue index 0f7b504..82e3845 100644 --- a/components/Settings/AppSettings/Appearance.vue +++ b/components/Settings/AppSettings/Appearance.vue @@ -8,7 +8,7 @@ {{ theme.displayName }} @@ -34,19 +34,19 @@ let themeLinkElement: HTMLLinkElement | null = null; const themes: Array = [] interface Theme { - ID: string + id: string displayName: string previewGradient: string complementaryColor: string - themeURL: string + themeUrl: string } -function changeTheme(ID: string, URL: string) { - if (themeLinkElement && themeLinkElement.getAttribute('href') === `${baseURL}themes/${URL}`) { +function changeTheme(id: string, url: string) { + if (themeLinkElement && themeLinkElement.getAttribute('href') === `${baseURL}themes/${url}`) { return; } - localStorage.setItem("selectedTheme", ID); + localStorage.setItem("selectedTheme", id); // if the theme didn't originally load for some reason, create it if (!themeLinkElement) { @@ -55,14 +55,14 @@ function changeTheme(ID: string, URL: string) { document.head.appendChild(themeLinkElement); } - themeLinkElement.href = `${baseURL}themes/${URL}`; + themeLinkElement.href = `${baseURL}themes/${url}`; } const fetchThemes = async () => { for (const theme of defaultThemes) { const themeConfig = await fetch(`${baseURL}themes/${theme}.json`) const themeConfigJson = await themeConfig.json() as Theme - themeConfigJson.ID = theme + themeConfigJson.id = theme themes.push(themeConfigJson) } diff --git a/public/themes/ash.json b/public/themes/ash.json index 1bd7670..d5d2a59 100644 --- a/public/themes/ash.json +++ b/public/themes/ash.json @@ -2,5 +2,5 @@ "displayName": "Ash", "previewGradient": "45deg, #2f2e2d, #46423b", "complementaryColor": "white", - "themeURL": "ash.css" + "themeUrl": "ash.css" } \ No newline at end of file diff --git a/public/themes/dark.json b/public/themes/dark.json index 0ff69be..4731d43 100644 --- a/public/themes/dark.json +++ b/public/themes/dark.json @@ -2,5 +2,5 @@ "displayName": "Dark", "previewGradient": "45deg, #1f1e1d, #36322b", "complementaryColor": "white", - "themeURL": "dark.css" + "themeUrl": "dark.css" } \ No newline at end of file diff --git a/public/themes/light.json b/public/themes/light.json index 3745abb..b95c78b 100644 --- a/public/themes/light.json +++ b/public/themes/light.json @@ -2,5 +2,5 @@ "displayName": "Light", "previewGradient": "45deg, #f0ebe8, #d4d0ca", "complementaryColor": "black", - "themeURL": "light.css" + "themeUrl": "light.css" } \ No newline at end of file From 7098dda6b4f1a6d530978caa8120d2552ac303be Mon Sep 17 00:00:00 2001 From: JustTemmie <47639983+JustTemmie@users.noreply.github.com> Date: Sat, 5 Jul 2025 19:03:24 +0200 Subject: [PATCH 22/32] fix: remove un-necessary imports --- pages/settings.vue | 3 --- 1 file changed, 3 deletions(-) diff --git a/pages/settings.vue b/pages/settings.vue index 01b78d7..17558b1 100644 --- a/pages/settings.vue +++ b/pages/settings.vue @@ -40,9 +40,6 @@