Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export class CommentsContainerComponent implements OnInit, DoCheck {

updateElementsListReply(comment: AddedCommentDTO): void {
const reply: CommentsDTO = {
currentUserDisliked: false, dislikes: 0,
...comment,
currentUserLiked: false,
likes: 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,10 @@ export class CommentsListComponent {
return element.status === 'EDITED';
}

private updateLikeDislikeCount(commentId: number, type: ReactionType, isAdd: boolean): void {
this.elementsList = this.elementsList.map((comment) => {
if (comment?.id === commentId) {
comment[type] = Math.max(0, comment[type] + (isAdd ? 1 : -1));
}
return comment;
});
private updateCommentData(updated: CommentsDTO): void {
this.elementsList = this.elementsList.map((comment) =>
comment.id === updated.id ? { ...comment, ...updated } : comment
);
}

private showErrorMessage(message: string): void {
Expand All @@ -102,27 +99,16 @@ export class CommentsListComponent {
}
this.isProcessing.add(commentId);

const comment = this.elementsList.find((c) => c.id === commentId);
if (!comment) {
return;
}

const isLiking = !comment.isLiked;
this.commentsService
.postLike(commentId)
.pipe(
take(1),
finalize(() => this.isProcessing.delete(commentId))
)
.subscribe(
() => {
comment.isLiked = isLiking;
comment.isDisliked = false;
comment.likes += isLiking ? 1 : -1;
this.snackBar.open(isLiking ? 'Comment liked' : 'Like removed', 'Close', { duration: 3000 });
},
() => this.showErrorMessage('Failed to update like. Please try again.')
);
this.commentsService.postLikeV2(commentId).pipe(
take(1),
finalize(() => this.isProcessing.delete(commentId))
).subscribe({
next: (updatedComment) => {
this.updateCommentData(updatedComment);
this.snackBar.open(updatedComment.currentUserLiked ? 'Comment liked' : 'Like removed', 'Close', { duration: 3000 });
},
error: () => this.showErrorMessage('Failed to update like. Please try again.')
});
}

dislikeComment(commentId: number): void {
Expand All @@ -131,26 +117,16 @@ export class CommentsListComponent {
}
this.isProcessing.add(commentId);

const comment = this.elementsList.find((c) => c.id === commentId);
if (!comment) {
return;
}

const isDisliking = !comment.isDisliked;
this.commentsService
.postDislike(commentId)
.pipe(
take(1),
finalize(() => this.isProcessing.delete(commentId))
)
.subscribe(
() => {
comment.isDisliked = isDisliking;
comment.isLiked = false;
this.snackBar.open(isDisliking ? 'Comment disliked' : 'Dislike removed', 'Close', { duration: 3000 });
},
() => this.showErrorMessage('Failed to update dislike. Please try again.')
);
this.commentsService.postDislikeV2(commentId).pipe(
take(1),
finalize(() => this.isProcessing.delete(commentId))
).subscribe({
next: (updatedComment) => {
this.updateCommentData(updatedComment);
this.snackBar.open(updatedComment.currentUserDisliked ? 'Comment disliked' : 'Dislike removed', 'Close', { duration: 3000 });
},
error: () => this.showErrorMessage('Failed to update dislike. Please try again.')
});
}

saveEditedComment(element: CommentsDTO): void {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div class="d-flex main-wrapper">
<button class="cta-btn like" (click)="pressLike()">
<button class="cta-btn like">
<img [src]="commentsImages.like" class="btn-img" alt="like" aria-hidden="true" #like />
<span class="d-none d-sm-block btn-text" *ngIf="!likeState && !error; else liked">
{{ 'homepage.eco-news.comment.btn.like' | translate }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,6 @@ export class LikeCommentComponent implements OnInit {
this.localStorageService.userIdBehaviourSubject.subscribe((id) => (this.userId = id));
}

pressLike(): void {
this.commentsService.postLike(this.comment.id).subscribe(() => {
this.getUserId();
this.socketService.send(this.socketService.connection.greenCity, this.socketMessageToSend, {
id: this.comment.id,
amountLikes: this.likeState ? 0 : 1,
userId: this.userId
});
});
}

changeLkeBtn(msg: SocketAmountLikes): void {
if (msg.liked) {
Expand Down
3 changes: 2 additions & 1 deletion src/app/greencity/modules/comments/mocks/comments-mock.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { CommentsDTO } from '../models/comments-model';

export const MOCK_COMMENTS_DTO: CommentsDTO = {
isDisliked: false, isLiked: false,
isDisliked: false,
isLiked: false,
author: {
id: 0,
name: 'fake_author',
Expand Down
3 changes: 3 additions & 0 deletions src/app/greencity/modules/comments/models/comments-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ export interface AuthorDTO {
export interface CommentsDTO {
author: AuthorDTO;
currentUserLiked: boolean;
currentUserDisliked: boolean;
id: number;
likes: number;
dislikes: number;
isLiked: boolean;
isDisliked: boolean;
modifiedDate: string;
Expand All @@ -28,6 +30,7 @@ export interface CommentsDTO {
additionalImages?: string[];
}


export interface AddedCommentDTO {
author: AuthorDTO;
id: number;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { AddedCommentDTO, CommentFormData, CommentsModel } from '../models/comments-model';
import { AddedCommentDTO, CommentFormData, CommentsDTO, CommentsModel } from '../models/comments-model';

@Injectable({
providedIn: 'root'
Expand All @@ -20,9 +20,9 @@ export abstract class CommentsService {

abstract getRepliesAmount(parentCommentId: number): Observable<number>;

abstract postLike(parentCommentId: number): Observable<void>;
abstract postLikeV2(parentCommentId: number): Observable<CommentsDTO>;

abstract postDislike(parentCommentId: number): Observable<void>;
abstract postDislikeV2(parentCommentId: number): Observable<CommentsDTO>;

abstract editComment(parentCommentId: number, text: string): Observable<void>;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { catchError, Observable, throwError } from 'rxjs';
import { map } from 'rxjs/operators';
import { environment } from '@environment/environment';
import { CommentsService } from '../../comments/services/comments.service';
import { AddedCommentDTO, CommentFormData, CommentsModel } from '../../comments/models/comments-model';
import { AddedCommentDTO, CommentFormData, CommentsDTO, CommentsModel } from '../../comments/models/comments-model';
import { CommentService } from '@shared/service/comment/comment.service';

@Injectable({
Expand Down Expand Up @@ -60,8 +60,12 @@ export class EcoNewsCommentsService implements CommentsService {
return this.http.get<number>(`${this.backEnd}eco-news/comments/${parentCommentId}/replies/active/count`);
}

postLike(parentCommentId: number): Observable<void> {
return this.http.post<void>(`${this.backEnd}eco-news/comments/like?commentId=${parentCommentId}`, {});
postLikeV2(parentCommentId: number): Observable<CommentsDTO> {
return this.http.post<CommentsDTO>(`${this.backEnd}eco-news/comments/like?commentId=${parentCommentId}`, {});
}

postDislikeV2(parentCommentId: number): Observable<CommentsDTO> {
return this.http.post<CommentsDTO>(`${this.backEnd}eco-news/comments/dislike?commentId=${parentCommentId}`, {});
}

editComment(parentCommentId: number, text: string): Observable<void> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { CreateEcoEventAction, EditEcoEventAction } from 'src/app/store/actions/
import { EventStoreService } from '../../services/event-store.service';
import { EventsService } from '../../services/events.service';
import { EventDetailsComponent } from './event-details.component';
import { EventDto as EventDTO } from '../../models/events.interface';
import { EventDto as EventDTO } from '../../models/events.interface';
import { MatSnackBarService } from '@global-service/mat-snack-bar/mat-snack-bar.service';

export function mockPipe(options: Pipe): Pipe {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ import { EventAttender, EventDto, EventForm, PlaceOnline } from '../../models/ev
import { EventStoreService } from '../../services/event-store.service';
import { MatSnackBarService } from '@global-service/mat-snack-bar/mat-snack-bar.service';



@Component({
selector: 'app-event-details',
templateUrl: './event-details.component.html',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export interface LikeResponse {
id: number;
likes: number;
dislikes: number;
isLiked: boolean;
isDisliked: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,8 @@
<app-events-list-item
[isGalleryView]="isGalleryView"
[event]="eventItem"
(likeStatusChange)="likeEvent($event)"
(dislikeStatusChange)="dislikeEvent($event)"
(likeStatusChange)="onLikeStatusChange($event)"
(dislikeStatusChange)="onDislikeStatusChange($event)"
[userId]="userId"
[isUserAssignList]="false"
></app-events-list-item>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { Addresses, EventListResponse, FilterItem } from '../../models/events.interface';
import { Addresses, EventDto, EventListResponse, FilterItem } from '../../models/events.interface';
import { UserOwnAuthService } from 'src/app/shared/services/auth/user-own-auth.service';
import { Observable, ReplaySubject, Subscription, take } from 'rxjs';
import { LocalStorageService } from 'src/app/shared/services/localstorage/local-storage.service';
Expand All @@ -18,6 +18,7 @@ import { MatOption } from '@angular/material/core';
import { HttpParams } from '@angular/common/http';
import { EventStoreService } from '../../services/event-store.service';
import { initializeSavedState } from 'src/app/greencity/shared/components/saved-tabs/saved-section-const';
import { LikeResponse } from '../../services/LikeResponse';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Incorrect import path for LikeResponse interface.

The import statement is using a path to the services directory, but the file we're reviewing shows this interface is located in the components directory.

-import { LikeResponse } from '../../services/LikeResponse';
+import { LikeResponse } from './LikeResponse';
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import { LikeResponse } from '../../services/LikeResponse';
import { LikeResponse } from './LikeResponse';


@Component({
selector: 'app-events-list',
Expand Down Expand Up @@ -111,55 +112,30 @@ export class EventsListComponent implements OnInit, OnDestroy {
value.trim() !== '' ? this.searchEventsByTitle() : this.getEvents();
});
}
private refreshEventInList(updatedEvent: EventListResponse): void {
const index = this.eventsList.findIndex((e) => e.id === updatedEvent.id);

private updateEventFromServer(eventId: number, updatedEvent: EventDto): void {
const index = this.eventsList.findIndex((e) => e.id === eventId);
if (index !== -1) {
this.eventsList[index] = updatedEvent;
this.eventsList[index] = {
...this.eventsList[index],
likes: updatedEvent.likes,
dislikes: updatedEvent.dislikes,
isLiked: updatedEvent.isLiked,
isDisliked: updatedEvent.isDisliked
};
}
}

likeEvent(event: EventListResponse): void {
this.eventService.likeEvent(event.id).subscribe(() => {
this.updateEventReaction(event, 'like');
this.eventService.getEventById(event.id).subscribe((updatedEvent) => {
//@ts-ignore
this.refreshEventInList(updatedEvent);
});
});
}

dislikeEvent(event: EventListResponse): void {
this.eventService.dislikeEvent(event.id).subscribe(
() => {
this.updateEventReaction(event, 'dislike');
},
(error) => {
console.error('Dislike API request failed:', error);
}
);
onLikeStatusChange(updatedEvent: EventListResponse): void {
const index = this.eventsList.findIndex(e => e.id === updatedEvent.id);
if (index !== -1) {
this.eventsList[index] = { ...this.eventsList[index], ...updatedEvent };
}
}

private updateEventReaction(event: EventListResponse, reactionType: 'like' | 'dislike'): void {
const i = this.eventsList.findIndex((e) => e.id === event.id);
if (i !== -1) {
const current = this.eventsList[i];
if (reactionType === 'like') {
if (!current.isLiked) {
current.likes++;
current.isLiked = true;
current.isDisliked = false;
}
} else {
if (current.isDisliked) {
current.isDisliked = false;
} else {
if (current.isLiked && current.likes > 0) {
current.likes--;
current.isLiked = false;
}
current.isDisliked = true;
}
}
onDislikeStatusChange(updatedEvent: EventListResponse): void {
const index = this.eventsList.findIndex(e => e.id === updatedEvent.id);
if (index !== -1) {
this.eventsList[index] = { ...this.eventsList[index], ...updatedEvent };
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/app/greencity/modules/events/models/events.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,15 +155,15 @@ export interface EventResponse {
isRelevant: boolean;
likes: number;
dislikes: number;
isLiked: boolean;
isDisliked: boolean;
countComments: number;
eventRate: number;
open: boolean;
isSubscribed: boolean;
isFavorite: boolean;
isOrganizedByFriend: boolean;
currentUserGrade?: number | null;
isLiked: boolean;
isDisliked: boolean;
}

export type EventListResponse = Omit<EventResponse, 'additionalImages' | 'description'>;
Expand Down
6 changes: 4 additions & 2 deletions src/app/greencity/modules/events/services/LikeResponse.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export interface LikeResponse {
id: number;
liked: boolean;
likes: number;
dislikes: number;
isLiked: boolean;
isDisliked: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { environment } from '@environment/environment';
import { CommentsService } from '../../comments/services/comments.service';
import { AddedCommentDTO, CommentFormData, CommentsModel } from '../../comments/models/comments-model';
import { AddedCommentDTO, CommentFormData, CommentsDTO, CommentsModel } from '../../comments/models/comments-model';
import { CommentService } from '@shared/service/comment/comment.service';

@Injectable({
Expand Down Expand Up @@ -51,13 +51,15 @@ export class EventsCommentsService implements CommentsService {
return this.http.get<number>(`${this.backEnd}events/comments/${parentCommentId}/replies/count`);
}

postLike(parentCommentId: number): Observable<void> {
return this.http.post<void>(`${this.backEnd}events/comments/like/${parentCommentId}`, {});
postLikeV2(commentId: number) {
return this.http.post<CommentsDTO>(`${this.backEnd}events/comments/likeV2/${commentId}`, {});
}
postDislike(commentId: number): Observable<void> {
return this.http.post<void>(`${this.backEnd}events/comments/dislike/${commentId}`, {});

postDislikeV2(commentId: number) {
return this.http.post<CommentsDTO>(`${this.backEnd}events/comments/dislikeV2/${commentId}`, {});
}


editComment(parentCommentId: number, text: string): Observable<void> {
return this.http.patch<void>(`${this.backEnd}events/comments/${parentCommentId}`, text);
}
Expand Down
Loading
Loading