Compare commits
10 commits
310b1cc2df
...
febdbb9421
Author | SHA1 | Date | |
---|---|---|---|
febdbb9421 | |||
417a558109 | |||
4b2c3af5e5 | |||
1c5b136323 | |||
00d6eb0a00 | |||
abf3b248c4 | |||
5011affd49 | |||
3fd28ed3fc | |||
9a84315b64 | |||
115b7d8341 |
11 changed files with 114 additions and 76 deletions
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div v-if="props.type == 'normal'" class="message normal-message" :class="{ 'message-margin-bottom': props.marginBottom }">
|
||||
<div v-if="props.type == 'normal'" :id="props.last ? 'last-message' : undefined" class="message normal-message" :class="{ 'message-margin-bottom': props.marginBottom }">
|
||||
<div class="left-column">
|
||||
<img v-if="props.img" class="message-author-avatar" :src="props.img" :alt="username">
|
||||
<Icon v-else name="lucide:user" class="message-author-avatar" />
|
||||
|
@ -18,7 +18,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else ref="messageElement" class="message grouped-message">
|
||||
<div v-else ref="messageElement" :id="props.last ? 'last-message' : undefined" class="message grouped-message">
|
||||
<div class="left-column">
|
||||
<div>
|
||||
<span :class="{ 'invisible': dateHidden }" class="message-date" :title="date.toString()">
|
||||
|
@ -43,7 +43,8 @@ const props = defineProps<{
|
|||
timestamp: number,
|
||||
format: "12" | "24",
|
||||
type: "normal" | "grouped",
|
||||
marginBottom: boolean
|
||||
marginBottom: boolean,
|
||||
last: boolean
|
||||
}>();
|
||||
|
||||
const messageDate = ref<string>();
|
||||
|
@ -56,6 +57,7 @@ const date = new Date(props.timestamp);
|
|||
|
||||
console.log("Message.vue: message:", props.text);
|
||||
console.log("Message.vue: message type:", props.type);
|
||||
console.log("Message.vue: is last?", props.last);
|
||||
|
||||
let dateHour = date.getHours();
|
||||
let dateMinute = date.getMinutes();
|
||||
|
@ -102,6 +104,10 @@ onMounted(() => {
|
|||
margin-bottom: 1dvh;
|
||||
}
|
||||
|
||||
#last-message {
|
||||
margin-bottom: 2dvh;
|
||||
}
|
||||
|
||||
.message-metadata {
|
||||
display: flex;
|
||||
gap: .5dvw;
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
<template>
|
||||
<div id="message-area">
|
||||
<div id="messages" ref="messagesElement">
|
||||
<div v-for="(message, i) of messages">
|
||||
<Message :username="message.user.display_name ?? message.user.username"
|
||||
<Message v-for="(message, i) of messages" :username="message.user.display_name ?? message.user.username"
|
||||
:text="message.message" :timestamp="messageTimestamps[message.uuid]" :img="message.user.avatar"
|
||||
format="12" :type="messagesType[message.uuid]"
|
||||
:margin-bottom="messages[i + 1] && messagesType[messages[i + 1].uuid] == 'normal'" />
|
||||
</div>
|
||||
:margin-bottom="messages[i + 1] && messagesType[messages[i + 1].uuid] == 'normal'"
|
||||
:last="i == messages.length - 1" />
|
||||
</div>
|
||||
<div id="message-box" class="rounded-corners">
|
||||
<form id="message-form" @submit="sendMessage">
|
||||
|
@ -176,7 +175,8 @@ onMounted(async () => {
|
|||
padding-bottom: 1dvh;
|
||||
padding-top: 1dvh;
|
||||
margin-bottom: 1dvh;
|
||||
margin-top: 2dvh;
|
||||
margin-left: 1dvw;
|
||||
margin-right: 1dvw;
|
||||
}
|
||||
|
||||
#message-form {
|
||||
|
@ -198,6 +198,8 @@ onMounted(async () => {
|
|||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1dvh;
|
||||
padding-left: 1dvw;
|
||||
padding-right: 1dvw;
|
||||
}
|
||||
|
||||
#submit-button {
|
||||
|
|
56
composables/api.ts
Normal file
56
composables/api.ts
Normal file
|
@ -0,0 +1,56 @@
|
|||
import type { ChannelResponse, GuildMemberResponse, GuildResponse, MessageResponse } from "~/types/interfaces";
|
||||
|
||||
export const useApi = () => {
|
||||
async function fetchGuilds(): Promise<GuildResponse[] | undefined> {
|
||||
return await fetchWithApi(`/guilds`);
|
||||
}
|
||||
|
||||
async function fetchGuild(guildId: string): Promise<GuildResponse | undefined> {
|
||||
return await fetchWithApi(`/guilds/${guildId}`);
|
||||
}
|
||||
|
||||
async function fetchChannels(guildId: string): Promise<ChannelResponse[] | undefined> {
|
||||
return await fetchWithApi(`/guilds/${guildId}/channels`);
|
||||
}
|
||||
|
||||
async function fetchChannel(channelId: string): Promise<ChannelResponse | undefined> {
|
||||
return await fetchWithApi(`/channels/${channelId}`)
|
||||
}
|
||||
|
||||
async function fetchMembers(guildId: string): Promise<GuildMemberResponse[] | undefined> {
|
||||
return await fetchWithApi(`/guilds/${guildId}/members`);
|
||||
}
|
||||
|
||||
async function fetchMember(guildId: string, memberId: string): Promise<GuildMemberResponse | undefined> {
|
||||
return await fetchWithApi(`/guilds/${guildId}/members/${memberId}`);
|
||||
}
|
||||
|
||||
async function fetchUsers() {
|
||||
return await fetchWithApi(`/users`);
|
||||
}
|
||||
|
||||
async function fetchUser(userId: string) {
|
||||
return await fetchWithApi(`/users/${userId}`);
|
||||
}
|
||||
|
||||
async function fetchMessages(channelId: string, options?: { amount?: number, offset?: number }): Promise<MessageResponse[] | undefined> {
|
||||
return await fetchWithApi(`/channels/${channelId}/messages`, { query: { amount: options?.amount ?? 100, offset: options?.offset ?? 0 } });
|
||||
}
|
||||
|
||||
async function fetchMessage(channelId: string, messageId: string): Promise<MessageResponse | undefined> {
|
||||
return await fetchWithApi(`/channels/${channelId}/messages/${messageId}`);
|
||||
}
|
||||
|
||||
return {
|
||||
fetchGuilds,
|
||||
fetchGuild,
|
||||
fetchChannels,
|
||||
fetchChannel,
|
||||
fetchMembers,
|
||||
fetchMember,
|
||||
fetchUsers,
|
||||
fetchUser,
|
||||
fetchMessages,
|
||||
fetchMessage
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
<script lang="ts" setup>
|
||||
import type { GuildResponse } from '~/types/interfaces';
|
||||
|
||||
|
||||
const loading = useState("loading", () => false);
|
||||
|
||||
const guilds: GuildResponse[] | undefined = await fetchWithApi("/me/guilds");
|
||||
|
|
15
middleware/server.ts
Normal file
15
middleware/server.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
import type { ChannelResponse } from "~/types/interfaces";
|
||||
|
||||
export default defineNuxtRouteMiddleware(async (to, from) => {
|
||||
const { fetchChannels } = useApi();
|
||||
|
||||
const guildId = to.params.serverId as string;
|
||||
|
||||
const channels: ChannelResponse[] | undefined = await fetchChannels(guildId);
|
||||
console.log("channels:", channels);
|
||||
|
||||
if (channels && channels.length > 0) {
|
||||
console.log("wah");
|
||||
return await navigateTo(`/servers/${guildId}/channels/${channels[0].uuid}`, { replace: true });
|
||||
}
|
||||
})
|
|
@ -26,9 +26,9 @@
|
|||
<MessageArea :channel-url="channelUrlPath" />
|
||||
<div id="members-list">
|
||||
<div class="member-item" v-for="member of members">
|
||||
<img v-if="member.avatar" :src="member.avatar" :alt="member.displayName" height="30" />
|
||||
<Icon v-else name="lucide:user" size="30" />
|
||||
<span class="member-display-name">{{ member.displayName }}</span>
|
||||
<img v-if="member.user.avatar" class="member-avatar" :src="member.user.avatar" :alt="member.user.display_name ?? member.user.username" />
|
||||
<Icon v-else class="member-avatar" name="lucide:user" />
|
||||
<span class="member-display-name">{{ member.user.display_name ?? member.user.username }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</NuxtLayout>
|
||||
|
@ -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%;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -5,8 +5,9 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
const guild = await fetchWithApi(`/guilds/${useRoute().params.serverId}`);
|
||||
console.log("guild:", guild);
|
||||
definePageMeta({
|
||||
middleware: "server"
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
|
|
@ -23,6 +23,14 @@ export interface GuildResponse {
|
|||
member_count: number
|
||||
}
|
||||
|
||||
export interface GuildMemberResponse {
|
||||
uuid: string,
|
||||
nickname: string,
|
||||
user_uuid: string,
|
||||
guild_uuid: string,
|
||||
user: UserResponse
|
||||
}
|
||||
|
||||
export interface ChannelResponse {
|
||||
uuid: string,
|
||||
guild_uuid: string,
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
import type { UserResponse } from "~/types/interfaces"
|
||||
|
||||
export default async (serverId: string, memberId: string): Promise<UserResponse> => {
|
||||
const user = await fetchWithApi(`/guilds/${serverId}/members/${memberId}`) as UserResponse;
|
||||
return user;
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
import type { UserResponse } from "~/types/interfaces"
|
||||
|
||||
export default async (serverId: string, userId: string): Promise<UserResponse> => {
|
||||
const user = await fetchWithApi(`/users/${userId}`) as UserResponse;
|
||||
return user;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue