Compare commits

...
Sign in to create a new pull request.

2 commits

Author SHA1 Message Date
7d0294e808
wip: start work on members list placeholders
All checks were successful
ci/woodpecker/push/build-and-publish Pipeline was successful
2025-08-05 03:50:59 +02:00
c465753111
feat: update members fetching to handle endpoint pagination update 2025-08-05 03:42:39 +02:00
3 changed files with 48 additions and 5 deletions

View file

@ -1,4 +1,4 @@
import type { ChannelResponse, GuildMemberResponse, GuildResponse, MessageResponse, StatsResponse, UserResponse } from "~/types/interfaces"; import type { ChannelResponse, GuildMemberResponse, GuildMembersResponse, GuildResponse, MessageResponse, StatsResponse, UserResponse } from "~/types/interfaces";
function ensureIsArray(list: any) { function ensureIsArray(list: any) {
if (Array.isArray(list)) { if (Array.isArray(list)) {
@ -33,8 +33,15 @@ export const useApi = () => {
return await fetchWithApi(`/channels/${channelId}`) return await fetchWithApi(`/channels/${channelId}`)
} }
async function fetchMembers(guildId: string): Promise<GuildMemberResponse[]> { async function fetchMembers(guildId: string, options?: { per_page?: number, page?: number }): Promise<GuildMembersResponse> {
return ensureIsArray(await fetchWithApi(`/guilds/${guildId}/members`)); const query = new URLSearchParams();
query.set("page", options?.page ? options.page.toString() : "1");
if (options?.per_page) {
query.set("per_page", options.per_page.toString());
}
console.log("members query:", query);
return await fetchWithApi(`/guilds/${guildId}/members?${query.toString()}`) as GuildMembersResponse;
} }
async function fetchMember(guildId: string, memberId: string): Promise<GuildMemberResponse | undefined> { async function fetchMember(guildId: string, memberId: string): Promise<GuildMemberResponse | undefined> {

View file

@ -24,7 +24,8 @@
border-sides="left" local-storage-name="membersListWidth"> border-sides="left" local-storage-name="membersListWidth">
<div id="members-container"> <div id="members-container">
<div id="members-list"> <div id="members-list">
<MemberEntry v-for="member of members" :member="member" tabindex="0"/> <MemberEntry v-for="member of members" :member="member" tabindex="0" />
<GuildMemberEntryPlaceholder v-for="n in totalMemberCount" />
</div> </div>
</div> </div>
</ResizableSidebar> </ResizableSidebar>
@ -49,6 +50,7 @@ const channels = ref<ChannelResponse[] | undefined>();
const channel = ref<ChannelResponse | undefined>(); const channel = ref<ChannelResponse | undefined>();
const members = ref<GuildMemberResponse[]>(); const members = ref<GuildMemberResponse[]>();
const totalMemberCount = ref(0);
const showInvitePopup = ref(false); const showInvitePopup = ref(false);
const showGuildSettings = ref(false); const showGuildSettings = ref(false);
@ -65,6 +67,16 @@ onMounted(async () => {
console.log("fetched guild"); console.log("fetched guild");
await setArrayVariables(); await setArrayVariables();
console.log("set array variables"); console.log("set array variables");
const membersList = document.getElementById("members-list");
if (membersList) {
membersList.addEventListener("scroll", (e) => {
if (e.target && e.target instanceof Element) {
if (isVisible(e.target)) {
}
}
});
}
}); });
onActivated(async () => { onActivated(async () => {
@ -77,7 +89,10 @@ onActivated(async () => {
}); });
async function setArrayVariables() { async function setArrayVariables() {
members.value = await fetchMembers(route.params.serverId as string); const membersRes = await fetchMembers(route.params.serverId as string);
members.value = membersRes.objects;
totalMemberCount.value = (membersRes.amount * membersRes.pages) - membersRes.amount;
console.log("Placeholder count:", totalMemberCount.value);
const guildUrl = `guilds/${route.params.serverId}`; const guildUrl = `guilds/${route.params.serverId}`;
channels.value = await fetchWithApi(`${guildUrl}/channels`); channels.value = await fetchWithApi(`${guildUrl}/channels`);
console.log("channels:", channels.value); console.log("channels:", channels.value);
@ -97,6 +112,20 @@ function toggleInvitePopup(e: Event) {
function handleMemberClick(member: GuildMemberResponse) { function handleMemberClick(member: GuildMemberResponse) {
} }
function isVisible(element: Element) {
const rect = element.getBoundingClientRect();
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (
window.innerHeight ||
document.documentElement.clientHeight) &&
rect.right <= (
window.innerWidth ||
document.documentElement.clientWidth)
);
}
</script> </script>
<style> <style>

View file

@ -31,6 +31,13 @@ export interface GuildMemberResponse {
user: UserResponse user: UserResponse
} }
export interface GuildMembersResponse {
objects: GuildMemberResponse[],
amount: number,
pages: number,
page: number
}
export interface ChannelResponse { export interface ChannelResponse {
uuid: string, uuid: string,
guild_uuid: string, guild_uuid: string,