User is now able to start a new dm chat with another user, optimized message loading
This commit is contained in:
@@ -5,6 +5,7 @@ export interface ptpUser {
|
|||||||
username: string;
|
username: string;
|
||||||
status: string;
|
status: string;
|
||||||
profilepicture: string;
|
profilepicture: string;
|
||||||
|
isPrivate: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface responseModel {
|
export interface responseModel {
|
||||||
@@ -20,6 +21,7 @@ export interface chat{
|
|||||||
displayName: string;
|
displayName: string;
|
||||||
profilepicture: string;
|
profilepicture: string;
|
||||||
profilepictureAsString: string;
|
profilepictureAsString: string;
|
||||||
|
isGroupChat: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface message {
|
export interface message {
|
||||||
|
|||||||
@@ -53,6 +53,7 @@
|
|||||||
:selected="chat.id == selectedChat.id"
|
:selected="chat.id == selectedChat.id"
|
||||||
:chat="chat"
|
:chat="chat"
|
||||||
@click="selectChat(chat as chat)"
|
@click="selectChat(chat as chat)"
|
||||||
|
:lastMessage="getChatPreviewMessage(chat.id)"
|
||||||
></ChatCardComponent>
|
></ChatCardComponent>
|
||||||
|
|
||||||
<ProfileCardComponent
|
<ProfileCardComponent
|
||||||
@@ -61,11 +62,16 @@
|
|||||||
:selected="chat.id == selectedChat.id"
|
:selected="chat.id == selectedChat.id"
|
||||||
@click="selectChat(chat as chat)"
|
@click="selectChat(chat as chat)"
|
||||||
slim
|
slim
|
||||||
|
:lastMessage="getChatPreviewMessage(chat.id)"
|
||||||
></ProfileCardComponent>
|
></ProfileCardComponent>
|
||||||
|
|
||||||
<p v-else>
|
<ChatCardComponent
|
||||||
<span v-for="member in chat.members">{{ member.id }}<br></span>
|
v-else
|
||||||
</p>
|
:selected="chat.id == selectedChat.id"
|
||||||
|
:chat="chat"
|
||||||
|
@click="selectChat(chat as chat)"
|
||||||
|
:lastMessage="getChatPreviewMessage(chat.id)"
|
||||||
|
></ChatCardComponent>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -92,7 +98,7 @@
|
|||||||
:image="selectedChat.members.find((member) => member.id !== userStore.user!.id)?.profilepicture"
|
:image="selectedChat.members.find((member) => member.id !== userStore.user!.id)?.profilepicture"
|
||||||
></HeaderInfoContainerComponent>
|
></HeaderInfoContainerComponent>
|
||||||
|
|
||||||
<div v-else-if="selectedChat.members.length > 2" style="display: flex;">
|
<div v-else style="display: flex;">
|
||||||
<HeaderInfoContainerComponent
|
<HeaderInfoContainerComponent
|
||||||
:displayName="selectedChat.displayName"
|
:displayName="selectedChat.displayName"
|
||||||
:image="selectedChat.profilepictureAsString"
|
:image="selectedChat.profilepictureAsString"
|
||||||
@@ -100,7 +106,8 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<p style="overflow: hidden;white-space: nowrap;text-overflow: ellipsis;line-height: 14px;height:50px;margin: 0px;display: table-cell;vertical-align: middle;padding: 10px;max-width: 300px;">
|
<p style="overflow: hidden;white-space: nowrap;text-overflow: ellipsis;line-height: 14px;height:50px;margin: 0px;display: table-cell;vertical-align: middle;padding: 10px;max-width: 300px;">
|
||||||
<span>Du, </span>
|
<span>Du</span>
|
||||||
|
<span v-if="selectedChat.members.length > 1">, </span>
|
||||||
<span v-for="(user, index) in selectedChat.members.filter(u => u.id != userStore.user!.id)">@{{ user.username }}{{ index < selectedChat.members.length - 2 ? ", " : "" }} </span>
|
<span v-for="(user, index) in selectedChat.members.filter(u => u.id != userStore.user!.id)">@{{ user.username }}{{ index < selectedChat.members.length - 2 ? ", " : "" }} </span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -113,37 +120,13 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div v-if="selectedUser.id != null" id="messageContainer" style="padding: 25px;overflow-y: auto;height: 100%;display: flex;flex-direction: column-reverse;">
|
<div v-if="selectedUser.id != null && selectedChat.members.length == 2" id="messageContainer" style="padding: 25px;overflow-y: auto;height: 100%;display: flex;flex-direction: column-reverse;">
|
||||||
<div v-if="!hasChatWith(selectedUser.id)" style="width: 100%; text-align: center;font-size: 1.2rem;">
|
<div v-if="!hasChatWith(selectedUser.id)" style="width: 100%; text-align: center;font-size: 1.2rem;">
|
||||||
<p>Das ist der Beginn deines Chats mit <strong>{{selectedUser.firstName}} {{selectedUser.lastName}}</strong></p>
|
<p>Das ist der Beginn deines Chats mit <strong>{{selectedUser.firstName}} {{selectedUser.lastName}}</strong></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<p>Du hast schonmal mit dem geschrieben wie schön</p>
|
<p>Du hast schonmal mit dem geschrieben wie schön</p>
|
||||||
|
|
||||||
<div v-for="(message, index) in (messageStore.messages[selectedChat.id])" :key="index">
|
|
||||||
<MessageComponent
|
|
||||||
v-if="message.gif"
|
|
||||||
:url="message.content"
|
|
||||||
:timestamp="message.timestamp"
|
|
||||||
:own-message="message.isOwn"
|
|
||||||
gif
|
|
||||||
></MessageComponent>
|
|
||||||
|
|
||||||
<MessageComponent
|
|
||||||
v-if="!message.gif && message.link"
|
|
||||||
:url="message.content"
|
|
||||||
:timestamp="message.timestamp"
|
|
||||||
:own-message="message.isOwn"
|
|
||||||
link
|
|
||||||
></MessageComponent>
|
|
||||||
|
|
||||||
<MessageComponent
|
|
||||||
v-if="!message.gif && !message.link"
|
|
||||||
:message="message.content"
|
|
||||||
:timestamp="message.timestamp"
|
|
||||||
:own-message="message.isOwn"
|
|
||||||
></MessageComponent>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -173,7 +156,7 @@
|
|||||||
|
|
||||||
<div class="footer">
|
<div class="footer">
|
||||||
|
|
||||||
<q-input filled v-model="message" placeholder="Nachricht eingeben" tabindex="0" @keyup.enter.prevent="sendMessage">
|
<q-input filled v-model="message" placeholder="Nachricht eingeben" tabindex="0" @keyup.enter.prevent="sendMessage" :disable="!selectedChat.id">
|
||||||
<template v-slot:after>
|
<template v-slot:after>
|
||||||
<q-btn round dense flat icon="gif_box" id="sendMessageBtn" style="font-size: 1.2rem;" @click="toggleGifMenu"></q-btn>
|
<q-btn round dense flat icon="gif_box" id="sendMessageBtn" style="font-size: 1.2rem;" @click="toggleGifMenu"></q-btn>
|
||||||
</template>
|
</template>
|
||||||
@@ -219,7 +202,7 @@
|
|||||||
import ProfileCardComponent from 'components/ProfileCardComponent.vue';
|
import ProfileCardComponent from 'components/ProfileCardComponent.vue';
|
||||||
import ChatCardComponent from 'components/ChatCardComponent.vue';
|
import ChatCardComponent from 'components/ChatCardComponent.vue';
|
||||||
import HeaderInfoContainerComponent from 'components/HeaderInfoContainerComponent.vue';
|
import HeaderInfoContainerComponent from 'components/HeaderInfoContainerComponent.vue';
|
||||||
import {message} from 'src/models';
|
import type {message} from 'src/models';
|
||||||
import type {chat, ptpUser} from 'src/models';
|
import type {chat, ptpUser} from 'src/models';
|
||||||
import {useUserStore} from 'stores/user-store';
|
import {useUserStore} from 'stores/user-store';
|
||||||
import { useChatStore } from 'stores/chat-store';
|
import { useChatStore } from 'stores/chat-store';
|
||||||
@@ -257,6 +240,31 @@ import { useMessageStore } from 'src/stores/message-store';
|
|||||||
let messages : message[] = [
|
let messages : message[] = [
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const getChatPreviewMessage = (chatId : number) => {
|
||||||
|
const messageArray : message[] = messageStore.messages[chatId];
|
||||||
|
|
||||||
|
|
||||||
|
if(messageArray && messageArray.length > 0) {
|
||||||
|
const newestMessage = messageArray[0];
|
||||||
|
|
||||||
|
let messageContent = newestMessage.content;
|
||||||
|
let userDescriptor = newestMessage.sender.firstName;
|
||||||
|
|
||||||
|
if(isTenorGifUrl(newestMessage.content)) {
|
||||||
|
messageContent = "GIF";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(newestMessage.sender.id == userStore.user!.id) {
|
||||||
|
userDescriptor = "Du";
|
||||||
|
}
|
||||||
|
|
||||||
|
return userDescriptor + ": " + messageContent;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
return "Der Chat wurde erstellt";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function isUrl(url : string) {
|
function isUrl(url : string) {
|
||||||
try {
|
try {
|
||||||
new URL(url);
|
new URL(url);
|
||||||
@@ -292,7 +300,7 @@ import { useMessageStore } from 'src/stores/message-store';
|
|||||||
|
|
||||||
|
|
||||||
function getGifs() {
|
function getGifs() {
|
||||||
let query = gifSearch.value != "" ? gifSearch.value : "shrek";
|
let query = gifSearch.value != "" ? gifSearch.value : "the office";
|
||||||
|
|
||||||
if(changed.value) {
|
if(changed.value) {
|
||||||
tenorStore.getGifsBySearchTerm(query, loadedGifsAmount);
|
tenorStore.getGifsBySearchTerm(query, loadedGifsAmount);
|
||||||
@@ -309,7 +317,16 @@ import { useMessageStore } from 'src/stores/message-store';
|
|||||||
}
|
}
|
||||||
|
|
||||||
function sendMessage() {
|
function sendMessage() {
|
||||||
messageStore.sendMessage(selectedChat.value.id, userStore.user!.id, message.value);
|
if(selectedChat.value.id != -1) {
|
||||||
|
messageStore.sendMessage(selectedChat.value.id, userStore.user!.id, message.value);
|
||||||
|
} else {
|
||||||
|
messageStore.createChatAndSendFirstMessage(selectedUser.value.id,userStore.user!.id, message.value).then((response) => {
|
||||||
|
reloadChats().then(() => {
|
||||||
|
activeMenu.value = 'chats';
|
||||||
|
selectChat(chatStore.chats.find((chat) => chat.id == response)!);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
message.value = "";
|
message.value = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -325,13 +342,17 @@ import { useMessageStore } from 'src/stores/message-store';
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getMessages() {
|
function getMessages() {
|
||||||
if(selectedChat.value.id != null) {
|
for(let chat of chatStore.chats) {
|
||||||
messageStore.loadMessagesByChatID(selectedChat.value.id);
|
messageStore.loadMessagesByChatID(chat.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setInterval(getMessages, 2000);
|
const reloadChats = async() => {
|
||||||
|
await chatStore.loadChatsByUser();
|
||||||
|
};
|
||||||
|
|
||||||
|
setInterval(getMessages, 5000);
|
||||||
|
|
||||||
|
|
||||||
setInterval(getGifs, 500);
|
setInterval(getGifs, 500);
|
||||||
@@ -347,7 +368,18 @@ import { useMessageStore } from 'src/stores/message-store';
|
|||||||
|
|
||||||
function selectUser(user : ptpUser) {
|
function selectUser(user : ptpUser) {
|
||||||
selectedUser.value = user;
|
selectedUser.value = user;
|
||||||
selectedChat.value = {} as chat;
|
//selectedChat.value = {} as chat;
|
||||||
|
// CHECKEN, OB ES SCHON EINEN CHAT GIBT
|
||||||
|
const exampleChat: chat = {
|
||||||
|
id: -1,
|
||||||
|
members: [user, userStore.user!],
|
||||||
|
messages: [],
|
||||||
|
displayName: user.firstName + " " + user.lastName,
|
||||||
|
profilepicture: user.profilepicture,
|
||||||
|
profilepictureAsString: user.profilepicture,
|
||||||
|
isGroupChat: false
|
||||||
|
};
|
||||||
|
selectedChat.value = exampleChat;
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectChat(chat : chat) {
|
function selectChat(chat : chat) {
|
||||||
@@ -365,22 +397,19 @@ import { useMessageStore } from 'src/stores/message-store';
|
|||||||
// Hier wird geprüft, ob es ein Chat mit einem bestimmten anderen Nutzer existiert
|
// Hier wird geprüft, ob es ein Chat mit einem bestimmten anderen Nutzer existiert
|
||||||
const chatExists = chatStore.chats.find((chat) => chat.members.length === 2 && chat.members.find((member) => member.id === id));
|
const chatExists = chatStore.chats.find((chat) => chat.members.length === 2 && chat.members.find((member) => member.id === id));
|
||||||
|
|
||||||
if(chatExists) return true;
|
return Boolean(chatExists);
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Init methods
|
// Init methods
|
||||||
|
|
||||||
loadChats();
|
loadChats();
|
||||||
|
|
||||||
|
|
||||||
const user = ref();
|
const user = ref();
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
//alert("mounted");
|
|
||||||
user.value = userStore.user;
|
user.value = userStore.user;
|
||||||
//alert(user.value.firstName);
|
|
||||||
})
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -2,11 +2,14 @@ import { defineStore } from 'pinia';
|
|||||||
import { api } from 'src/boot/axios';
|
import { api } from 'src/boot/axios';
|
||||||
import { message, ptpUser, responseModel } from 'src/models';
|
import { message, ptpUser, responseModel } from 'src/models';
|
||||||
import Keycloak, { KeycloakInitOptions, KeycloakLoginOptions } from 'keycloak-js';
|
import Keycloak, { KeycloakInitOptions, KeycloakLoginOptions } from 'keycloak-js';
|
||||||
|
import { useNotificationStore } from './notification-store';
|
||||||
|
import { useUserStore } from './user-store';
|
||||||
|
|
||||||
|
|
||||||
export const useMessageStore = defineStore('messageStore', {
|
export const useMessageStore = defineStore('messageStore', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
messages: [[]] as [message[]],
|
messages: [[]] as [message[]],
|
||||||
|
loadedMessagesForChats: [] as number[],
|
||||||
}),
|
}),
|
||||||
actions: {
|
actions: {
|
||||||
async sendMessage(chatId : number, senderId : string, content : string) {
|
async sendMessage(chatId : number, senderId : string, content : string) {
|
||||||
@@ -16,9 +19,28 @@ export const useMessageStore = defineStore('messageStore', {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async createChatAndSendFirstMessage(receiverId : string, senderId : string, content : string) {
|
||||||
|
const config = { headers: {'Content-Type': 'application/json'} };
|
||||||
|
return (await api.post("/messages/dm/"+senderId+"/"+receiverId, content, config).then((response) => {
|
||||||
|
console.info("LET ME IN");
|
||||||
|
console.info(response.data);
|
||||||
|
console.info(response.data.id);
|
||||||
|
this.loadMessagesByChatID(response.data.id);
|
||||||
|
|
||||||
|
return response.data.id;
|
||||||
|
|
||||||
|
}));
|
||||||
|
},
|
||||||
|
|
||||||
loadMessagesByChatID(chatID : number) {
|
loadMessagesByChatID(chatID : number) {
|
||||||
this.getAllMessagesByChatID(chatID).then((messages) => {
|
const notificationStore = useNotificationStore();
|
||||||
messages.forEach((message : message) => {
|
const userStore = useUserStore();
|
||||||
|
const messagesTemp : message[] = [];
|
||||||
|
|
||||||
|
const initialLoad = !this.loadedMessagesForChats.includes(chatID);
|
||||||
|
|
||||||
|
this.getAllMessagesByChatID(chatID).then((responseBody) => {
|
||||||
|
responseBody.response.forEach((message : message) => {
|
||||||
message.content = message.content.substring(1, message.content.length-1);
|
message.content = message.content.substring(1, message.content.length-1);
|
||||||
if (isUrl(message.content)) {
|
if (isUrl(message.content)) {
|
||||||
if (isTenorGifUrl(message.content)) {
|
if (isTenorGifUrl(message.content)) {
|
||||||
@@ -27,14 +49,33 @@ export const useMessageStore = defineStore('messageStore', {
|
|||||||
message.link = true;
|
message.link = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
this.messages[chatID] = messages;
|
if(!this.loadedMessagesForChats.includes(chatID)){
|
||||||
|
this.messages[chatID] = [];
|
||||||
|
this.loadedMessagesForChats.push(chatID);
|
||||||
|
}
|
||||||
|
if(!initialLoad){
|
||||||
|
if(message.sender.id !== userStore.user!.id) {
|
||||||
|
notificationStore.sendNotificationIfAllowed(message.sender.profilepicture, message.sender.username, message.content);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.messages[chatID].unshift(message);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
async getAllMessagesByChatID(chatID : number) {
|
async getAllMessagesByChatID(chatID : number) {
|
||||||
return (await api.get("/messages/"+chatID)).data;
|
//const timestamp = !this.messages[chatID] ? 0 : this.messages[chatID][0].timestamp;
|
||||||
|
let timestamp = "0";
|
||||||
|
if(this.loadedMessagesForChats.includes(chatID)){
|
||||||
|
timestamp = this.messages[chatID][0].timestamp;
|
||||||
|
}
|
||||||
|
//console.log("Timestamp: "+timestamp);
|
||||||
|
return (await api.get("/messages/"+chatID+"/"+timestamp)).data;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user