Skip to content

Commit

Permalink
Finished Directmessages + Reactions (Hellsticks96#153)
Browse files Browse the repository at this point in the history
* implemented old image upload

Co-Authored-By: Kaser Mahmood <[email protected]>

* implemented image upload in thread and directmessages, improved image upload style & fixed no upload without text

* fixed failed check

* fully integrated directmessages for both side communication, fixed reactions in directmessages

* fixed profil pic in directmessage

---------

Co-authored-by: Kaser Mahmood <[email protected]>
  • Loading branch information
Kakar21 and KasZaim authored Sep 8, 2024
1 parent 0d95a18 commit 01f9539
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ <h5 (click)="openProfileById(message.value.id)">{{ message.value.name }}</h5>
</div>
</div>
</div>
<div class="emoji-picker" *ngIf="isPickerVisible && pickerContext === 'reaction'">
<div class="emoji-picker" *ngIf="isPickerVisible && pickerContext === 'reaction'" [ngStyle]="{ top: pickerPosition.top, left: pickerPosition.left }">
<emoji-mart (emojiClick)="addEmoji($event)"></emoji-mart>
</div>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
width: 4.375rem;
height: 4.375rem;
border-radius: 50%;
object-fit: cover;
}

> div:not(.message-info, .hoverMenu) {
Expand Down
31 changes: 25 additions & 6 deletions src/app/main/chat/direct-message/direct-message.component.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Component, ElementRef, Input, ViewChild } from "@angular/core";
import { Component, ElementRef, HostListener, Input, ViewChild } from "@angular/core";
import { ChatComponent } from "../chat.component";
import { PickerComponent } from "@ctrl/ngx-emoji-mart";
import { MatDialog, MatDialogModule } from "@angular/material/dialog";
Expand Down Expand Up @@ -57,6 +57,7 @@ export class DirectMessageComponent {
currentInputValue: string = "";
@ViewChild("messageInput") messageInput!: ElementRef<HTMLInputElement>;
pickerContext: string = "";
pickerPosition = { top: '0px', left: '0px' };
currentMessagePadnumber: string = "";
previewUrl: string | ArrayBuffer | null = null;

Expand All @@ -81,15 +82,32 @@ export class DirectMessageComponent {
log() {
console.log();
}

@HostListener('window:resize', ['$event'])
onResize(event: Event) {
this.isPickerVisible = false;
}

togglePicker(context: string, padNr: any, event: MouseEvent) {
this.isPickerVisible = !this.isPickerVisible;
this.pickerContext = context;
this.currentMessagePadnumber = padNr;
if (this.isPickerVisible) {
const pickerHeight = 350; // Geschätzte Höhe des Emoji-Pickers
const pickerWidth = 300; // Geschätzte Breite des Emoji-Pickers

let top = Math.min(event.clientY, window.innerHeight - pickerHeight);
let left = Math.min(event.clientX, window.innerWidth - pickerWidth);

this.pickerPosition = { top: `${top}px`, left: `${left}px` };
}
}

closePicker(event: Event) {
if (this.isPickerVisible) {
this.isPickerVisible = false;
this.pickerContext = "";
this.currentMessagePadnumber = "";
}
}
addEmoji(event: any) {
Expand All @@ -102,16 +120,17 @@ export class DirectMessageComponent {
);
}
}

addReactionToMessage(messagePadnr: string, emoji: string) {
this.chatService
.addReaction(this.chatService.selectedUser.id, emoji, 'DM', messagePadnr)
this.DMSerivce.addReaction(messagePadnr, emoji, this.chatService.selectedUser.id)
.then(() => console.log("Reaction added"))
.catch((error) => console.error("Error adding reaction: ", error));
}

addOrSubReaction(message: any, reaction: any,) {
debugger;
this.chatService.addOrSubReaction(message, reaction, 'DM', this.chatService.selectedUser.id);
addOrSubReaction(message: any, reaction: string) {
this.DMSerivce.addOrSubReaction(message, reaction, this.chatService.selectedUser.id)
.then(() => console.log("Reaction added or removed"))
.catch((error) => console.error("Error adding/removing reaction: ", error));
}

openDialogChannelInfo() {
Expand Down
144 changes: 125 additions & 19 deletions src/app/main/chat/direct-message/directmessage.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable } from "@angular/core";
import { CurrentuserService } from "../../../currentuser.service";
import { Firestore, collection, doc, getDocs, onSnapshot, orderBy, query, setDoc, updateDoc, DocumentReference, getDoc } from "@angular/fire/firestore";
import { Firestore, collection, doc, getDocs, onSnapshot, orderBy, query, setDoc, updateDoc, DocumentReference, getDoc, where } from "@angular/fire/firestore";
import { serverTimestamp } from "@angular/fire/firestore";
import { Message } from "../../../interfaces/message";
import { ChatService } from "../chat.service";
Expand All @@ -12,68 +12,174 @@ export class DirectmessageService {
sendedUserID!: string;
messages: Record<string, Message> = {};
allMessages: { [userId: string]: { [messageId: string]: any } } = {};
selectedPadnumber: string = "";

constructor(
public currentUser: CurrentuserService,
private firestore: Firestore,
private chat: ChatService,
) {
console.log(this.messages)
}
) {}

async sendMessage(sendedUserID: string, message: Message) {
this.sendedUserID = sendedUserID;
const chatId = this.currentUser.currentUser.id < sendedUserID
? `${this.currentUser.currentUser.id}_${sendedUserID}`
: `${sendedUserID}_${this.currentUser.currentUser.id}`;

const userRef = collection(
this.firestore,
`users/${this.currentUser.currentUser.id}/${sendedUserID}/`,
`directmessages/${chatId}/messages`
);

const messagesSnapshot = await getDocs(userRef);
const messageCount = messagesSnapshot.size;
const newMessageRef = doc(userRef, this.padNumber(messageCount, 4));

const newMessage: Message = {
id: this.currentUser.currentUser.id,
avatar: this.currentUser.currentUser.avatar, // avatar: message.avatar,
avatar: this.currentUser.currentUser.avatar,
name: this.currentUser.currentUser.name,
time: message.time,
message: message.message,
createdAt: serverTimestamp(),
reactions: {},
padNumber: "",
padNumber: this.selectedPadnumber,
btnReactions: [],
imageUrl: message.imageUrl
};

try {
await setDoc(newMessageRef, newMessage, { merge: true });
} catch (error) {
console.error("Failed to send message:", error);
}
}

async addReaction(messagePadNr: string, emoji: string, userId: string) {
// Eindeutigen Chat-Pfad erstellen
const chatId = this.currentUser.currentUser.id < userId
? `${this.currentUser.currentUser.id}_${userId}`
: `${userId}_${this.currentUser.currentUser.id}`;

const messagesRef = collection(
this.firestore,
`directmessages/${chatId}/messages`
);

const messageRef = doc(messagesRef, messagePadNr);
const messageSnapshot = await getDoc(messageRef);

if (!messageSnapshot.exists()) {
console.error(`Message with ID ${messagePadNr} not found`);
return;
}

const messageData = messageSnapshot.data();
if (!messageData["reactions"]) {
messageData["reactions"] = {};
}

if (!messageData["reactions"][emoji]) {
messageData["reactions"][emoji] = {
count: 0,
users: []
};
}

const reaction = messageData["reactions"][emoji];
const currentUserName = this.currentUser.currentUser.name;

if (!reaction.users.includes(currentUserName)) {
messageData["reactions"][emoji].count++;
messageData["reactions"][emoji].users.push(currentUserName);
await updateDoc(messageRef, { reactions: messageData["reactions"] });
}
}

async addOrSubReaction(message: Message, reaction: string, userId: string) {
const chatId = this.currentUser.currentUser.id < userId
? `${this.currentUser.currentUser.id}_${userId}`
: `${userId}_${this.currentUser.currentUser.id}`;

const messagesRef = collection(
this.firestore,
`directmessages/${chatId}/messages`
);

const messageRef = doc(messagesRef, message.toString());
const messageSnapshot = await getDoc(messageRef);

if (!messageSnapshot.exists()) {
console.error(`Message with ID ${message.padNumber} not found`);
return;
}

const messageData = messageSnapshot.data();
const currentUserName = this.currentUser.currentUser.name;

if (!messageData["reactions"]) {
messageData["reactions"] = {
[reaction]: { count: 0, users: [] }
};
}

const reactionData = messageData["reactions"][reaction] || { count: 0, users: [] };
const userIndex = reactionData.users.indexOf(currentUserName);

if (userIndex === -1) {
// Reaktion hinzufügen
reactionData.users.push(currentUserName);
reactionData.count++;
} else {
// Reaktion entfernen
reactionData.users.splice(userIndex, 1);
reactionData.count--;

if (reactionData.count === 0) {
delete messageData["reactions"][reaction];
}
}

await updateDoc(messageRef, { reactions: messageData["reactions"] });
}

padNumber(num: number, size: number) {
let s = num + "";
while (s.length < size) s = "0" + s;
this.selectedPadnumber = s;
return s;
}

getMessages(id: string) {
const channelRef = collection(
getMessages(userId: string) {
// Erstelle einen eindeutigen Pfad basierend auf beiden Benutzer-IDs
const chatId = this.currentUser.currentUser.id < userId
? `${this.currentUser.currentUser.id}_${userId}`
: `${userId}_${this.currentUser.currentUser.id}`;

const messagesRef = collection(
this.firestore,
`users/${this.currentUser.currentUser.id}/${id}/`,
`directmessages/${chatId}/messages`
);
const newMessageRef = doc(channelRef);

const messagesQuery = query(channelRef, orderBy("time"));


// Abfrage für Nachrichten, nur sortiert nach 'padNumber'
const messagesQuery = query(
messagesRef,
orderBy("padNumber") // Nur nach 'padNumber' sortieren
);

// Echtzeitlistener
onSnapshot(messagesQuery, (querySnapshot) => {
this.messages = {};

this.messages = {}; // Nachrichten leeren
querySnapshot.forEach((doc) => {
const messageData = doc.data() as Message;
this.messages[doc.id] = messageData;
this.messages[doc.id] = messageData; // Nachricht speichern mit ihrer ID als Schlüssel
});
});
}





getAllMessages() {
this.allMessages = {};
Expand Down

0 comments on commit 01f9539

Please sign in to comment.