From da151c13ed3879b6c8c4154253d1ea912c62a82d Mon Sep 17 00:00:00 2001 From: Nell Date: Sat, 22 Aug 2026 20:34:43 +0200 Subject: [PATCH] init --- frontend/src/pages/index.vue | 83 +++++++++++++++++-- frontend/src/pages/server/channel/index.vue | 49 +++++++++++- frontend/src/pages/server/index.vue | 3 +- frontend/src/router/index.ts | 8 ++ frontend/src/stores/conversation.ts | 48 +++++++++++ src/domain/dto/conversation.rs | 31 ++++++++ src/domain/dto/mod.rs | 1 + src/routes/channel/handlers.rs | 24 +++--- src/routes/conversation/handlers.rs | 88 +++++++++++++++++++++ src/routes/conversation/mod.rs | 2 + src/routes/conversation/routes.rs | 9 +++ src/routes/message/handlers.rs | 32 ++++++++ src/routes/mod.rs | 2 + src/routes/openapi.rs | 7 ++ 14 files changed, 366 insertions(+), 21 deletions(-) create mode 100644 frontend/src/stores/conversation.ts create mode 100644 src/domain/dto/conversation.rs create mode 100644 src/routes/conversation/handlers.rs create mode 100644 src/routes/conversation/mod.rs create mode 100644 src/routes/conversation/routes.rs diff --git a/frontend/src/pages/index.vue b/frontend/src/pages/index.vue index fd71d59..b7d949c 100644 --- a/frontend/src/pages/index.vue +++ b/frontend/src/pages/index.vue @@ -1,9 +1,82 @@ - \ No newline at end of file + +
+ Messages + + +
+ + + + + + + + +
+ + + +
+ +
Vos discussions
+
Sélectionnez une discussion ou commencez-en une nouvelle.
+ Nouvelle discussion +
+
+ + + + Nouvelle discussion + + AnnulerCréer + + + + + diff --git a/frontend/src/pages/server/channel/index.vue b/frontend/src/pages/server/channel/index.vue index ebf547e..3c2e34b 100644 --- a/frontend/src/pages/server/channel/index.vue +++ b/frontend/src/pages/server/channel/index.vue @@ -10,9 +10,11 @@ import {onReloadAll} from '@/plugins/events.ts' import EmojiPicker from '@/components/EmojiPicker.vue' import {useEmojiStore, type Emoji} from '@/stores/emoji.ts' import {useAuthStore} from '@/stores/auth.ts' +import {useConversationStore} from '@/stores/conversation' +import {useRoute, useRouter} from 'vue-router' const props = defineProps<{ - serverId: string + serverId?: string channelId: string }>(); @@ -22,6 +24,9 @@ const serverStore = useServerStore(); const userStore = useUserStore(); const emojiStore = useEmojiStore(); const authStore = useAuthStore(); +const conversationStore = useConversationStore() +const route = useRoute() +const router = useRouter() const {renderMarkdown} = useMarkdown() const messageContainer = ref(null); @@ -35,6 +40,16 @@ const paginationLockScrollTop = ref(0); const lastScrollTop = ref(0); const markedMessageByChannel = new Map(); const reactionPending = ref(new Set()); +const isConversation = computed(() => route.name === 'home-conversation') +const addParticipantDialog = ref(false) +const selectedParticipantIds = ref([]) +const addingParticipants = ref(false) +const currentConversation = computed(() => conversationStore.conversations.find(item => item.id === channelId.value)) +const availableParticipants = computed(() => userStore.users.filter(user => + user.id !== authStore.currentUser?.id && + !currentConversation.value?.participants.some(participant => participant.id === user.id) && + !selectedParticipantIds.value.includes(user.id), +)) const markCurrentChannelRead = async (targetChannelId: string) => { if (messageStore.activeChannelId !== targetChannelId || !newestId.value) return; @@ -47,12 +62,24 @@ const markCurrentChannelRead = async (targetChannelId: string) => { if (messageStore.activeChannelId !== targetChannelId) return; markedMessageByChannel.set(targetChannelId, messageId); - serverStore.applyChannelReadState(props.serverId, targetChannelId, readState.unread_count); + if (isConversation.value) conversationStore.applyReadState(targetChannelId, readState.unread_count) + else if (props.serverId) serverStore.applyChannelReadState(props.serverId, targetChannelId, readState.unread_count); } catch (error) { console.error('Erreur lors de la mise à jour de la lecture:', error); } }; +const forkConversation = async () => { + if (!selectedParticipantIds.value.length) return + addingParticipants.value = true + try { + const conversation = await conversationStore.forkConversation(channelId.value, selectedParticipantIds.value) + addParticipantDialog.value = false + selectedParticipantIds.value = [] + await router.push(`/conversation/${conversation.id}`) + } finally { addingParticipants.value = false } +} + const showRecentMessagesButton = computed(() => !loading.value && (hasMoreAfter.value || !isAtBottom.value), ); @@ -247,7 +274,7 @@ watch(isAtBottom, async (atBottom) => { watch(channelId, async (newChannelId) => { if (newChannelId) { - await emojiStore.fetchEmojis(props.serverId); + if (props.serverId) await emojiStore.fetchEmojis(props.serverId); await messageStore.fetchMessages(newChannelId); await scrollToBottom(); await markCurrentChannelRead(newChannelId); @@ -261,6 +288,12 @@ watch(() => props.serverId, (newServerId) => {