Skip to content

Commit 10b035c

Browse files
authored
Merge pull request #412 from Ketteiteki/add_reply_and_showing_attachment_pic
add reply and showing attachment pic
2 parents dd8f7bc + c54e487 commit 10b035c

8 files changed

Lines changed: 280 additions & 10 deletions

File tree

MangoAPI.Client/src/app/components/chats/chats.component.html

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,10 @@ <h5>Chats</h5>
224224
/>
225225
<div class="message-wrapper">
226226
<div class="message-content">
227+
<div *ngIf="message.inReplayToAuthor" class="message-reply">
228+
<p class="message-reply-displayname">{{ message.inReplayToAuthor }}</p>
229+
<p class="message-reply-text">{{ message.inReplayToText }}</p>
230+
</div>
227231
<span *ngIf="message.messageAttachmentUrl"
228232
><img
229233
class="message-image"
@@ -278,7 +282,18 @@ <h5>Chats</h5>
278282
</div>
279283
</div>
280284
<div class="message-button">
281-
<img alt="Reply Icon" src="./../../../assets/svg/reply.svg" />
285+
<img
286+
alt="Reply Icon"
287+
src="./../../../assets/svg/reply.svg"
288+
(click)="
289+
onReplyClick(
290+
message.messageId,
291+
message.userDisplayName,
292+
message.messageText,
293+
message.userDisplayNameColour
294+
)
295+
"
296+
/>
282297
</div>
283298
</div>
284299
</div>
@@ -303,6 +318,16 @@ <h5>Chats</h5>
303318
>
304319
{{ message.userDisplayName }}
305320
</div>
321+
<div *ngIf="message.inReplayToAuthor" class="message-reply">
322+
<p
323+
class="message-reply-displayname {{
324+
getDisplayNameColour(message.userDisplayNameColour)
325+
}}"
326+
>
327+
{{ message.inReplayToAuthor }}
328+
</p>
329+
<p class="message-reply-text">{{ message.inReplayToText }}</p>
330+
</div>
306331
<span *ngIf="message.messageAttachmentUrl"
307332
><img
308333
class="message-image"
@@ -317,7 +342,18 @@ <h5>Chats</h5>
317342
{{ toShortTimeString(message.createdAt) }}
318343
</p>
319344
<div class="message-button">
320-
<img alt="Reply Icon" src="./../../../assets/svg/reply.svg" />
345+
<img
346+
alt="Reply Icon"
347+
src="./../../../assets/svg/reply.svg"
348+
(click)="
349+
onReplyClick(
350+
message.messageId,
351+
message.userDisplayName,
352+
message.messageText,
353+
message.userDisplayNameColour
354+
)
355+
"
356+
/>
321357
</div>
322358
</div>
323359
</div>
@@ -327,7 +363,47 @@ <h5>Chats</h5>
327363
</li>
328364
</ul>
329365
</div>
330-
366+
<div *ngIf="_replyStateService.reply" class="reply">
367+
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
368+
<svg
369+
class="reply-svg"
370+
fill="#adb5bd"
371+
height="45"
372+
width="45"
373+
viewBox="0 0 45 45"
374+
xmlns="http://www.w3.org/2000/svg"
375+
>
376+
<path
377+
d="M10.53 5.03a.75.75 0 10-1.06-1.06l-6.25 6.25a.75.75 0 000 1.06l6.25 6.25a.75.75 0 101.06-1.06L5.56 11.5H17a3.248 3.248 0 013.25 3.248v4.502a.75.75 0 001.5 0v-4.502A4.748 4.748 0 0017 10H5.56l4.97-4.97z"
378+
/>
379+
</svg>
380+
<div class="reply-container">
381+
<p
382+
class="reply-displayname {{
383+
getDisplayNameColour(_replyStateService.reply.displayNameColour)
384+
}}"
385+
>
386+
{{ _replyStateService.reply.displayName }}
387+
</p>
388+
<p class="reply-text">{{ _replyStateService.reply.text }}</p>
389+
</div>
390+
<img
391+
src="../../../assets/svg/cross.svg"
392+
class="cross-svg"
393+
(click)="_replyStateService.setReplyNull()"
394+
/>
395+
</div>
396+
<div *ngIf="messageAttachment" class="attachment">
397+
<img src="{{messageAttachmentBlobUrl}}" class="attachment-image" alt="">
398+
<div class="attachment-container">
399+
<p class="attachment-filename">{{messageAttachment.name}}</p>
400+
</div>
401+
<img
402+
src="../../../assets/svg/cross.svg"
403+
class="cross-svg"
404+
(click)="removeImageSelected()"
405+
/>
406+
</div>
331407
<div class="chat-footer" *ngIf="activeChat.isMember; else elseNotMember">
332408
<div class="dropdown">
333409
<button class="button-dark button-dark-no-hover align-text-top" data-bs-toggle="dropdown">

MangoAPI.Client/src/app/components/chats/chats.component.ts

Lines changed: 54 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ import { ValidationService } from '../../services/messenger/validation.service';
1515
import * as signalR from '@microsoft/signalr';
1616
import { EditMessageNotification } from '../../types/models/EditMessageNotification';
1717
import { DeleteMessageNotification } from '../../types/models/DeleteMessageNotification';
18-
import { firstValueFrom, Subject, takeUntil } from 'rxjs';
18+
import { Subject, takeUntil, BehaviorSubject, firstValueFrom, distinctUntilKeyChanged } from 'rxjs';
1919
import { DisplayNameColours } from 'src/app/types/enums/DisplayNameColours';
2020
import { DeleteMessageCommand } from 'src/app/types/requests/DeleteMessageCommand';
2121
import ApiBaseService from 'src/app/services/api/apiBase.service';
2222
import { SendMessageResponse } from '../../types/responses/SendMessageResponse';
23+
import { ReplyStateSerivce } from 'src/app/services/states/replyState.service';
24+
import { Reply } from 'src/app/types/models/Reply';
2325

2426
@Component({
2527
selector: 'app-chats',
@@ -36,7 +38,8 @@ export class ChatsComponent implements OnInit, OnDestroy {
3638
private _router: Router,
3739
private _validationService: ValidationService,
3840
private _apiBaseService: ApiBaseService,
39-
public _modalWindowStateService: ModalWindowStateService
41+
public _modalWindowStateService: ModalWindowStateService,
42+
public _replyStateService: ReplyStateSerivce
4043
) {}
4144

4245
private connectionBuilder: signalR.HubConnectionBuilder = new signalR.HubConnectionBuilder();
@@ -72,12 +75,14 @@ export class ChatsComponent implements OnInit, OnDestroy {
7275
public messages: Message[] = [];
7376

7477
public messageAttachment: File | null = null;
78+
public messageAttachmentBlobUrl: string | ArrayBuffer | null = '';
7579
public messageText = '';
76-
public messageAttachmentUrl = '';
7780
public searchChatQuery = '';
7881
public searchMessagesQuery = '';
7982
public chatFilter = 'All chats';
8083

84+
public activeChatBehaviorSubject = new BehaviorSubject<Chat>(this.activeChat);
85+
8186
componentDestroyed$: Subject<boolean> = new Subject();
8287

8388
public get routingConstants(): typeof RoutingConstants {
@@ -89,6 +94,12 @@ export class ChatsComponent implements OnInit, OnDestroy {
8994
}
9095

9196
initializeView(): void {
97+
this.activeChatBehaviorSubject.pipe(distinctUntilKeyChanged('chatId')).subscribe(() => {
98+
this._replyStateService.setReplyNull();
99+
this.messageAttachment = null;
100+
this.messageAttachmentBlobUrl = null;
101+
});
102+
92103
const tokens = this._tokensService.getTokens();
93104

94105
if (!tokens) {
@@ -144,8 +155,31 @@ export class ChatsComponent implements OnInit, OnDestroy {
144155
.catch((err) => console.error(err.toString()));
145156
}
146157

147-
imageSelected(event: any) {
158+
onReplyClick(
159+
messageId: string,
160+
displayName: string,
161+
text: string,
162+
displayNameColour: DisplayNameColours
163+
) {
164+
const replyEntity = new Reply(messageId, displayName, text, displayNameColour);
165+
166+
this._replyStateService.setReply(replyEntity);
167+
this.scrollToEnd();
168+
}
169+
170+
async imageSelected(event: any) {
148171
this.messageAttachment = event.target.files[0];
172+
173+
const reader = new FileReader();
174+
reader.onload = () => {
175+
this.messageAttachmentBlobUrl = reader.result;
176+
};
177+
reader.readAsDataURL(event.target.files[0]);
178+
}
179+
180+
removeImageSelected() {
181+
this.messageAttachment = null;
182+
this.messageAttachmentBlobUrl = null;
149183
}
150184

151185
onOpenImageClick(imageLink: string): void {
@@ -275,8 +309,13 @@ export class ChatsComponent implements OnInit, OnDestroy {
275309
}
276310

277311
this.activeChatId = chatId;
278-
this.activeChat = this.chats.filter((x) => x.chatId === this.activeChatId)[0];
312+
const newActiveChat = this.chats.filter((x) => x.chatId === this.activeChatId)[0];
313+
this.activeChat = newActiveChat;
314+
315+
this.activeChatBehaviorSubject.next(newActiveChat);
316+
279317
this.getChatMessages(this.activeChatId);
318+
this.scrollToEnd();
280319
}
281320

282321
chatContainsMessages(chat: Chat): boolean {
@@ -426,6 +465,11 @@ export class ChatsComponent implements OnInit, OnDestroy {
426465
sendMessageFormData.append('messageText', newMessageText);
427466
sendMessageFormData.append('chatId', this.activeChatId);
428467
sendMessageFormData.append('messageId', messageId);
468+
sendMessageFormData.append(
469+
'inReplayToAuthor',
470+
this._replyStateService.reply?.displayName ?? ''
471+
);
472+
sendMessageFormData.append('inReplayToText', this._replyStateService.reply?.text ?? '');
429473

430474
if (this.messageAttachment) {
431475
sendMessageFormData.append('Attachment', this.messageAttachment);
@@ -440,13 +484,17 @@ export class ChatsComponent implements OnInit, OnDestroy {
440484
newMessageText,
441485
isoString,
442486
true,
443-
tokens.userProfilePictureUrl
487+
tokens.userProfilePictureUrl,
488+
this._replyStateService.reply?.displayName ?? null,
489+
this._replyStateService.reply?.text ?? null
444490
);
445491

446492
this.clearMessageInput();
447493

448494
this.messages.push(newMessage);
449495

496+
this._replyStateService.setReplyNull();
497+
450498
const sendMessage$ = this._messagesService.sendMessage(sendMessageFormData);
451499

452500
const response = await firstValueFrom<SendMessageResponse>(sendMessage$);
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Injectable } from '@angular/core';
2+
import { Reply } from './../../types/models/Reply';
3+
4+
5+
@Injectable({
6+
providedIn: 'root'
7+
})
8+
export class ReplyStateSerivce {
9+
public reply: Reply | null = null;
10+
11+
public setReply(replyEntity: Reply) {
12+
this.reply = replyEntity;
13+
}
14+
15+
public setReplyNull() {
16+
this.reply = null;
17+
}
18+
}

MangoAPI.Client/src/app/types/models/Message.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ export class Message {
2424
messageText: string,
2525
createdAt: string,
2626
self: boolean,
27-
messageAuthorPictureUrl: string
27+
messageAuthorPictureUrl: string,
28+
inReplayToAuthor: string | null,
29+
inReplayToText: string | null
2830
) {
2931
this.messageId = messageId;
3032
this.userId = userId;
@@ -35,5 +37,7 @@ export class Message {
3537
this.createdAt = createdAt;
3638
this.self = self;
3739
this.messageAuthorPictureUrl = messageAuthorPictureUrl;
40+
this.inReplayToAuthor = inReplayToAuthor ?? null;
41+
this.inReplayToText = inReplayToText ?? null;
3842
}
3943
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { DisplayNameColours } from "../enums/DisplayNameColours";
2+
3+
export class Reply {
4+
public messageId: string;
5+
public displayName: string;
6+
public text: string;
7+
public displayNameColour: DisplayNameColours;
8+
9+
constructor(messageId: string, displayName: string, text: string, displayNameColour: DisplayNameColours) {
10+
this.messageId = messageId;
11+
this.displayName = displayName;
12+
this.text = text;
13+
this.displayNameColour = displayNameColour;
14+
}
15+
}
Lines changed: 4 additions & 0 deletions
Loading
Lines changed: 2 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)