stream day 3

This commit is contained in:
Zoe
2023-01-05 19:16:43 -06:00
parent c55cf2867b
commit 108bb6d6fb
11 changed files with 257 additions and 63 deletions

18
App.vue
View File

@@ -2,9 +2,12 @@
<div>
<NuxtLayout>
<div class="flex h-screen max-h-screen">
<Nav />
<Sidebar />
<NuxtPage />
<Nav :servers="servers" />
<Sidebar :server="activeServer"
:user="user" />
<div class="w-full h-full">
<NuxtPage :user="user" />
</div>
</div>
</NuxtLayout>
</div>
@@ -12,12 +15,19 @@
<script lang="ts">
import { useUserStore } from '~/stores/user'
import { useServerStore } from './stores/servers'
export default {
data() {
return {
servers: useServerStore().servers,
activeServer: storeToRefs(useServerStore()).activeServer,
user: useUserStore().user
}
},
async setup() {
const userStore = useUserStore()
const sessionToken = useCookie('sessionToken')
console.log(sessionToken.value)
if (userStore.user.id === undefined && sessionToken.value) {
const user = await $fetch('/api/getCurrentUser')

View File

@@ -1,8 +1,8 @@
<template>
<nav class="p-4 bg-zinc-800 grid grid-cols-1 grid-rows-[56px_1fr_56px] h-screen text-white relative">
<nav class="p-4 bg-[hsl(216,calc(1*7.2%),13.5%)] grid grid-cols-1 grid-rows-[56px_1fr_56px] h-screen min-w-[88px] text-white relative">
<div>
<div
@click="openServer('@me')"
@click="openServer('@me', 'dms')"
class="bg-zinc-600/80 p-3 rounded-full transition-all hover:rounded-2xl ease-in-out hover:bg-zinc-500/60 duration-300">
<svg width="32"
height="32"
@@ -16,10 +16,10 @@
</svg>
</div>
</div>
<div class="overflow-y-scroll my-2 flex gap-2">
<div class="overflow-y-scroll my-2 flex gap-y-2 flex-col">
<div v-for="server in servers"
:key="server.id"
@click="openServer(server.id)"
@click="openServer(server.id, 'servers')"
class="bg-zinc-600/80 p-3 rounded-full transition-all hover:rounded-2xl ease-in-out hover:bg-zinc-500/60 duration-300 h-[56px] w-[56px]">
<svg width="32"
height="32"
@@ -89,7 +89,6 @@ import { useServerStore } from '~/stores/servers'
export default {
data() {
return {
servers: useServerStore().servers,
createServerModelOpen: false,
serverName: ''
}
@@ -102,15 +101,12 @@ export default {
this.serverName = '';
serverStore.addServer(server)
},
openServer(id: string): void {
openServer(id: string, type: string): void {
const router = useRouter();
useServerStore().servers.find((e: unknown, i: number) => {
if (e.id === id) {
useServerStore().activeServer = i
}
})
useServerStore().setActive(type, id)
router.push({ path: `/channel/${id}` });
}
}
},
props: ['servers']
}
</script>

View File

@@ -1,5 +1,5 @@
<template>
<div class="flex bg-zinc-700 w-60 h-screen shadow-sm text-white select-none">
<div class="flex bg-[hsl(223,calc(1*6.9%),19.8%)] min-w-60 w-60 h-screen shadow-sm text-white select-none">
<div class="w-full"
v-if="server">
<div class="flex p-4 border-b border-zinc-600/80">
@@ -22,20 +22,6 @@
d="M5 9h14M5 15h14M11 4L7 20M17 4l-4 16" />
</svg> {{ channel.name }}
</div>
<div class="flex text-center hover:bg-zinc-600/70 px-2 py-1.5 w-full transition-colors rounded drop-shadow-sm"
v-for="channel in server.channels"
:key="channel.id">
<svg width="24"
height="24"
viewBox="0 0 24 24">
<path fill="none"
stroke="currentColor"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
d="M5 9h14M5 15h14M11 4L7 20M17 4l-4 16" />
</svg> {{ channel.name }}
</div>
</div>
</div>
@@ -43,22 +29,12 @@
</template>
<script lang="ts">
import { useUserStore } from '~/stores/user'
import { useServerStore } from '~/stores/servers'
export default {
data() {
return {
user: useUserStore().user,
server: useServerStore().servers[useServerStore().activeServer]
}
},
mounted() {
const route = useRoute()
if (route.path.includes('@me')) {
this.server = useServerStore().dms[useServerStore().activeServer]
}
}
console.log(useServerStore().currentServer, useServerStore().servers)
},
props: ['server', 'user']
}
</script>

View File

@@ -28,6 +28,7 @@ export default {
autoImports: [
// automatically imports `defineStore`
'defineStore', // import { defineStore } from 'pinia'
'storeToRefs',
// automatically imports `defineStore` as `definePiniaStore`
['defineStore', 'definePiniaStore'], // import { defineStore as definePiniaStore } from 'pinia'
],

View File

@@ -1,16 +1,105 @@
<template>
hello world
<div class="w-full h-full bg-[hsl(220,calc(1*7.7%),22.9%)] relative text-white">
<div class="w-full h-[calc(100%-60px)] overflow-y-scroll pb-1"
id="conversation-pane">
<div>
<div v-if="conversation.length === 0">
<p>No messages yet</p>
</div>
<div v-else
v-for="conversations in conversation">
<div v-if="conversations.userId == user.id"
class="message-container"
id="messages-container">
<div class="message-sender">
<div class="message-sender-text">
<p class="message-sender-you">You</p>
<p>{{ conversations.body }}</p>
</div>
</div>
</div>
<div v-else
class="message-container">
<div class="message-sender">
<div class="message-sender-text">
<p class="message-sender-you">{{ conversations.userId }}</p>
<p>{{ conversations.body }}</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="conversation-input w-full">
<form @submit.prevent="sendMessage"
class="relative px-4 w-[calc(100%-12rem)]">
<input type="text"
class="py-2 px-4 rounded-md bg-[hsl(218,calc(1*7.9%),27.3%)]"
id="message"
v-model="messageContent"
placeholder="Send a Message..." />
<input type="submit"
class=""
value="Send" />
</form>
</div>
</div>
</template>
<script>
<script lang="ts">
import { useServerStore } from '~/stores/servers'
export default {
data() {
return {
conversation: [],
messageContent: ''
}
},
async setup() {
const route = useRoute()
const { server } = await $fetch(`/api/channel/${route.params.dmId}`)
if (!useServerStore().dms.includes(server)) useServerStore().addDM(server);
if (!server) return;
useServerStore().addDM(server);
const channelId = server.channels[0].id
await useServerStore().setActive('dms', server.id);
return {
server,
channelId
}
},
async mounted() {
const { channel } = await $fetch(`/api/channel/messages/${this.channelId}`)
this.conversation = channel.messages
},
async updated() {
if (!useServerStore().activeServer == this.server) await useServerStore().setActive('dms', this.server.id)
},
methods: {
async sendMessage() {
const route = useRoute()
if (!this.messageContent) return;
const { message } = await $fetch(`/api/channel/sendMessage`, { method: 'post', body: { body: this.messageContent, channelId: this.channelId } })
this.conversation.push(message)
}
},
props: ['user']
}
</script>
<style scoped>
.conversation-input {
display: flex;
position: fixed;
flex-direction: row;
margin-top: 0.5rem;
margin-bottom: 0.5rem;
height: 60px;
border-top: #ffffff 1px solid;
background-color: #3C3C3C;
bottom: calc(0px - 0.5rem);
}
</style>

View File

@@ -1,12 +1,25 @@
<template>
hello world
{{ $route.params.id }}
</template>
<script setup async>
<script lang="ts">
import { useServerStore } from '~/stores/servers'
export default {
async setup() {
const route = useRoute()
const { server } = await $fetch(`/api/channel/${route.params.id}`)
if (!useServerStore().servers.includes(server)) useServerStore().addServer(server);
if (!server) return;
useServerStore().addServer(server);
await useServerStore().setActive('servers', server.id)
return {
server
}
},
async updated() {
if (!this.server) return;
if (!await useServerStore().activeServer == this.server.id) await useServerStore().setActive('servers', this.server.id)
}
}
</script>

View File

@@ -12,10 +12,10 @@ model User {
email String @unique
username String @unique
passwordhash String
Server Server[]
server Server[]
serverId String?
Messages Message[]
Session Session[]
messages Message[]
session Session[]
}
model Server {
@@ -28,9 +28,9 @@ model Server {
model Channel {
id String @id @default(cuid())
name String
Server Server? @relation(fields: [serverId], references: [id])
server Server? @relation(fields: [serverId], references: [id])
serverId String?
Message Message[]
messages Message[]
}
model Message {

View File

@@ -0,0 +1,35 @@
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
export default defineEventHandler(async (event) => {
if (!event.context.user.authenticated) return {
message: 'You must be logged in to view a channel.'
}
if (!event.context.params.id) {
event.node.res.statusCode = 400;
return {
message: 'A channelId is required'
}
}
const channel = await prisma.channel.findFirst({
where: {
id: event.context.params.id
},
include: {
messages: true,
}
})
if (!channel) {
event.node.res.statusCode = 404;
return {
message: `Channel with id "${event.context.params.id}" not found`
}
}
return {
channel
}
})

View File

@@ -0,0 +1,71 @@
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
export default defineEventHandler(async (event) => {
if (!event.context.user.authenticated) {
event.node.res.statusCode = 401;
return {
message: 'You must be logged in to send a message.'
}
}
const { body, channelId } = await readBody(event)
if (!body || !channelId) {
event.node.res.statusCode = 400;
return {
message: 'A body or channelId is required to send a message.'
}
}
const channel = await prisma.channel.findFirst({
where: {
id: channelId
}
})
const server = await prisma.server.findFirst({
where: {
id: channel.serverId
},
include: {
participants: true
}
})
const userInServer = server.participants.filter((e) => e.id === event.context.user.id)
if (!userInServer.length > 0) {
event.node.res.statusCode = 401;
return {
message: 'You must be in the server to send a message.'
}
}
if (!server) {
event.node.res.statusCode = 404;
return {
message: 'Server not found'
}
}
const message = await prisma.message.create({
data: {
body,
creator: {
connect: {
id: event.context.user.id
}
},
channel: {
connect: {
id: channelId
}
}
}
})
return {
message
}
})

View File

@@ -4,8 +4,6 @@ const prisma = new PrismaClient()
export default defineEventHandler(async (event) => {
const cookies = parseCookies(event)
console.log(cookies.sessionToken)
if (!cookies.sessionToken) {
event.context.user = { authenticated: false }
return;

View File

@@ -2,14 +2,19 @@ export const useServerStore = defineStore('server', {
state: () => ({
servers: [],
dms: [],
activeServer: undefined
activeServer: {}
}),
actions: {
addServer(server) {
if (this.servers.includes(server)) return;
this.servers.push(server)
},
addDM(server) {
if (this.dms.includes(server)) return;
this.dms.push(server)
}
},
setActive(type, serverId) {
this.activeServer = this[type].find((e) => e.id === serverId)
},
},
})