Merge pull request 'Move /me/friends to /me, as the new landing page' (#44) from update-friend-landing-page into main
All checks were successful
ci/woodpecker/push/build-and-publish Pipeline was successful

Reviewed-on: #44
Reviewed-by: SauceyRed <saucey@saucey.red>
This commit is contained in:
Twig 2025-07-16 09:42:38 +00:00
commit f26c5fd7ce
14 changed files with 72 additions and 75 deletions

View file

@ -24,9 +24,7 @@ let displayAvatar: string | null
const user = props.user || props.member?.user
if (user) {
displayName = props.member?.nickname
|| user.display_name
|| user.username
displayName = getDisplayName(user, props.member)
if (user.avatar) {
displayAvatar = user.avatar

View file

@ -1,7 +1,7 @@
<template>
<div class="member-item" @click="togglePopup" @blur="hidePopup" tabindex="0">
<Avatar :member="props.member" class="member-avatar"/>
<span class="member-display-name">{{ props.member.user.display_name || props.member.user.username }}</span>
<span class="member-display-name">{{ getDisplayName(props.member.user, props.member) }}</span>
<UserPopup v-if="isPopupVisible" :user="props.member.user" id="profile-popup" />
</div>
</template>

View file

@ -6,7 +6,7 @@
</div>
<VerticalSpacer />
<NuxtLink class="user-item" :href="`/me/friends`" tabindex="0">
<NuxtLink class="user-item" :href="`/me`" tabindex="0">
<Icon class="user-avatar" name="lucide:user" />
<span class="user-display-name">Friends</span>
</NuxtLink>

View file

@ -17,7 +17,7 @@
</div>
<div v-else>
<UserEntry v-for="user of friends" :user="user" :name="user.display_name || user.username"
<UserEntry v-for="user of friends" :user="user" :name="getDisplayName(user)"
:href="`/me/${user.uuid}`"/>
</div>
</div>
@ -26,7 +26,9 @@
<script lang="ts" setup>
const { fetchFriends } = useApi();
const friends = await fetchFriends()
const friends = await fetchFriends().then((response) => {
return response.sort((a, b) => getDisplayName(a).localeCompare(getDisplayName(b)))
})
const props = defineProps<{
variant: string

View file

@ -25,7 +25,7 @@
</svg>
</div>
<MessageReply v-if="props.replyMessage" :id="props.message.uuid"
:author="props.replyMessage.user.display_name || props.replyMessage.user.username"
:author="getDisplayName(props.replyMessage.user)"
:text="props.replyMessage?.message"
:reply-id="props.replyMessage.uuid" max-width="reply" />
<div class="left-column">
@ -34,7 +34,7 @@
<div class="message-data">
<div class="message-metadata">
<span class="message-author-username" tabindex="0" :style="`color: ${props.authorColor}`">
{{ displayName }}
{{ getDisplayName(props.author) }}
</span>
<span class="message-date" :title="date.toString()">
<span v-if="getDayDifference(date, currentDate) === 1">Yesterday at</span>
@ -77,7 +77,6 @@ const dateHidden = ref<boolean>(true);
const date = new Date(props.timestamp);
const currentDate: Date = new Date()
const displayName = props.author?.display_name || props.author?.username
console.log("[MSG] message to render:", props.message);
console.log("author:", props.author);

View file

@ -1,7 +1,7 @@
<template>
<div id="message-area">
<div id="messages" ref="messagesElement">
<Message v-for="(message, i) of messages" :username="message.user.display_name ?? message.user.username"
<Message v-for="(message, i) of messages" :username="getDisplayName(message.user)"
:text="message.message" :timestamp="messageTimestamps[message.uuid]" :img="message.user.avatar"
:format="timeFormat" :type="messagesType[message.uuid]"
:margin-bottom="(messages[i + 1] && messagesType[messages[i + 1].uuid] == 'normal') ?? false"

View file

@ -2,7 +2,7 @@
<NuxtLink class="user-item" :href="`/me/${user.uuid}`" tabindex="0">
<Avatar :user="props.user" class="user-avatar"/>
<span class="user-display-name">{{ displayName }}</span>
<span class="user-display-name">{{ getDisplayName(props.user) }}</span>
</NuxtLink>
</template>
@ -13,7 +13,6 @@ const props = defineProps<{
user: UserResponse
}>();
const displayName = props.user.display_name || props.user.username
</script>
<style>

View file

@ -5,7 +5,7 @@
<div id="cover-color"></div>
<div id="main-body">
<p id="display-name">
<strong>{{ props.user.display_name }}</strong>
<strong>{{ getDisplayName(props.user) }}</strong>
</p>
<p id="username-and-pronouns">
{{ props.user.username }}

View file

@ -33,8 +33,13 @@ export const useApi = () => {
return await fetchWithApi(`/users/${userId}`);
}
async function fetchFriends(): Promise<UserResponse[] | undefined> {
return await fetchWithApi('/me/friends')
async function fetchFriends(): Promise<UserResponse[]> {
const response = await fetchWithApi('/me/friends')
if (Array.isArray(response)) {
return response
} else {
return []
}
}
async function addFriend(username: string): Promise<void> {

View file

@ -127,7 +127,7 @@ const options = [
h("input", {
id: "guild-name-input",
type: "text",
placeholder: `${user?.display_name || user?.username}'s Awesome Bouncy Castle'`,
placeholder: `${getDisplayName(user!)}'s Awesome Bouncy Castle'`,
style: "width: 100%"
}),
h(Button, {

View file

@ -1,56 +0,0 @@
<template>
<NuxtLayout name="client">
<DirectMessagesSidebar />
<div :id="$style['page-content']">
<div :id="$style['navigation-bar']">
<Button :text="`All Friends ${friends?.length}`" variant="neutral" :callback="() => updateFilter('all')" />
<Button :text="`Online ${0}`" variant="neutral" :callback="() => updateFilter('online')" />
<Button :text="`Pending ${0}`" variant="neutral" :callback="() => updateFilter('pending')" />
<Button text="Add Friend" variant="normal" :callback="() => updateFilter('add')" />
</div>
<div>
<AddFriend v-if="filter == 'add'"></AddFriend>
<FriendsList v-else :variant="filter"></FriendsList>
</div>
</div>
</NuxtLayout>
</template>
<script lang="ts" setup>
import DirectMessagesSidebar from '~/components/Me/DirectMessagesSidebar.vue';
import Button from '~/components/UserInterface/Button.vue';
import AddFriend from '~/components/Me/AddFriend.vue';
import FriendsList from '~/components/Me/FriendsList.vue';
const { fetchFriends } = useApi();
let filter = ref("all");
const friends = await fetchFriends()
function updateFilter(newFilter: string) {
filter.value = newFilter;
}
</script>
<style module>
#page-content {
display: flex;
flex-direction: column;
flex-grow: 1;
margin: .75em;
}
#navigation-bar {
display: flex;
align-items: left;
text-align: left;
flex-direction: row;
gap: .5em;
}
</style>

View file

@ -1,13 +1,56 @@
<template>
<NuxtLayout name="client">
<DirectMessagesSidebar />
<div :id="$style['page-content']">
<div :id="$style['navigation-bar']">
<Button :text="`All Friends ${friends?.length}`" variant="neutral" :callback="() => updateFilter('all')" />
<Button :text="`Online ${0}`" variant="neutral" :callback="() => updateFilter('online')" />
<Button :text="`Pending ${0}`" variant="neutral" :callback="() => updateFilter('pending')" />
<Button text="Add Friend" variant="normal" :callback="() => updateFilter('add')" />
</div>
<div>
<AddFriend v-if="filter == 'add'"></AddFriend>
<FriendsList v-else :variant="filter"></FriendsList>
</div>
</div>
</NuxtLayout>
</template>
<script lang="ts" setup>
import DirectMessagesSidebar from '~/components/Me/DirectMessagesSidebar.vue';
import Button from '~/components/UserInterface/Button.vue';
import AddFriend from '~/components/Me/AddFriend.vue';
import FriendsList from '~/components/Me/FriendsList.vue';
const { fetchFriends } = useApi();
let filter = ref("all");
const friends = await fetchFriends()
function updateFilter(newFilter: string) {
filter.value = newFilter;
}
</script>
<style>
<style module>
#page-content {
display: flex;
flex-direction: column;
flex-grow: 1;
margin: .75em;
}
#navigation-bar {
display: flex;
align-items: left;
text-align: left;
flex-direction: row;
gap: .5em;
}
</style>

7
utils/getDisplayName.ts Normal file
View file

@ -0,0 +1,7 @@
import type { GuildMemberResponse, UserResponse } from "~/types/interfaces";
export function getDisplayName(user: UserResponse, member?: GuildMemberResponse): string {
if (member?.nickname) return member.nickname
if (user.display_name) return user.display_name
return user.username
}

View file

@ -7,7 +7,7 @@ export default (element: HTMLDivElement, props: MessageProps) => {
const messageBox = document.getElementById("message-box") as HTMLDivElement;
if (messageBox) {
const div = document.createElement("div");
const messageReply = h(MessageReply, { author: props.author?.display_name || props.author!.username, text: props.text || "", id: props.message.uuid, replyId: props.replyMessage?.uuid || element.dataset.messageId!, maxWidth: "full" });
const messageReply = h(MessageReply, { author: getDisplayName(props.author), text: props.text || "", id: props.message.uuid, replyId: props.replyMessage?.uuid || element.dataset.messageId!, maxWidth: "full" });
messageBox.prepend(div);
render(messageReply, div);
}