work in progress
This commit is contained in:
21
irchad-web/src/components/BufferList.vue
Normal file
21
irchad-web/src/components/BufferList.vue
Normal file
@@ -0,0 +1,21 @@
|
||||
<script setup>
|
||||
import { computed } from "vue";
|
||||
import { useIRCStore } from "@/stores/irc";
|
||||
const { buffers } = useIRCStore();
|
||||
const store = useIRCStore();
|
||||
const bufferList = computed(() => {
|
||||
return Object.keys(buffers);
|
||||
});
|
||||
|
||||
function click(bufferName) {
|
||||
store.setActiveBuffer(bufferName);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-list>
|
||||
<v-list-item v-for="buf in bufferList" @click="click(buf)">
|
||||
{{ buf }}
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</template>
|
||||
60
irchad-web/src/components/Chat.vue
Normal file
60
irchad-web/src/components/Chat.vue
Normal file
@@ -0,0 +1,60 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useIRCStore } from "@/stores/irc";
|
||||
|
||||
const store = useIRCStore();
|
||||
const inputBuffer = ref();
|
||||
|
||||
onMounted(() => {
|
||||
store.connect();
|
||||
});
|
||||
|
||||
function send() {
|
||||
store.sendActiveBuffer(inputBuffer.value);
|
||||
inputBuffer.value = "";
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<div class="d-flex flex-row" style="height: 100vh">
|
||||
<v-sheet border class="buffers">
|
||||
<BufferList />
|
||||
</v-sheet>
|
||||
<div class="messages d-flex flex-column">
|
||||
<MessageList
|
||||
:messages="store.activeBuffer?.messages"
|
||||
:me="store.clientInfo.nick"
|
||||
/>
|
||||
<v-sheet>
|
||||
<v-text-field
|
||||
variant="outlined"
|
||||
:placeholder="`Message ${store.activeBufferName}`"
|
||||
v-model="inputBuffer"
|
||||
hide-details
|
||||
class="ma-2"
|
||||
@keydown.enter.exact.prevent="send"
|
||||
/>
|
||||
</v-sheet>
|
||||
</div>
|
||||
<v-sheet class="user-list h-100" border>
|
||||
<UserList :users="store.activeBuffer?.users" />
|
||||
</v-sheet>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.buffers {
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.messages {
|
||||
height: 100%;
|
||||
flex: 2;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.user-list {
|
||||
height: 100%;
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
61
irchad-web/src/components/MessageList.vue
Normal file
61
irchad-web/src/components/MessageList.vue
Normal file
@@ -0,0 +1,61 @@
|
||||
<script setup>
|
||||
import { computed } from "vue";
|
||||
import { useIRCStore } from "@/stores/irc";
|
||||
const props = defineProps(["messages", "me"]);
|
||||
|
||||
const store = useIRCStore();
|
||||
const messagesReverse = computed(() => {
|
||||
if (props.messages) {
|
||||
return [...props.messages];
|
||||
}
|
||||
});
|
||||
|
||||
const timeFormatter = new Intl.DateTimeFormat("en-US", {
|
||||
hour: "numeric",
|
||||
minute: "2-digit",
|
||||
hour12: true,
|
||||
});
|
||||
function formatTime(ts) {
|
||||
const date = new Date(ts);
|
||||
return timeFormatter.format(date);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-sheet class="message-list d-flex">
|
||||
<v-list>
|
||||
<v-list-item
|
||||
v-for="msg in messagesReverse"
|
||||
density="compact"
|
||||
:prepend-avatar="store.getMetadata(msg.nick, 'avatar')"
|
||||
>
|
||||
<v-list-item-title>
|
||||
<span
|
||||
class="message-nick"
|
||||
:class="{ 'text-primary': me === msg.nick }"
|
||||
>
|
||||
{{ msg.nick }}
|
||||
</span>
|
||||
<span class="message-time" v-if="!!msg.time">{{
|
||||
formatTime(msg.time)
|
||||
}}</span>
|
||||
</v-list-item-title>
|
||||
<v-list-item-subtitle>
|
||||
{{ msg.message }}
|
||||
</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</v-sheet>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.message-list {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
.message-time {
|
||||
font-size: 0.65em;
|
||||
margin-left: 4px;
|
||||
}
|
||||
</style>
|
||||
15
irchad-web/src/components/UserList.vue
Normal file
15
irchad-web/src/components/UserList.vue
Normal file
@@ -0,0 +1,15 @@
|
||||
<script setup>
|
||||
import { useIRCStore } from "@/stores/irc";
|
||||
const props = defineProps(["users"]);
|
||||
const store = useIRCStore();
|
||||
</script>
|
||||
<template>
|
||||
<v-list density="compact">
|
||||
<v-list-item
|
||||
v-for="user in users"
|
||||
:prepend-avatar="store.getMetadata(user.nick, 'avatar')"
|
||||
>
|
||||
{{ user.nick }}
|
||||
</v-list-item>
|
||||
</v-list>
|
||||
</template>
|
||||
Reference in New Issue
Block a user