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>
|
<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">
|
<div class="left-column">
|
||||||
<img v-if="props.img" class="message-author-avatar" :src="props.img" :alt="username">
|
<img v-if="props.img" class="message-author-avatar" :src="props.img" :alt="username">
|
||||||
<Icon v-else name="lucide:user" class="message-author-avatar" />
|
<Icon v-else name="lucide:user" class="message-author-avatar" />
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</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 class="left-column">
|
||||||
<div>
|
<div>
|
||||||
<span :class="{ 'invisible': dateHidden }" class="message-date" :title="date.toString()">
|
<span :class="{ 'invisible': dateHidden }" class="message-date" :title="date.toString()">
|
||||||
|
@ -43,7 +43,8 @@ const props = defineProps<{
|
||||||
timestamp: number,
|
timestamp: number,
|
||||||
format: "12" | "24",
|
format: "12" | "24",
|
||||||
type: "normal" | "grouped",
|
type: "normal" | "grouped",
|
||||||
marginBottom: boolean
|
marginBottom: boolean,
|
||||||
|
last: boolean
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const messageDate = ref<string>();
|
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:", props.text);
|
||||||
console.log("Message.vue: message type:", props.type);
|
console.log("Message.vue: message type:", props.type);
|
||||||
|
console.log("Message.vue: is last?", props.last);
|
||||||
|
|
||||||
let dateHour = date.getHours();
|
let dateHour = date.getHours();
|
||||||
let dateMinute = date.getMinutes();
|
let dateMinute = date.getMinutes();
|
||||||
|
@ -102,6 +104,10 @@ onMounted(() => {
|
||||||
margin-bottom: 1dvh;
|
margin-bottom: 1dvh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#last-message {
|
||||||
|
margin-bottom: 2dvh;
|
||||||
|
}
|
||||||
|
|
||||||
.message-metadata {
|
.message-metadata {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: .5dvw;
|
gap: .5dvw;
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
<template>
|
<template>
|
||||||
<div id="message-area">
|
<div id="message-area">
|
||||||
<div id="messages" ref="messagesElement">
|
<div id="messages" ref="messagesElement">
|
||||||
<div v-for="(message, i) of messages">
|
<Message v-for="(message, i) of messages" :username="message.user.display_name ?? message.user.username"
|
||||||
<Message :username="message.user.display_name ?? message.user.username"
|
|
||||||
:text="message.message" :timestamp="messageTimestamps[message.uuid]" :img="message.user.avatar"
|
:text="message.message" :timestamp="messageTimestamps[message.uuid]" :img="message.user.avatar"
|
||||||
format="12" :type="messagesType[message.uuid]"
|
format="12" :type="messagesType[message.uuid]"
|
||||||
:margin-bottom="messages[i + 1] && messagesType[messages[i + 1].uuid] == 'normal'" />
|
:margin-bottom="messages[i + 1] && messagesType[messages[i + 1].uuid] == 'normal'"
|
||||||
</div>
|
:last="i == messages.length - 1" />
|
||||||
</div>
|
</div>
|
||||||
<div id="message-box" class="rounded-corners">
|
<div id="message-box" class="rounded-corners">
|
||||||
<form id="message-form" @submit="sendMessage">
|
<form id="message-form" @submit="sendMessage">
|
||||||
|
@ -176,7 +175,8 @@ onMounted(async () => {
|
||||||
padding-bottom: 1dvh;
|
padding-bottom: 1dvh;
|
||||||
padding-top: 1dvh;
|
padding-top: 1dvh;
|
||||||
margin-bottom: 1dvh;
|
margin-bottom: 1dvh;
|
||||||
margin-top: 2dvh;
|
margin-left: 1dvw;
|
||||||
|
margin-right: 1dvw;
|
||||||
}
|
}
|
||||||
|
|
||||||
#message-form {
|
#message-form {
|
||||||
|
@ -198,6 +198,8 @@ onMounted(async () => {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 1dvh;
|
gap: 1dvh;
|
||||||
|
padding-left: 1dvw;
|
||||||
|
padding-right: 1dvw;
|
||||||
}
|
}
|
||||||
|
|
||||||
#submit-button {
|
#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);
|
console.log("got gorb.txt:", gorbTxt.value);
|
||||||
const parsed = parseWellKnown(gorbTxt.value as string);
|
const parsed = parseWellKnown(gorbTxt.value as string);
|
||||||
if (parsed.ApiBaseUrl) {
|
if (parsed.ApiBaseUrl) {
|
||||||
apiBase.value = parsed.ApiBaseUrl;
|
apiBase.value = `${parsed.ApiBaseUrl}/${apiVersion}`;
|
||||||
console.log("set apiBase to:", parsed.ApiBaseUrl);
|
console.log("set apiBase to:", parsed.ApiBaseUrl);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { GuildResponse } from '~/types/interfaces';
|
import type { GuildResponse } from '~/types/interfaces';
|
||||||
|
|
||||||
|
|
||||||
const loading = useState("loading", () => false);
|
const loading = useState("loading", () => false);
|
||||||
|
|
||||||
const guilds: GuildResponse[] | undefined = await fetchWithApi("/me/guilds");
|
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" />
|
<MessageArea :channel-url="channelUrlPath" />
|
||||||
<div id="members-list">
|
<div id="members-list">
|
||||||
<div class="member-item" v-for="member of members">
|
<div class="member-item" v-for="member of members">
|
||||||
<img v-if="member.avatar" :src="member.avatar" :alt="member.displayName" height="30" />
|
<img v-if="member.user.avatar" class="member-avatar" :src="member.user.avatar" :alt="member.user.display_name ?? member.user.username" />
|
||||||
<Icon v-else name="lucide:user" size="30" />
|
<Icon v-else class="member-avatar" name="lucide:user" />
|
||||||
<span class="member-display-name">{{ member.displayName }}</span>
|
<span class="member-display-name">{{ member.user.display_name ?? member.user.username }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</NuxtLayout>
|
</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 }[];
|
//const servers = await fetchWithApi("/servers") as { uuid: string, name: string, description: string }[];
|
||||||
//console.log("channelid: servers:", servers);
|
//console.log("channelid: servers:", servers);
|
||||||
const members = [
|
|
||||||
{
|
const { fetchMembers } = useApi();
|
||||||
id: "3287484395",
|
const members = await fetchMembers(route.params.serverId as string);
|
||||||
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: ""
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
console.log("channelid: set loading to true");
|
console.log("channelid: set loading to true");
|
||||||
|
@ -129,6 +85,7 @@ function toggleInvitePopup(e: Event) {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: .5em;
|
margin-top: .5em;
|
||||||
margin-bottom: .5em;
|
margin-bottom: .5em;
|
||||||
|
gap: .5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#members-list {
|
#members-list {
|
||||||
|
@ -153,4 +110,10 @@ function toggleInvitePopup(e: Event) {
|
||||||
gap: 1dvh;
|
gap: 1dvh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.member-avatar {
|
||||||
|
height: 2.3em;
|
||||||
|
width: 2.3em;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
|
@ -5,8 +5,9 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
const guild = await fetchWithApi(`/guilds/${useRoute().params.serverId}`);
|
definePageMeta({
|
||||||
console.log("guild:", guild);
|
middleware: "server"
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,14 @@ export interface GuildResponse {
|
||||||
member_count: number
|
member_count: number
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface GuildMemberResponse {
|
||||||
|
uuid: string,
|
||||||
|
nickname: string,
|
||||||
|
user_uuid: string,
|
||||||
|
guild_uuid: string,
|
||||||
|
user: UserResponse
|
||||||
|
}
|
||||||
|
|
||||||
export interface ChannelResponse {
|
export interface ChannelResponse {
|
||||||
uuid: string,
|
uuid: string,
|
||||||
guild_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