diff --git a/src/app/chat/chat-icons.ts b/src/app/chat/chat-icons.ts index 826620d5f6..a47be113b9 100644 --- a/src/app/chat/chat-icons.ts +++ b/src/app/chat/chat-icons.ts @@ -1,3 +1,5 @@ export const CHAT_ICONS = { - telegram: 'assets/img/chat/telegram-logo.svg' + telegram: 'assets/img/chat/telegram-logo.svg', + edit: './assets/img/chat/new-message.svg', + close: './assets/img/comments/cancel-comment-edit.png' }; diff --git a/src/app/chat/component/chat-page/chat-page.component.html b/src/app/chat/component/chat-page/chat-page.component.html index c3966ce8d9..eb11dc9aa7 100644 --- a/src/app/chat/component/chat-page/chat-page.component.html +++ b/src/app/chat/component/chat-page/chat-page.component.html @@ -31,7 +31,12 @@ - + + diff --git a/src/app/chat/component/chat-page/chat-page.component.scss b/src/app/chat/component/chat-page/chat-page.component.scss index 63dc712f6c..8b2a857354 100644 --- a/src/app/chat/component/chat-page/chat-page.component.scss +++ b/src/app/chat/component/chat-page/chat-page.component.scss @@ -145,6 +145,7 @@ } .messages { + position: relative; flex: 1; overflow-y: auto; padding-right: 0.5rem; @@ -195,6 +196,7 @@ } .message-input-container { + position: relative; display: flex; flex-direction: column; align-items: center; @@ -260,6 +262,64 @@ } } +.message-icons { + width: 14px; + margin: 0 0 3px auto; + display: flex; + + .icon { + max-width: 11px; + } +} + +.edit-text-container { + position: absolute; + bottom: 6rem; + width: 88%; + padding: 7px 10px; + border-radius: 7px; + margin-left: 5px; + display: flex; + align-self: flex-start; + background-color: var(--primary-white); + color: var(--secondary-dark-grey); + border: 1px solid var(--after-primary-light-grey); + box-shadow: -2px -1px 5px #0000001a; + + p { + margin: 0; + font-size: 14px; + + &:first-of-type { + color: var(--tertiary-light-green); + } + } + + .icon { + width: 16px; + margin: 0 15px; + } + + .close { + margin-left: auto; + width: 10px; + height: 10px; + } +} + +.edit-status { + margin: 0 15px; + font-size: 10px; + + .edited-icon { + width: 13px; + } +} + +.menu-item { + font-size: 14px; +} + .file-attach { margin-top: 6px; display: flex; diff --git a/src/app/chat/component/chat-page/chat-page.component.ts b/src/app/chat/component/chat-page/chat-page.component.ts index f0c821171d..d91ecb25d2 100644 --- a/src/app/chat/component/chat-page/chat-page.component.ts +++ b/src/app/chat/component/chat-page/chat-page.component.ts @@ -31,7 +31,10 @@ export class ChatComponent implements OnInit, AfterViewInit, OnDestroy { @ViewChild('pagingAnchor') pagingAnchor!: ElementRef; private io?: IntersectionObserver; private readonly destroy$ = new Subject(); - constructor(public facade: ChatFacade, public route: ActivatedRoute) {} + constructor( + public facade: ChatFacade, + public route: ActivatedRoute + ) {} ngOnInit(): void { this.facade.init(Number(this.route.snapshot.queryParams['chatId'])); @@ -73,6 +76,14 @@ export class ChatComponent implements OnInit, AfterViewInit, OnDestroy { this.io.observe(this.pagingAnchor.nativeElement); } + messageController(text: string, file?: File) { + if (!this.facade.selectedMessage) { + this.facade.sendMessage(text, file); + } else { + this.facade.editMessage(text); + } + } + ngOnDestroy(): void { this.io?.disconnect(); this.destroy$.next(); diff --git a/src/app/chat/data/chat-api.service.ts b/src/app/chat/data/chat-api.service.ts index 423cedfdf7..3aff49b350 100644 --- a/src/app/chat/data/chat-api.service.ts +++ b/src/app/chat/data/chat-api.service.ts @@ -56,6 +56,16 @@ export class ChatApiService { return this.http.post(url, form, { headers, responseType: 'text' as 'json' }); } + editMessage(chatInternalId: number, messageId: number, newText: string) { + const headers = this.authHeaders(); + if (!headers) { + return new Observable((o) => o.complete()); + } + const url = `${this.baseUrl}/message/edit`; + const data = new Blob([JSON.stringify({ chatId: chatInternalId, messageId: messageId, newText })], { type: 'application/json' }); + return this.http.put(url, data, { headers, responseType: 'text' as 'json' }); + } + getLastOrder(chatInternalId: number) { const headers = this.authHeaders(); if (!headers) { diff --git a/src/app/chat/facade/chat.facade.ts b/src/app/chat/facade/chat.facade.ts index ca321e1218..090d037aea 100644 --- a/src/app/chat/facade/chat.facade.ts +++ b/src/app/chat/facade/chat.facade.ts @@ -14,6 +14,8 @@ export class ChatFacade { readonly selectedChat = signal(null); readonly selectedImageUrl = signal(null); + readonly selectedMessage = signal(null); + readonly clientInfoVisible = signal(false); readonly clientInfoData = signal(null); @@ -158,7 +160,11 @@ export class ChatFacade { this.location.replaceState(newPath); } - selectChatById(chatInternalId: number) { + selectMessage(message?: ChatMessageView) { + this.selectedMessage.set(message); + } + + selectChatById(chatInternalId: number) { const chat = this.chats().find((c) => c.chatInternalId === chatInternalId); if (chat) { this.selectChat(chat); @@ -332,6 +338,25 @@ export class ChatFacade { }); } + editMessage(newText: string) { + const sel = this.selectedChat(); + const mes = this.selectedMessage(); + if (!sel || !newText.trim() || !mes) { + return; + } + this.api.editMessage(sel.chatInternalId, mes.id, newText.trim()).subscribe({ + next: () => { + const messageIndex = sel.messages.findIndex((m) => m.id === mes.id); + if (messageIndex > -1) { + sel.messages[messageIndex].text = newText; + } + this.selectedChat.set({ ...sel }); + this.selectMessage(null); + }, + error: (e) => console.error('Failed to edit the message:', e) + }); + } + toggleClientInfo() { this.clientInfoVisible.update((v) => !v); const visible = this.clientInfoVisible(); diff --git a/src/app/chat/ui/message-input/message-input.component.html b/src/app/chat/ui/message-input/message-input.component.html index 6ec7b67635..cd6b49251a 100644 --- a/src/app/chat/ui/message-input/message-input.component.html +++ b/src/app/chat/ui/message-input/message-input.component.html @@ -1,7 +1,16 @@
+
+ edit +
+

{{ 'chat.edit-message' | translate }}

+

{{ editText }}

+
+ close +