Skip to content

Commit

Permalink
split the component
Browse files Browse the repository at this point in the history
  • Loading branch information
terryyin committed Oct 25, 2024
1 parent 101d9a9 commit 4bc5849
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 60 deletions.
1 change: 1 addition & 0 deletions frontend/components.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ declare module 'vue' {
CircleNewDialog: typeof import('./src/components/circles/CircleNewDialog.vue')['default']
ContentLoader: typeof import('./src/components/commons/ContentLoader.vue')['default']
ContestableQuestion: typeof import('./src/components/review/ContestableQuestion.vue')['default']
ConversationComponent: typeof import('./src/components/conversations/ConversationComponent.vue')['default']
EditableText: typeof import('./src/components/form/EditableText.vue')['default']
FailureReportList: typeof import('./src/components/admin/FailureReportList.vue')['default']
Feather: typeof import('./src/components/svgs/link_types/Feather.vue')['default']
Expand Down
113 changes: 113 additions & 0 deletions frontend/src/components/conversations/ConversationComponent.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<template>
<div class="px-3 py-3 conversations" v-if="currentConversationMessages">
<div
v-for="conversationMessage in currentConversationMessages"
:key="conversationMessage.id"
class="d-flex mb-3"
:class="{ 'justify-content-end': isCurrentUser(conversationMessage.sender?.id || 0) }"
>
<div
class="card py-2 px-3"
:class="[
isCurrentUser(conversationMessage.sender?.id || 0) ? 'text-bg-dark' : 'bg-light',
conversationMessage.sender?.id === undefined ? 'ai-chat' : '',
]"
>
<template v-if="conversationMessage.sender?.id === undefined">
<SvgRobot />
</template>
{{ formatMessage(conversationMessage.message) }}
</div>
</div>
<div class="chat-controls">
<form class="row chat-input-container" @submit.prevent="handleSendMessage()">
<div class="col-md-10">
<textarea class="w-100" name="Description" v-model="message" />
</div>
<div class="col-md-1">
<input
type="submit"
value="Send"
id="chat-button"
class="btn float-btn btn-secondary"
/>
</div>
</form>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, watch } from "vue"
import useLoadingApi from "@/managedApi/useLoadingApi"
import type { User, ConversationMessage } from "@/generated/backend"
import SvgRobot from "@/components/svgs/SvgRobot.vue"
const props = defineProps<{
conversationId: number
user: User
}>()
const emit = defineEmits<{
(e: "conversation-fetched", conversationId: number): void
}>()
const { managedApi } = useLoadingApi()
const currentConversationMessages = ref<ConversationMessage[] | undefined>(
undefined
)
const message = ref("")
const formatMessage = (message: string) => {
return message.replace(/^"|"$/g, "").trim()
}
const isCurrentUser = (id: number): boolean => {
return id === props.user?.id
}
const fetchConversationMessages = async () => {
currentConversationMessages.value =
await managedApi.restConversationMessageController.getConversationMessages(
props.conversationId
)
emit("conversation-fetched", props.conversationId)
}
const handleSendMessage = async () => {
await managedApi.restConversationMessageController.replyToConversation(
props.conversationId,
message.value
)
message.value = ""
await fetchConversationMessages()
}
onMounted(() => {
fetchConversationMessages()
})
watch(() => props.conversationId, fetchConversationMessages)
</script>
<style scoped>
.conversations {
margin-bottom: 100px;
}
.ai-chat {
color: red;
}
.chat-controls {
position: fixed;
width: 75%;
bottom: 0;
right: 0;
background-color: white;
box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1);
padding: 10px;
}
</style>
74 changes: 14 additions & 60 deletions frontend/src/pages/MessageCenterPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,40 +11,20 @@
<div class="row g-0 h-100">
<div class="col-md-3 bg-light sidebar">
<ul class="list-group">
<li v-for="conversation in conversations" :key="conversation.id" class="list-group-item list-group-item-action" @click="fetchThreadsForConversation(conversation.id || 0)">
<li v-for="conversation in conversations" :key="conversation.id" class="list-group-item list-group-item-action" @click="fetchConversationMessages(conversation.id || 0)">
<div>{{ conversationTopic(conversation) }}</div>
<div>{{ conversationPartner(conversation) }}</div>
</li>
</ul>
</div>
<div class="col-md-9 main-content">
<div class="px-3 py-3 conversations" v-if="currentConversationMessages">
<div v-for="conversationMessage in currentConversationMessages" :key="conversationMessage.id" class="d-flex mb-3" :class="{ 'justify-content-end': isCurrentUser(conversationMessage.sender?.id || 0) }">
<div class="card py-2 px-3" :class="[isCurrentUser(conversationMessage.sender?.id || 0) ? 'text-bg-dark': 'bg-light', conversationMessage.sender?.id === undefined ? 'ai-chat' : '']">
<template v-if="conversationMessage.sender?.id === undefined">
<SvgRobot />
</template>
{{ formatMessage(conversationMessage.message) }}
</div>
</div>
<div class="chat-controls">
<form class="row chat-input-container" @submit.prevent="handleSendMessage()">
<div class="col-md-10">
<textarea class="w-100" name="Description" v-model="message" />
</div>
<div class="col-md-1">
<input
type="submit"
value="Send"
id="chat-button"
class="btn float-btn btn-secondary"
/>
</div>
</form>
</div>
</div>
<ConversationComponent
v-if="currentConversationId && user"
:conversation-id="currentConversationId"
:user="user"
@conversation-fetched="handleConversationFetched"
/>
<h2 v-else>No conversation selected</h2>
</div>
</div>
Expand All @@ -53,15 +33,11 @@
</template>
<script setup lang="ts">
import type { PropType } from "vue"
import { onMounted, ref } from "vue"
import { onMounted, ref, type PropType } from "vue"
import useLoadingApi from "@/managedApi/useLoadingApi"
import ContainerFluidPage from "@/pages/commons/ContainerFluidPage.vue"
import type {
Conversation,
User,
ConversationMessage,
} from "@/generated/backend"
import ConversationComponent from "@/components/conversations/ConversationComponent.vue"
import type { Conversation, User } from "@/generated/backend"
import { messageCenterConversations } from "@/store/messageStore"
const { managedApi } = useLoadingApi()
Expand All @@ -71,40 +47,18 @@ const { user } = defineProps({
})
const conversations = ref<Conversation[] | undefined>(undefined)
const currentConversationId = ref(0)
const currentConversationMessages = ref<ConversationMessage[] | undefined>(
undefined
)
const message = ref("")
const formatMessage = (message: string) => {
return message.replace(/^"|"$/g, "").trim()
}
const isCurrentUser = (id: number): boolean => {
return id === user?.id
}
const currentConversationId = ref<number | null>(null)
const fetchData = async () => {
conversations.value =
await managedApi.restConversationMessageController.getConversationsOfCurrentUser()
}
const handleSendMessage = async () => {
await managedApi.restConversationMessageController.replyToConversation(
currentConversationId.value,
message.value
)
message.value = ""
await fetchThreadsForConversation(currentConversationId.value)
const fetchConversationMessages = async (conversationId: number) => {
currentConversationId.value = conversationId
}
const fetchThreadsForConversation = async (conversationId: number) => {
currentConversationMessages.value =
await managedApi.restConversationMessageController.getConversationMessages(
conversationId
)
currentConversationId.value = conversationId
const handleConversationFetched = async (conversationId: number) => {
messageCenterConversations.unreadConversations =
await managedApi.restConversationMessageController.markConversationAsRead(
conversationId
Expand Down

0 comments on commit 4bc5849

Please sign in to comment.