@@ -52,21 +53,18 @@ 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
+ const upload_field = document.getElementById("hidden-pfp-uploader")
+ if (upload_field.files?.length && upload_field.files.length > 0) {
+ console.log(upload_field.files[0])
+ formData.append("avatar", upload_field.files[0])
}
- // oh lord praise deep seek v3
- const jsonBlob = new Blob(
- [JSON.stringify({
+ const bytes = new TextEncoder().encode(JSON.stringify({
display_name: user.display_name,
username: user.username,
pronouns: user.pronouns,
- })],
- { type: 'application/json' }
- );
- formData.append('json', jsonBlob, 'data.json');
+ }));
+ formData.append("json", new Blob([bytes], { type: "application/json" }));
await fetchWithApi("/me", {
method: "PATCH",
@@ -91,29 +89,23 @@ const removeAvatar = async () => {
}
const changeAvatar = async () => {
- try {
- let input = document.createElement('input');
- input.type = 'file';
- input.accept = 'image/*';
+ const upload_field: HTMLInputElement = document.getElementById("hidden-pfp-uploader")
+
+ // upload_field.onchange = async(e) => {
+ // console.log(upload_field.files)
+ // if (upload_field.files?.length && upload_field.files.length > 0) {
+ // const file = upload_field.files[0];
+ // if (!file) return;
- input.onchange = async(e) => {
- const file = e.target.files?.[0];
- if (!file) return;
+ // const reader = new FileReader();
+ // reader.onload = (e) => {
+ // user.avatar = e?.target?.result;
+ // };
+ // reader.readAsDataURL(file);
+ // }
+ // }
- 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);
- }
+ upload_field?.click()
}
const resetPassword = async () => {
diff --git a/pages/settings.vue b/pages/settings.vue
index fb66aa2..60c4265 100644
--- a/pages/settings.vue
+++ b/pages/settings.vue
@@ -4,14 +4,14 @@
@@ -74,8 +74,11 @@ const props = defineProps<{
}
#about-me {
- margin-top: 4px;
- padding: 4px;
+ background-color: #34200f;
+ border-radius: 12px;
+
+ margin-top: 32px;
+ padding: 16px;
font-size: 16px;
}
\ No newline at end of file
diff --git a/components/settings/user_settings/Account.vue b/components/settings/user_settings/Account.vue
index bb50f07..6438946 100644
--- a/components/settings/user_settings/Account.vue
+++ b/components/settings/user_settings/Account.vue
@@ -2,21 +2,24 @@
My Account
-
+
@@ -29,10 +32,10 @@
Password (and eventually authenticator)
-
+
Account Deletion
-
+
@@ -50,36 +53,33 @@ const user = user_me!
let new_pfp_file: any = null
const saveChanges = async () => {
+ const formData = new FormData()
+
+ if (new_pfp_file !== null) {
+ formData.append("avatar", new_pfp_file)
+ }
+
+ const bytes = new TextEncoder().encode(JSON.stringify({
+ display_name: user.display_name,
+ username: user.username,
+ pronouns: user.pronouns,
+ about: user.about,
+ }));
+ formData.append('json', new Blob([bytes], { type: 'application/json' }));
+
try {
- const formData = new FormData()
-
- const upload_field: HTMLInputElement = document.getElementById("hidden-pfp-uploader")
- if (upload_field.files?.length && upload_field.files.length > 0) {
- console.log(upload_field.files[0])
- formData.append("avatar", upload_field.files[0])
- }
-
- const bytes = new TextEncoder().encode(JSON.stringify({
- display_name: user.display_name,
- username: user.username,
- pronouns: user.pronouns,
- }));
- formData.append("json", new Blob([bytes], { type: "application/json" }));
-
- await fetchWithApi("/me", {
- method: "PATCH",
+ await fetchWithApi('/me', {
+ method: 'PATCH',
body: formData
})
- user_reference = Object.assign({}, user_me)
- alert("success!!")
+ user_reference = Object.assign({}, await fetchUser())
+ 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}`)
+ alert(`error ${error?.response?.status} met whilst trying to update profile info`)
}
- }
+ }
};
@@ -89,23 +89,28 @@ const removeAvatar = async () => {
}
const changeAvatar = async () => {
- const upload_field: HTMLInputElement = document.getElementById("hidden-pfp-uploader")
-
- // upload_field.onchange = async(e) => {
- // console.log(upload_field.files)
- // if (upload_field.files?.length && upload_field.files.length > 0) {
- // const file = upload_field.files[0];
- // if (!file) return;
+ let input = document.createElement('input');
+ input.type = 'file';
+ input.accept = 'image/*';
- // const reader = new FileReader();
- // reader.onload = (e) => {
- // user.avatar = e?.target?.result;
- // };
- // reader.readAsDataURL(file);
- // }
- // }
+ input.onchange = async (e) => {
+ if (input.files?.length && input.files.length > 0) {
+ const file = input.files[0];
+ if (!file) return;
- upload_field?.click()
+ new_pfp_file = file
+
+ const reader = new FileReader();
+ reader.onload = (e) => {
+ if (e.target?.result && typeof e.target.result === 'string') {
+ user.avatar = e.target.result;
+ }
+ };
+ reader.readAsDataURL(file);
+ }
+ }
+
+ input.click()
}
const resetPassword = async () => {
@@ -130,7 +135,8 @@ const deleteAccount = async () => {
display: flex;
}
-.profile-container, .user-data-fields {
+.profile-container,
+.user-data-fields {
min-width: 350px;
}
@@ -139,4 +145,16 @@ const deleteAccount = async () => {
font-weight: 800;
margin: 12px 0;
}
+
+.profile-data-input {
+ min-width: 300px;
+ margin: 2px;
+ padding: 2px 10px;
+ height: 40px;
+ font-size: 16px;
+ border-radius: 8px;
+ border: none;
+ color: white;
+ background-color: #54361b;
+}
\ No newline at end of file
diff --git a/pages/settings.vue b/pages/settings.vue
index 60c4265..0c2fefe 100644
--- a/pages/settings.vue
+++ b/pages/settings.vue
@@ -69,24 +69,6 @@ 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);
diff --git a/types/interfaces.ts b/types/interfaces.ts
index 04da39a..b5b1995 100644
--- a/types/interfaces.ts
+++ b/types/interfaces.ts
@@ -59,7 +59,7 @@ export interface UserResponse {
display_name: string | null,
avatar: string | null,
pronouns: string | null,
- about_me: string | null,
+ about: string | null,
email?: string,
email_verified?: boolean
}
From a38589615b7fe13efd36ca302a1410c05bc32718 Mon Sep 17 00:00:00 2001
From: JustTemmie <47639983+JustTemmie@users.noreply.github.com>
Date: Mon, 2 Jun 2025 13:14:08 +0200
Subject: [PATCH 13/21] chore: finnish merge
---
components/settings/user_settings/Account.vue | 33 +++++++++----------
1 file changed, 16 insertions(+), 17 deletions(-)
diff --git a/components/settings/user_settings/Account.vue b/components/settings/user_settings/Account.vue
index f8e15bc..6438946 100644
--- a/components/settings/user_settings/Account.vue
+++ b/components/settings/user_settings/Account.vue
@@ -53,24 +53,23 @@ const user = user_me!
let new_pfp_file: any = null
const saveChanges = async () => {
+ const formData = new FormData()
+
+ if (new_pfp_file !== null) {
+ formData.append("avatar", new_pfp_file)
+ }
+
+ const bytes = new TextEncoder().encode(JSON.stringify({
+ display_name: user.display_name,
+ username: user.username,
+ pronouns: user.pronouns,
+ about: user.about,
+ }));
+ formData.append('json', new Blob([bytes], { type: 'application/json' }));
+
try {
- const formData = new FormData()
-
- const upload_field = document.getElementById("hidden-pfp-uploader")
- if (upload_field.files?.length && upload_field.files.length > 0) {
- console.log(upload_field.files[0])
- formData.append("avatar", upload_field.files[0])
- }
-
- const bytes = new TextEncoder().encode(JSON.stringify({
- display_name: user.display_name,
- username: user.username,
- pronouns: user.pronouns,
- }));
- formData.append("json", new Blob([bytes], { type: "application/json" }));
-
- await fetchWithApi("/me", {
- method: "PATCH",
+ await fetchWithApi('/me', {
+ method: 'PATCH',
body: formData
})
From 22b43cde79d6a7f7d74ffdeedcfffbc118015485 Mon Sep 17 00:00:00 2001
From: SauceyRed
Date: Tue, 3 Jun 2025 22:04:05 +0200
Subject: [PATCH 14/21] feat: make profile settings headings into block labels
for accessibility
---
components/settings/user_settings/Account.vue | 19 ++++++++++---------
1 file changed, 10 insertions(+), 9 deletions(-)
diff --git a/components/settings/user_settings/Account.vue b/components/settings/user_settings/Account.vue
index 6438946..28f6a25 100644
--- a/components/settings/user_settings/Account.vue
+++ b/components/settings/user_settings/Account.vue
@@ -5,18 +5,18 @@
-
AVATAR
+
AVATAR
-
DISPLAY NAME
-
-
USERNAME
-
-
PRONOUNS
-
-
ABOUT ME
-
+
DISPLAY NAME
+
+
USERNAME
+
+
PRONOUNS
+
+
ABOUT ME
+
@@ -141,6 +141,7 @@ const deleteAccount = async () => {
}
.subtitle {
+ display: block;
font-size: 14px;
font-weight: 800;
margin: 12px 0;
From 64c6276153e8d361ed4d89a7ebe2b9ed2650b0d0 Mon Sep 17 00:00:00 2001
From: SauceyRed
Date: Sat, 7 Jun 2025 06:25:51 +0200
Subject: [PATCH 15/21] feat: add dropdown for guild settings and invite
---
components/GuildOptionsMenu.vue | 58 +++++++++++++++++++
.../[serverId]/channels/[channelId].vue | 48 ++++++++++-----
2 files changed, 90 insertions(+), 16 deletions(-)
create mode 100644 components/GuildOptionsMenu.vue
diff --git a/components/GuildOptionsMenu.vue b/components/GuildOptionsMenu.vue
new file mode 100644
index 0000000..d024ec8
--- /dev/null
+++ b/components/GuildOptionsMenu.vue
@@ -0,0 +1,58 @@
+
+
+
+ {{ setting.name }}
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/servers/[serverId]/channels/[channelId].vue b/pages/servers/[serverId]/channels/[channelId].vue
index c9aa8d2..b3d492a 100644
--- a/pages/servers/[serverId]/channels/[channelId].vue
+++ b/pages/servers/[serverId]/channels/[channelId].vue
@@ -1,21 +1,13 @@
-
-
- {{ server?.name }}
-
-
-
-
-
-
-
-
-
-
-
-
+
+ {{ server?.name }}
+
+
+
+
+
();
const channel = ref();
const showInvitePopup = ref(false);
+const showGuildSettings = ref(false);
import type { ChannelResponse, GuildResponse, MessageResponse } from "~/types/interfaces";
@@ -72,7 +65,10 @@ onMounted(async () => {
console.log("channelid: set loading to false");
});
-function showGuildSettings() { }
+function toggleGuildSettings(e: Event) {
+ e.preventDefault();
+ showGuildSettings.value = !showGuildSettings.value;
+}
function toggleInvitePopup(e: Event) {
e.preventDefault();
@@ -132,4 +128,24 @@ function toggleInvitePopup(e: Event) {
text-overflow: ellipsis;
}
+#server-name-container {
+ padding-top: 3dvh;
+ padding-bottom: 3dvh;
+ display: flex;
+ justify-content: center;
+ position: relative;
+}
+
+#server-name {
+ font-size: 1.5em;
+}
+
+#server-settings-button {
+ background-color: transparent;
+ font-size: 1em;
+ color: white;
+ border: none;
+ padding: 0%;
+}
+
\ No newline at end of file
From b82d5733a17070797222753a26657d5ac7bd9afe Mon Sep 17 00:00:00 2001
From: SauceyRed
Date: Sat, 7 Jun 2025 06:28:07 +0200
Subject: [PATCH 16/21] feat: refactor left column in UI, add join guild icon
---
layouts/client.vue | 60 ++++++++++++++++++++++++++++++++++++----------
1 file changed, 48 insertions(+), 12 deletions(-)
diff --git a/layouts/client.vue b/layouts/client.vue
index 73a40d6..fdce980 100644
--- a/layouts/client.vue
+++ b/layouts/client.vue
@@ -6,14 +6,21 @@
main bar
-
-
-
-
-
-
-
+
@@ -26,6 +33,9 @@ import type { GuildResponse } from '~/types/interfaces';
const loading = useState("loading", () => false);
const guilds: GuildResponse[] | undefined = await fetchWithApi("/me/guilds");
+for (let i = 0; i < 20; i++) {
+ guilds?.push(guilds[0]);
+}
//const servers = await fetchWithApi("/servers") as { uuid: string, name: string, description: string }[];
//console.log("servers:", servers);
@@ -124,13 +134,24 @@ const members = [
}
#left-column {
+ display: grid;
+ grid-template-rows: 1fr auto;
+ overflow-y: hidden;
+ border-right: 1px solid rgb(70, 70, 70);
+ padding-top: 1dvh;
+ padding-bottom: 1dvh;
+}
+
+#left-column-top {
display: flex;
flex-direction: column;
- gap: 2dvh;
- padding-left: .5dvw;
- padding-right: .5dvw;
- border-right: 1px solid rgb(70, 70, 70);
- padding-top: 1.5dvh;
+ gap: 1.5dvh;
+ overflow-y: scroll;
+}
+
+#left-column-bottom {
+ padding-top: 1dvh;
+ border-top: 1px solid rgb(70, 70, 70);
}
#middle-left-column {
@@ -148,6 +169,21 @@ const members = [
display: flex;
flex-direction: column;
gap: 1dvh;
+ overflow-y: scroll;
+}
+
+#join-server-button {
+ color: white;
+ background-color: transparent;
+ border: none;
+ cursor: pointer;
+ font-size: 2rem;
+ padding: 0;
+ display: inline-block;
+}
+
+#join-server-icon {
+ float: left;
}
\ No newline at end of file
From 556068063548e1be8c2be067bbdca8b4ac9c8061 Mon Sep 17 00:00:00 2001
From: JustTemmie <47639983+JustTemmie@users.noreply.github.com>
Date: Wed, 11 Jun 2025 17:42:35 +0200
Subject: [PATCH 17/21] feat: use dynamic units, minor refactoring
---
components/{buttons => Buttons}/Button.vue | 0
.../{buttons => Buttons}/ButtonScary.vue | 0
.../AppSettings}/Appearance.vue | 0
.../AppSettings}/Keybinds.vue | 0
.../AppSettings}/Language.vue | 0
.../AppSettings}/Notifications.vue | 0
.../UserSettings}/Account.vue | 81 +++++++++----------
.../UserSettings}/Connections.vue | 0
.../UserSettings}/Devices.vue | 0
.../UserSettings}/Privacy.vue | 2 +-
components/{Userpopup.vue => UserPopup.vue} | 9 ++-
pages/settings.vue | 50 +++++-------
12 files changed, 66 insertions(+), 76 deletions(-)
rename components/{buttons => Buttons}/Button.vue (100%)
rename components/{buttons => Buttons}/ButtonScary.vue (100%)
rename components/{settings/app_settings => Settings/AppSettings}/Appearance.vue (100%)
rename components/{settings/app_settings => Settings/AppSettings}/Keybinds.vue (100%)
rename components/{settings/app_settings => Settings/AppSettings}/Language.vue (100%)
rename components/{settings/app_settings => Settings/AppSettings}/Notifications.vue (100%)
rename components/{settings/user_settings => Settings/UserSettings}/Account.vue (71%)
rename components/{settings/user_settings => Settings/UserSettings}/Connections.vue (100%)
rename components/{settings/user_settings => Settings/UserSettings}/Devices.vue (100%)
rename components/{settings/user_settings => Settings/UserSettings}/Privacy.vue (70%)
rename components/{Userpopup.vue => UserPopup.vue} (81%)
diff --git a/components/buttons/Button.vue b/components/Buttons/Button.vue
similarity index 100%
rename from components/buttons/Button.vue
rename to components/Buttons/Button.vue
diff --git a/components/buttons/ButtonScary.vue b/components/Buttons/ButtonScary.vue
similarity index 100%
rename from components/buttons/ButtonScary.vue
rename to components/Buttons/ButtonScary.vue
diff --git a/components/settings/app_settings/Appearance.vue b/components/Settings/AppSettings/Appearance.vue
similarity index 100%
rename from components/settings/app_settings/Appearance.vue
rename to components/Settings/AppSettings/Appearance.vue
diff --git a/components/settings/app_settings/Keybinds.vue b/components/Settings/AppSettings/Keybinds.vue
similarity index 100%
rename from components/settings/app_settings/Keybinds.vue
rename to components/Settings/AppSettings/Keybinds.vue
diff --git a/components/settings/app_settings/Language.vue b/components/Settings/AppSettings/Language.vue
similarity index 100%
rename from components/settings/app_settings/Language.vue
rename to components/Settings/AppSettings/Language.vue
diff --git a/components/settings/app_settings/Notifications.vue b/components/Settings/AppSettings/Notifications.vue
similarity index 100%
rename from components/settings/app_settings/Notifications.vue
rename to components/Settings/AppSettings/Notifications.vue
diff --git a/components/settings/user_settings/Account.vue b/components/Settings/UserSettings/Account.vue
similarity index 71%
rename from components/settings/user_settings/Account.vue
rename to components/Settings/UserSettings/Account.vue
index 28f6a25..120ceb3 100644
--- a/components/settings/user_settings/Account.vue
+++ b/components/Settings/UserSettings/Account.vue
@@ -1,14 +1,13 @@
-
My Account
AVATAR
-
-
+
+
+
DISPLAY NAME
USERNAME
@@ -19,19 +18,13 @@
-
-
+
-
+
+
-
-
-
-
-
-
-
Password (and eventually authenticator)
+
Password (and eventually authenticator)
Account Deletion
@@ -41,22 +34,27 @@
\ 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 18/21] 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 @@
+
+
+ {{ props.text }}
+
+
+
+
+
+
\ 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 @@
-
-
-
-
- {{ props.text }}
-
-
-
-
-
-
\ 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 @@
-
-
-
-
- {{ props.text }}
-
-
-
-
-
-
\ 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
-
+
DISPLAY NAME
@@ -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 () => {