-
Notifications
You must be signed in to change notification settings - Fork 48
Feature/8044/display news likes and details for admins on eco news page #3563
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature/8044/display news likes and details for admins on eco news page #3563
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
🔭 Outside diff range comments (1)
src/app/main/component/events/services/events.service.ts (1)
267-269
: 🛠️ Refactor suggestionConsider removing redundant method.
The
postToggleLike
method appears to be redundant with the newlikeEvent
method. Consider removing it or refactoring to use one consistent implementation.
🧹 Nitpick comments (7)
src/app/main/component/events/models/events.interface.ts (1)
172-173
: Consider making thedislikes
property optional for backward compatibility.The
dislikes
property should be marked as optional to maintain backward compatibility with existing event responses that may not include this field.- dislikes: number; + dislikes?: number;src/app/main/component/events/services/events.service.ts (1)
46-48
: Define a specific return type for the API response.Using
Observable<any>
reduces type safety. Consider defining an interface for the API response.- likeEvent(eventId: number): Observable<any> { + interface LikeResponse { + success: boolean; + message?: string; + } + likeEvent(eventId: number): Observable<LikeResponse> {src/app/main/component/shared/components/events-list-item/events-list-item.component.ts (1)
383-383
: Standardize method naming convention.The methods use inconsistent naming:
likePost
vsdislikePost
. Consider renaming tolikeEvent
anddislikeEvent
to match the service method names.- likePost() { + likeEvent() { - dislikePost() { + dislikeEvent() {Also applies to: 396-396
src/app/main/component/events/components/events-list/events-list.component.ts (2)
142-164
: Simplify reaction update logic.The
updateEventReaction
method has complex nested conditions that could be simplified for better readability.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; - } - } + switch (reactionType) { + case 'like': + if (!current.isLiked) { + current.likes++; + current.isLiked = true; + current.isDisliked = false; + } + break; + case 'dislike': + if (current.isLiked && current.likes > 0) { + current.likes--; + current.isLiked = false; + } + current.isDisliked = !current.isDisliked; + break; + } } }
114-119
: Handle event not found case.The
refreshEventInList
method should handle the case when the event is not found in the list.private refreshEventInList(updatedEvent: EventListResponse): void { const index = this.eventsList.findIndex((e) => e.id === updatedEvent.id); - if (index !== -1) { - this.eventsList[index] = updatedEvent; - } + if (index === -1) { + console.warn(`Event with ID ${updatedEvent.id} not found in the list`); + return; + } + this.eventsList[index] = updatedEvent; }src/app/main/component/shared/components/events-list-item/events-list-item.component.scss (1)
18-20
: Optimize icon rotation animation performance.The rotation transform could benefit from hardware acceleration and smooth transitions.
Apply this diff to enhance the animation:
.rotate-icon { - transform: rotate(180deg); + transform: rotate(180deg); + transform-style: preserve-3d; + backface-visibility: hidden; + transition: transform 0.2s ease; + will-change: transform; }src/app/main/component/comments/components/comments-list/comments-list.component.scss (1)
163-173
: Add interactive states and fix linting.
- Add empty line before nested rule
- Add hover and focus states for better user experience
.comment-likes { display: flex; gap: 10px; align-items: center; + + button { + padding: 8px; + border: none; + background: none; + cursor: pointer; + + &:hover { + background-color: var(--quaternary-light-grey); + border-radius: 50%; + } + + &:focus-visible { + outline: 2px solid var(--primary-color); + border-radius: 50%; + } + + &.active { + color: var(--primary-color); + } + } + .like-amount { font-family: var(--primary-font); font-size: 12px;🧰 Tools
🪛 GitHub Actions: CI/CD GreenCityClient
[error] 167-167: Expected empty line before rule
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (10)
src/app/main/component/comments/components/comments-list/comments-list.component.html
(1 hunks)src/app/main/component/comments/components/comments-list/comments-list.component.scss
(2 hunks)src/app/main/component/comments/components/comments-list/comments-list.component.ts
(2 hunks)src/app/main/component/events/components/events-list/events-list.component.html
(1 hunks)src/app/main/component/events/components/events-list/events-list.component.ts
(2 hunks)src/app/main/component/events/models/events.interface.ts
(2 hunks)src/app/main/component/events/services/events.service.ts
(4 hunks)src/app/main/component/shared/components/events-list-item/events-list-item.component.html
(1 hunks)src/app/main/component/shared/components/events-list-item/events-list-item.component.scss
(1 hunks)src/app/main/component/shared/components/events-list-item/events-list-item.component.ts
(2 hunks)
🧰 Additional context used
🪛 GitHub Actions: CI/CD GreenCityClient
src/app/main/component/comments/components/comments-list/comments-list.component.scss
[error] 14-14: Expected empty line before rule
[error] 17-17: Expected empty line before rule
[error] 167-167: Expected empty line before rule
🔇 Additional comments (1)
src/app/main/component/events/components/events-list/events-list.component.html (1)
145-146
: LGTM!The event bindings for like/dislike status changes are properly implemented.
src/app/main/component/shared/components/events-list-item/events-list-item.component.ts
Outdated
Show resolved
Hide resolved
src/app/main/component/shared/components/events-list-item/events-list-item.component.ts
Outdated
Show resolved
Hide resolved
src/app/main/component/events/components/events-list/events-list.component.ts
Outdated
Show resolved
Hide resolved
src/app/main/component/shared/components/events-list-item/events-list-item.component.html
Outdated
Show resolved
Hide resolved
src/app/main/component/comments/components/comments-list/comments-list.component.ts
Outdated
Show resolved
Hide resolved
src/app/main/component/comments/components/comments-list/comments-list.component.ts
Outdated
Show resolved
Hide resolved
src/app/main/component/comments/components/comments-list/comments-list.component.html
Outdated
Show resolved
Hide resolved
src/app/main/component/comments/components/comments-list/comments-list.component.scss
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (2)
src/app/main/component/events/services/events.service.ts (2)
50-60
: 🛠️ Refactor suggestionRemove debug logging and standardize error handling.
- Remove console.log statements from production code.
- Standardize error handling to match the
likeEvent
method.Apply this diff:
- dislikeEvent(eventId: number): Observable<any> { - return this.http.post<any>(`${this.backEnd}events/${eventId}/dislike`, {}).pipe( - tap((response: any) => { - console.log(`DISLIKE request successful. Response:`, response); - }), - catchError((error) => { - console.error(`DISLIKE request failed for event ID: ${eventId}`, error); - return throwError(error); - }) - ); + dislikeEvent(eventId: number): Observable<LikeResponse> { + return this.http.post<LikeResponse>(`${this.backEnd}events/${eventId}/dislike`, {}).pipe( + catchError((error) => throwError(error)) + );
241-241
: 🛠️ Refactor suggestionRemove debug logging statement.
Remove the console.log statement from production code.
Apply this diff:
- console.log(requestParams);
eb2f31b
to
bdd32dc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
♻️ Duplicate comments (2)
src/app/main/component/events/services/events.service.ts (2)
58-60
: 🛠️ Refactor suggestionImprove type safety and standardize error handling.
- The response type
any
should be replaced withLikeResponse
.- Error handling should be consistent with other methods.
Apply this diff:
- dislikeEvent(eventId: number): Observable<any> { - return this.http.post<any>(`${this.backEnd}events/${eventId}/dislike`, {}).pipe(catchError((error) => throwError(error))); + dislikeEvent(eventId: number): Observable<LikeResponse> { + return this.http.post<LikeResponse>(`${this.backEnd}events/${eventId}/dislike`, {}).pipe( + catchError((error) => throwError(() => error)) + ); }
49-56
: 🛠️ Refactor suggestionRemove duplicate functionality and improve error handling.
- This method duplicates the functionality of the existing
postToggleLike
method at line 265.- Error handling could be simplified by removing the console.error statement.
Apply this diff:
- likeEvent(eventId: number): Observable<LikeResponse> { - return this.http.post<LikeResponse>(`${this.backEnd}events/${eventId}/like`, {}).pipe( - catchError((error) => { - console.error('Error liking event:', error); - return throwError(() => error); - }) - ); - }And update the
postToggleLike
method to use theLikeResponse
interface:- postToggleLike(eventId: number): Observable<any> { + postToggleLike(eventId: number): Observable<LikeResponse> { - return this.http.post(`${this.backEnd}events/${eventId}/like`, {}); + return this.http.post<LikeResponse>(`${this.backEnd}events/${eventId}/like`, {}).pipe( + catchError((error) => throwError(() => error)) + ); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
src/app/main/component/comments/components/comments-list/comments-list.component.ts
(4 hunks)src/app/main/component/comments/services/comments.service.ts
(1 hunks)src/app/main/component/events/services/events.service.ts
(4 hunks)src/app/main/component/shared/components/events-list-item/events-list-item.component.html
(1 hunks)src/app/main/component/shared/components/events-list-item/events-list-item.component.ts
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- src/app/main/component/shared/components/events-list-item/events-list-item.component.html
🔇 Additional comments (11)
src/app/main/component/comments/components/comments-list/comments-list.component.ts (8)
9-10
: Imports look good
No issues found with these added imports; they align well with the new functionality.
12-15
: Enum usage is appropriate
Defining an enum for reaction types helps maintain clarity and type safety.
56-57
: Good approach to manage concurrent requests
Introducing separate booleans for like and dislike actions effectively prevents overlapping requests.
62-63
: Constructor injections are fine
Injecting MatDialog and MatSnackBar aligns with Angular best practices for modular services.
85-92
: Bulk update logic is concise
Using Math.max to prevent negative values is a good safeguard, and the mapping approach effectively updates the targeted comment.
94-120
: Consider toggling reactions
This method only increments like counts, potentially allowing multiple likes from the same user. A toggle mechanism (adding or removing a like) could help avoid inconsistent states, as previously suggested.
122-148
: Same toggle suggestion applies here
Just like the like flow, consider a toggle approach to avoid inflating dislike counts if a user repeatedly dislikes the same comment.
204-207
: Verify toggling logic
This assignment togglesisAdd
based on the currentrepliedComment
. Verify that the first-time toggle and subsequent toggles flow as intended, especially ifrepliedComment
starts as null.src/app/main/component/comments/services/comments.service.ts (1)
25-26
: New method aligns with existing pattern
IntroducingpostDislike
alongsidepostLike
maintains symmetry and clarity in the service.src/app/main/component/events/services/events.service.ts (1)
22-25
: LGTM!The interface is well-defined and properly types the response from the like/dislike endpoints.
src/app/main/component/shared/components/events-list-item/events-list-item.component.ts (1)
51-52
: LGTM!The event emitters are well-defined and properly typed to communicate like/dislike status changes to the parent component.
src/app/main/component/shared/components/events-list-item/events-list-item.component.ts
Outdated
Show resolved
Hide resolved
src/app/main/component/shared/components/events-list-item/events-list-item.component.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🔭 Outside diff range comments (1)
src/app/main/component/eco-news/services/eco-news-comments.service.ts (1)
63-65
: 🛠️ Refactor suggestionAdd error handling to postLike method for consistency.
The new
postDislike
method includes proper error handling, but it's missing in thepostLike
method. Let's maintain consistency across similar operations.Apply this diff to add error handling:
postLike(parentCommentId: number): Observable<void> { - return this.http.post<void>(`${this.backEnd}eco-news/comments/like?commentId=${parentCommentId}`, {}); + return this.http.post<void>(`${this.backEnd}eco-news/comments/like?commentId=${parentCommentId}`, {}).pipe( + catchError((error) => { + console.error('Failed to post like:', error); + return throwError(() => error); + }) + ); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/app/main/component/eco-news/services/eco-news-comments.service.ts
(2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build (18.x)
🔇 Additional comments (2)
src/app/main/component/eco-news/services/eco-news-comments.service.ts (2)
3-3
: LGTM! Proper error handling imports added.The new imports for error handling operators are correctly added and well-organized with existing rxjs imports.
25-32
:✅ Verification successful
Verify URL format usage across the codebase.
Let's ensure the URL format change won't impact other parts of the application.
🏁 Script executed:
#!/bin/bash # Search for similar URL patterns in the codebase echo "Searching for similar comment action endpoints..." rg -l "comments/.*like" --type ts echo "Searching for specific dislike endpoint usage..." rg -l "comments/.*/dislike" --type tsLength of output: 1135
Verification Complete: URL Format is Localized
- The search confirms that the
/dislike
endpoint is used only insrc/app/main/component/eco-news/services/eco-news-comments.service.ts
.- Similar endpoints using a
/like
pattern appear throughout the codebase and follow a consistent format.- There’s no evidence that the URL change will impact other parts of the application.
You can proceed with this change.
src/app/main/component/eco-news/services/eco-news-comments.service.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/app/main/component/events/services/events-comments.service.ts (1)
57-59
: LGTM! The implementation follows established patterns.The new
postDislike
method is well-implemented and maintains consistency with the existingpostLike
method. The implementation follows Angular's service patterns and properly handles HTTP requests.Consider adding error handling to both
postLike
andpostDislike
methods to provide better feedback to the UI layer. For example:postDislike(commentId: number): Observable<void> { - return this.http.post<void>(`${this.backEnd}events/comments/dislike/${commentId}`, {}); + return this.http.post<void>(`${this.backEnd}events/comments/dislike/${commentId}`, {}).pipe( + catchError((error) => { + console.error('Error disliking comment:', error); + throw error; + }) + ); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/app/main/component/events/services/events-comments.service.ts
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build (18.x)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (3)
src/assets/mocks/events/mock-events.ts (2)
243-243
: Remove unnecessary inline comment.The comment "// Added this property" is redundant and inconsistent with the rest of the file's style.
- dislikes: 2, // Added this property + dislikes: 2,
183-183
: Consider adding more diverse test cases.While the current mock data provides basic test cases for the dislikes feature, consider adding edge cases such as:
- Zero dislikes
- Very large numbers
- Cases where dislikes > likes
Also applies to: 243-243, 296-296, 358-358, 515-515
src/app/main/service/habit-comments/habit-comments.service.ts (1)
34-36
: Consider adding error handling and type safety.To improve robustness and maintainability:
- Add retry logic for network failures
- Add rate limiting to prevent spam
- Define an interface for the response type
Example implementation:
interface DislikeResponse { success: boolean; message?: string; } postDislike(parentCommentId: number): Observable<DislikeResponse> { return this.http .post<DislikeResponse>( `${this.backEnd}habits/comments/dislike?commentId=${parentCommentId}`, {} ) .pipe( retry(3), throttleTime(1000) ); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/app/main/service/habit-comments/habit-comments.service.ts
(1 hunks)src/assets/mocks/events/mock-events.ts
(6 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build (18.x)
🔇 Additional comments (2)
src/assets/mocks/events/mock-events.ts (1)
183-183
: LGTM! Consistent implementation of dislikes property.The
dislikes
property has been consistently added across all mock event objects, providing a good range of test values.Also applies to: 243-243, 296-296, 358-358, 515-515
src/app/main/service/habit-comments/habit-comments.service.ts (1)
34-36
: LGTM! Implementation follows existing patterns.The implementation is consistent with the existing
postLike
method and follows the service's established patterns.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
src/app/main/service/localstorage/local-storage.service.spec.ts (2)
13-59
: LGTM! Consider adding test cases for social interaction metrics.The mock event object has been properly updated to include likes, dislikes, and comment counts, which aligns with the PR objectives. However, since these are new fields being added, it would be beneficial to add specific test cases that verify the handling of these social interaction metrics.
Consider adding test cases like:
it('should handle event social metrics correctly', () => { const eventWithMetrics = { ...mockEvent }; service.setEventForEdit('testKey', eventWithMetrics); const savedEvent = JSON.parse(localStorage.getItem('testKey')); expect(savedEvent.likes).toBe(5); expect(savedEvent.dislikes).toBe(2); expect(savedEvent.countComments).toBe(7); });
613-617
: Enhance test coverage for event storage.While the test verifies basic storage functionality, it could be improved to ensure type safety and deep object equality.
Consider enhancing the test:
it('should correctly store and retrieve the event with all properties', () => { const key = 'testKey'; service.setEventForEdit(key, mockEvent); // Get and parse the stored event const storedEvent: EventResponse = JSON.parse(localStorage.getItem(key)); // Verify type safety and deep equality expect(storedEvent).toBeTruthy(); expect(storedEvent.likes).toBe(mockEvent.likes); expect(storedEvent.dislikes).toBe(mockEvent.dislikes); expect(storedEvent.countComments).toBe(mockEvent.countComments); expect(storedEvent.tags).toEqual(mockEvent.tags); expect(storedEvent.dates[0].coordinates).toEqual(mockEvent.dates[0].coordinates); });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/app/main/service/localstorage/local-storage.service.spec.ts
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build (18.x)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/app/main/component/comments/components/comments-list/comments-list.component.spec.ts (1)
14-16
: LGTM! Consider organizing imports.The new imports and module setup are comprehensive and align well with the component's functionality.
Consider organizing imports by category (Angular core, Material, shared components, models) for better maintainability:
- import { WarningPopUpComponent } from '@shared/components'; - import { AddedCommentDTO } from '../../models/comments-model'; - import { MatSnackBarModule } from '@angular/material/snack-bar'; + // Angular Material + import { MatSnackBarModule } from '@angular/material/snack-bar'; + + // Shared Components + import { WarningPopUpComponent } from '@shared/components'; + + // Models + import { AddedCommentDTO } from '../../models/comments-model';Also applies to: 77-84
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/app/main/component/comments/components/comments-list/comments-list.component.spec.ts
(4 hunks)
🔇 Additional comments (4)
src/app/main/component/comments/components/comments-list/comments-list.component.spec.ts (4)
46-56
: LGTM! Clean mock implementations.The mock implementations are concise and well-structured, using arrow functions for better readability.
108-109
: Consider maintaining language consistency in test descriptions.The test descriptions are in Ukrainian while the code and variables are in English. This mixed language approach might affect maintainability and collaboration.
Would you like to maintain all test descriptions in English for consistency? This would align with the codebase's primary language.
Also applies to: 112-118
120-131
: LGTM! Well-structured test for comment deletion.The test case properly verifies the deletion functionality using AddedCommentDTO and includes all necessary properties.
164-230
: LGTM! Comprehensive test coverage for comment interactions.The test cases thoroughly cover:
- Counter updates (likes)
- Reply functionality
- Content form updates
- Author verification
- isAddingReply flag management
The tests are well-structured with clear setup and expectations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🔭 Outside diff range comments (1)
src/app/main/component/comments/components/comments-list/comments-list.component.spec.ts (1)
22-50
: 🛠️ Refactor suggestionAdd tests for like/dislike functionality.
The new like/dislike methods need test coverage. Add the following to the service mock:
const commentsServiceMock: any = { editComment: jasmine.createSpy('editComment').and.returnValue(of()), + postLike: jasmine.createSpy('postLike').and.returnValue(of()), + postDislike: jasmine.createSpy('postDislike').and.returnValue(of()), getActiveRepliesByPage: jasmine.createSpy('getActiveRepliesByPage').and.returnValue( // ... existing mock implementation ) };And add these test cases:
it('should handle successful like action', () => { const commentId = 1; component.likeComment(commentId); expect(commentsServiceMock.postLike).toHaveBeenCalledWith(commentId); }); it('should handle successful dislike action', () => { const commentId = 1; component.dislikeComment(commentId); expect(commentsServiceMock.postDislike).toHaveBeenCalledWith(commentId); }); it('should prevent concurrent like/dislike requests', () => { const commentId = 1; component.likeComment(commentId); component.likeComment(commentId); expect(commentsServiceMock.postLike).toHaveBeenCalledTimes(1); });
🧹 Nitpick comments (4)
src/app/main/component/comments/components/comments-list/comments-list.component.ts (2)
81-88
: Consider enhancing updateLikeDislikeCount with additional safeguards.The method could be more robust by:
- Adding type safety for the comment object
- Adding validation for negative counts
- private updateLikeDislikeCount(commentId: number, type: ReactionType, isAdd: boolean): void { + private updateLikeDislikeCount(commentId: number, type: ReactionType, isAdd: boolean): void { + if (!commentId || !type) { + console.warn('Invalid parameters passed to updateLikeDislikeCount'); + return; + } this.elementsList = this.elementsList.map((comment) => { if (comment?.id === commentId) { - comment[type] = Math.max(0, comment[type] + (isAdd ? 1 : -1)); + const currentCount = comment[type] || 0; + comment[type] = Math.max(0, currentCount + (isAdd ? 1 : -1)); } return comment; }); }
90-116
: Improve user feedback messages for better UX.The success and error messages could be more user-friendly and specific.
- this.snackBar.open('Comment liked successfully', 'Close', { + this.snackBar.open('Thanks for liking this comment!', 'Dismiss', { duration: 3000 }); - this.snackBar.open('Failed to like the comment. Please try again.', 'Close', { + this.snackBar.open('Unable to like the comment. Please try again later.', 'Dismiss', { - this.snackBar.open('Comment disliked successfully', 'Close', { + this.snackBar.open('Your feedback has been recorded', 'Dismiss', { duration: 3000 }); - this.snackBar.open('Failed to dislike the comment. Please try again.', 'Close', { + this.snackBar.open('Unable to record your feedback. Please try again later.', 'Dismiss', {Also applies to: 118-144
src/app/main/component/comments/components/comments-list/comments-list.component.spec.ts (1)
108-110
: Fix typos in test descriptions and improve clarity.Several test descriptions contain typos and are unclear:
'return the created componennt'
→'should create the component'
'inititilez preperties'
→'should initialize properties'
Also applies to: 112-118
src/app/main/component/events/components/events-list/events-list.component.ts (1)
141-163
: Add error handling for edge cases in updateEventReaction.The
updateEventReaction
method should handle edge cases where:
- The likes count might go negative
- The event might not be found in the list
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) { + if (current.isLiked) { current.likes--; current.isLiked = false; } current.isDisliked = true; } } + } else { + this.toastr.error('Event not found in the list'); } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/app/main/component/comments/components/comments-list/comments-list.component.spec.ts
(4 hunks)src/app/main/component/comments/components/comments-list/comments-list.component.ts
(4 hunks)src/app/main/component/comments/components/comments-list/reaction-type.enum.ts
(1 hunks)src/app/main/component/events/components/events-list/events-list.component.ts
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build (18.x)
🔇 Additional comments (2)
src/app/main/component/comments/components/comments-list/reaction-type.enum.ts (1)
1-4
: LGTM! Well-structured enum for reaction types.The enum provides good type safety and clear naming for reaction types.
src/app/main/component/events/components/events-list/events-list.component.ts (1)
114-119
: LGTM: Efficient event list update implementation.The
refreshEventInList
method efficiently updates a single event in the list without requiring a full list refresh.
src/app/main/component/events/components/events-list/events-list.component.ts
Outdated
Show resolved
Hide resolved
src/app/main/component/events/components/events-list/events-list.component.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/app/main/component/comments/models/comments-model.ts (1)
15-15
: Consider consolidating like-related properties.The interface has both
currentUserLiked
andisLiked
properties which appear to serve the same purpose. Consider consolidating these properties to maintain a single source of truth and consistent naming:- currentUserLiked: boolean; - isLiked: boolean; - isDisliked: boolean; + reactionStatus: { + isLiked: boolean; + isDisliked: boolean; + };Also applies to: 18-19
src/app/main/component/comments/components/comments-list/comments-list.component.ts (1)
27-27
: Remove redundant processing state properties.The
isProcessingLike
andisProcessingDislike
properties are redundant since you're already using theisProcessing
Set to track the processing state per comment.private isProcessing = new Set<number>(); - private isProcessingLike = false; - private isProcessingDislike = false;Also applies to: 56-57
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
src/assets/img/comments/dislike.png
is excluded by!**/*.png
src/assets/img/comments/disliked.png
is excluded by!**/*.png
📒 Files selected for processing (9)
src/app/main/component/comments/components/comments-container/comments-container.component.ts
(1 hunks)src/app/main/component/comments/components/comments-list/comments-list.component.html
(1 hunks)src/app/main/component/comments/components/comments-list/comments-list.component.scss
(3 hunks)src/app/main/component/comments/components/comments-list/comments-list.component.ts
(5 hunks)src/app/main/component/comments/models/comments-model.ts
(2 hunks)src/app/main/component/events/services/events.service.ts
(3 hunks)src/app/main/component/shared/components/events-list-item/events-list-item.component.html
(1 hunks)src/app/main/component/shared/components/events-list-item/events-list-item.component.scss
(2 hunks)src/app/main/component/shared/components/events-list-item/events-list-item.component.ts
(2 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
- src/app/main/component/shared/components/events-list-item/events-list-item.component.scss
- src/app/main/component/comments/components/comments-list/comments-list.component.scss
- src/app/main/component/events/services/events.service.ts
- src/app/main/component/comments/components/comments-list/comments-list.component.html
🔇 Additional comments (6)
src/app/main/component/comments/components/comments-container/comments-container.component.ts (1)
72-74
: LGTM!The initialization of the new properties
isLiked
andisDisliked
tofalse
is correct and follows the interface changes.src/app/main/component/comments/components/comments-list/comments-list.component.ts (2)
86-93
: Consider enhancing the like/dislike state management.The current implementation only supports incrementing counts, which might lead to incorrect state if users change their reactions.
99-126
: LGTM! Robust implementation of like/dislike functionality.The implementation includes:
- Proper error handling with user feedback
- Proper cleanup of processing state
- Proper null checks
- Proper state updates for both like and dislike counts
Also applies to: 128-154
src/app/main/component/shared/components/events-list-item/events-list-item.component.ts (2)
51-52
: LGTM! Event emitters are properly defined.The event emitters are correctly decorated and typed for communicating like/dislike status changes.
398-415
: Add authentication check before disliking.The method needs to verify if the user is authenticated before making the API call.
src/app/main/component/shared/components/events-list-item/events-list-item.component.html (1)
99-121
: LGTM! Like/dislike buttons implementation follows best practices.The implementation includes:
- Proper event bubbling prevention
- ARIA attributes for accessibility
- Semantic button elements
- Separate counts for likes and dislikes
src/app/main/component/shared/components/events-list-item/events-list-item.component.ts
Outdated
Show resolved
Hide resolved
652de5f
to
1965343
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (2)
src/app/greencity/modules/events/services/events-comments.service.ts (1)
57-59
: Inconsistent parameter naming and missing error handling.The
postDislike
method usescommentId
as parameter name while related methods likepostLike
useparentCommentId
. For consistency, consider using the same parameter name. Also, unlike the similar methods inEventsService
, there's no error handling here.- postDislike(commentId: number): Observable<void> { - return this.http.post<void>(`${this.backEnd}events/comments/dislike/${commentId}`, {}); + postDislike(parentCommentId: number): Observable<void> { + return this.http.post<void>(`${this.backEnd}events/comments/dislike/${parentCommentId}`, {}) + .pipe( + catchError((error) => { + console.error('Error disliking comment:', error); + return throwError(() => error); + }) + );Don't forget to add the necessary imports:
import { catchError } from 'rxjs/operators'; import { throwError } from 'rxjs';src/app/greencity/modules/events/services/events.service.ts (1)
168-170
: Inconsistent error handling and return type.The
dislikeEvent
method has a different error handling style and return type compared tolikeEvent
. For consistency, consider:
- Using the same error handling pattern (with or without logging)
- Using the same return type (
LikeResponse
instead ofany
)- dislikeEvent(eventId: number): Observable<any> { - return this.http.post<any>(`${this.backEnd}events/${eventId}/dislike`, {}).pipe(catchError((error) => throwError(() => error))); + dislikeEvent(eventId: number): Observable<LikeResponse> { + return this.http.post<LikeResponse>(`${this.backEnd}events/${eventId}/dislike`, {}).pipe( + catchError((error) => { + console.error('Error disliking event:', error); + return throwError(() => error); + }) + );
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
src/app/greencity/modules/events/models/events.interface.ts
(3 hunks)src/app/greencity/modules/events/services/LikeResponse.ts
(1 hunks)src/app/greencity/modules/events/services/events-comments.service.ts
(1 hunks)src/app/greencity/modules/events/services/events.service.ts
(3 hunks)
✅ Files skipped from review due to trivial changes (1)
- src/app/greencity/modules/events/services/LikeResponse.ts
🔇 Additional comments (3)
src/app/greencity/modules/events/models/events.interface.ts (1)
151-153
: LGTM! Good additions to the EventResponse interface.The new properties for tracking dislikes and like/dislike status are well-placed and properly typed. They complement the existing
likes
property and provide a more complete representation of user interactions with events.src/app/greencity/modules/events/services/events.service.ts (2)
4-4
: LGTM! Appropriate imports for the new functionality.The added imports are necessary for the new like/dislike methods and their error handling.
Also applies to: 16-17
17-17
:✅ Verification successful
Missing LikeResponse interface definition.
The
LikeResponse
interface is imported but not defined in the provided files. Make sure this interface exists and is properly defined.
🏁 Script executed:
#!/bin/bash # Check if the LikeResponse interface exists echo "Searching for LikeResponse interface definition:" fd -e ts | xargs grep -l "interface LikeResponse"Length of output: 319
Interface Definition Verified: The LikeResponse interface is now defined and available.
The verification shows that the file
src/app/greencity/modules/events/services/LikeResponse.ts
exists and contains the LikeResponse interface definition. Please ensure that this file correctly exports the interface (e.g., usingexport interface LikeResponse
) so that the import inevents.service.ts
works as expected.
likeEvent(eventId: number): Observable<LikeResponse> { | ||
return this.http.post<LikeResponse>(`${this.backEnd}events/${eventId}/like`, {}).pipe( | ||
catchError((error) => { | ||
console.error('Error liking event:', error); | ||
return throwError(() => error); | ||
}) | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Consider aligning with existing postToggleLike
method.
The new likeEvent
method seems to overlap with the existing postToggleLike
method (line 129). Consider either deprecating the old method or clarifying the different purposes in documentation.
🏁 Script executed:
#!/bin/bash
# Check if postToggleLike is still being used elsewhere in the codebase
echo "Checking usages of postToggleLike method:"
rg -A 2 -B 2 "postToggleLike" --type=ts
Length of output: 7299
Action Required: Consolidate Duplicate "Like" Methods
The new implementation of likeEvent
in src/app/greencity/modules/events/services/events.service.ts
overlaps significantly with the existing postToggleLike
method—which is also used in both the events and eco-news modules. In particular, both methods target the same endpoint (events/${eventId}/like
) and perform very similar operations, with the only notable difference being additional error handling and response typing in likeEvent
.
Recommendations:
- Consolidate or Deprecate: Consider merging these methods into a single implementation to avoid redundancy, or deprecate one if a distinct behavior is not warranted.
- Clarify Differences: If both methods must coexist (e.g., one for stricter error reporting and another for a different usage context), update the inline documentation and external docs to clearly articulate their intended purposes and differences.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/app/greencity/shared/components/events-list-item/events-list-item.component.scss (1)
22-26
: Style Update: Border Removal on#like
and#dislike
Removing the border from the#like
and#dislike
elements aligns with the desired UI adjustments for the new like/dislike indicators. As a minor suggestion, consider whether using ID selectors is optimal for styling or if a class-based approach might offer more flexibility in the future.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/app/greencity/shared/components/events-list-item/events-list-item.component.scss
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build (18.x)
🔇 Additional comments (1)
src/app/greencity/shared/components/events-list-item/events-list-item.component.scss (1)
18-21
: Style Update: New.rotate-icon
Class Addition
The addition of the.rotate-icon
class, which applies a 180-degree rotation viatransform: rotate(180deg);
, clearly supports the design intent for toggling icon orientation. This change is straightforward and meets the styling needs as described in the PR objectives.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (1)
src/app/greencity/modules/events/services/events.service.ts (1)
159-166
:⚠️ Potential issueAction Required: Consolidate Duplicate "Like" Methods
The new implementation of
likeEvent
overlaps significantly with the existingpostToggleLike
method (line 129). Both methods target similar endpoints (events/${eventId}/like-v2
vsevents/${eventId}/like
) and perform very similar operations, with the main differences being additional error handling and response typing inlikeEvent
.Consider:
- Consolidating these methods by enhancing
postToggleLike
with better typing and error handling- Deprecating the old method if the new one should be used going forward
- Adding clear documentation to explain the difference between these methods
postToggleLike(eventId: number): Observable<LikeResponse> { - return this.http.post(`${this.backEnd}events/${eventId}/like`, {}); + return this.http.post<LikeResponse>(`${this.backEnd}events/${eventId}/like-v2`, {}).pipe( + catchError((error) => { + console.error('Error liking event:', error); + return throwError(() => error); + }) + ); } // Remove this duplicate method -likeEvent(eventId: number): Observable<LikeResponse> { - return this.http.post<LikeResponse>(`${this.backEnd}events/${eventId}/like-v2`, {}).pipe( - catchError((error) => { - console.error('Error liking event:', error); - return throwError(() => error); - }) - ); -}
🧹 Nitpick comments (2)
src/app/greencity/modules/events/services/events.service.ts (2)
4-4
: Consider organizing related imports together.While the new imports are necessary for the added functionality, they could be organized more consistently. Consider grouping related imports together - RxJS operators (
catchError
) could be included in the existing RxJS imports, and model-related imports (LikeResponse
) could be grouped with other model imports.import { HttpClient, HttpParams } from '@angular/common/http'; import { Injectable, OnDestroy } from '@angular/core'; import { environment } from '@environment/environment'; -import { Observable, ReplaySubject, throwError } from 'rxjs'; +import { Observable, ReplaySubject } from 'rxjs'; +import { throwError } from 'rxjs'; import { Addresses, EventAttender, EventForm, EventResponse, EventResponseDto, LocationResponse, EventDto, PlaceOnline -} from '../models/events.interface'; +} from '../models/events.interface'; +import { LikeResponse } from './LikeResponse'; import { LanguageService } from 'src/app/shared/i18n/language.service'; -import { catchError } from 'rxjs/operators'; -import { LikeResponse } from './LikeResponse'; +import { catchError } from 'rxjs/operators';Also applies to: 16-16, 17-17
159-170
: Document the differences between like/dislike methods and their corresponding endpoints.Adding clear documentation comments for the new methods would help explain:
- The purpose of the new
-v2
endpoints compared to existing ones- The relationship between the new methods and the existing
postToggleLike
method- When developers should use each method
/** * Likes an event using the v2 endpoint. * @param eventId - The ID of the event to like * @returns An Observable containing the like response with ID and liked status * @see postToggleLike - Legacy method for toggling likes */ likeEvent(eventId: number): Observable<LikeResponse> { return this.http.post<LikeResponse>(`${this.backEnd}events/${eventId}/like-v2`, {}).pipe( catchError((error) => { console.error('Error liking event:', error); return throwError(() => error); }) ); } /** * Dislikes an event using the v2 endpoint. * @param eventId - The ID of the event to dislike * @returns An Observable containing the like response */ dislikeEvent(eventId: number): Observable<any> { return this.http.post<any>(`${this.backEnd}events/${eventId}/dislike-v2`, {}).pipe(catchError((error) => throwError(() => error))); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/app/greencity/modules/events/services/events.service.ts
(3 hunks)src/app/shared/services/localstorage/local-storage.service.spec.ts
(1 hunks)
✅ Files skipped from review due to trivial changes (1)
- src/app/shared/services/localstorage/local-storage.service.spec.ts
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build (18.x)
likeEvent(eventId: number): Observable<LikeResponse> { | ||
return this.http.post<LikeResponse>(`${this.backEnd}events/${eventId}/like-v2`, {}).pipe( | ||
catchError((error) => { | ||
console.error('Error liking event:', error); | ||
return throwError(() => error); | ||
}) | ||
); | ||
} | ||
|
||
dislikeEvent(eventId: number): Observable<any> { | ||
return this.http.post<any>(`${this.backEnd}events/${eventId}/dislike-v2`, {}).pipe(catchError((error) => throwError(() => error))); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Verify API endpoint naming patterns for consistency.
The new endpoints use -v2
suffix (like-v2
, dislike-v2
), while other endpoints in this service follow different patterns. For example, getEventById
uses /v2/
in the path rather than a suffix. Ensure this follows the API's established versioning patterns.
Run the following to check endpoint versioning patterns across the codebase:
🏁 Script executed:
#!/bin/bash
# Check for different API version patterns in the codebase
echo "Checking for /v2/ pattern in paths:"
rg "this\.backEnd.*?/v2/" --type ts
echo -e "\nChecking for -v2 suffix pattern in paths:"
rg "this\.backEnd.*?-v2" --type ts
echo -e "\nChecking other version patterns:"
rg "this\.backEnd.*?(v\d|V\d)" --type ts
Length of output: 2494
Attention: API Endpoint Versioning Inconsistency
It appears that within the Events service the versioning pattern is mixed. The endpoints for liking/disliking events—likeEvent
and dislikeEvent
—append a -v2
suffix (e.g. ${this.backEnd}events/${eventId}/like-v2
), while other endpoints (such as getEventById
, createV2
, and updateV2
) use a /v2/
segment or embed the version directly in the action name. This discrepancy could lead to confusion or misalignment with the API’s established versioning guidelines.
Please review and either update the like/dislike endpoints to match the /v2/
pattern or confirm that the suffix approach is intentional (with appropriate documentation) for consistency.
- File:
src/app/greencity/modules/events/services/events.service.ts
getEventById
: Uses/v2/
(e.g.,${this.backEnd}events/v2/${eventId}
)likeEvent
/dislikeEvent
: Use-v2
suffix (e.g.,${this.backEnd}events/${eventId}/like-v2
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (8)
src/app/greencity/modules/comments/mocks/comments-mock.ts
(1 hunks)src/app/greencity/modules/events/components/event-details/event-details.component.spec.ts
(1 hunks)src/app/greencity/modules/events/components/event-details/event-details.component.ts
(0 hunks)src/app/greencity/modules/events/models/events.interface.ts
(1 hunks)src/app/greencity/modules/events/services/events-comments.service.ts
(1 hunks)src/app/greencity/modules/events/services/events.service.ts
(0 hunks)src/app/greencity/shared/components/events-list-item/events-list-item.component.scss
(1 hunks)src/assets/mocks/events/mock-events.ts
(6 hunks)
💤 Files with no reviewable changes (2)
- src/app/greencity/modules/events/services/events.service.ts
- src/app/greencity/modules/events/components/event-details/event-details.component.ts
✅ Files skipped from review due to trivial changes (2)
- src/app/greencity/modules/events/components/event-details/event-details.component.spec.ts
- src/app/greencity/modules/comments/mocks/comments-mock.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- src/app/greencity/modules/events/services/events-comments.service.ts
- src/app/greencity/modules/events/models/events.interface.ts
- src/assets/mocks/events/mock-events.ts
🧰 Additional context used
🪛 GitHub Actions: CI/CD GreenCityClient
src/app/greencity/shared/components/events-list-item/events-list-item.component.scss
[error] 22-22: Unexpected unknown type selector '<<<<<<' (selector-type-no-unknown)
[error] 22-22: Expected 'HEAD' to be 'head' (selector-type-case)
[error] 27-27: Unexpected unknown type selector '=======' (selector-type-no-unknown)
[error] 27-27: Unexpected unknown type selector 'dev' (selector-type-no-unknown)
src/app/greencity/shared/components/events-list-item/events-list-item.component.scss
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/app/greencity/modules/events/components/events-list/LikeResponse.ts
(1 hunks)src/app/greencity/modules/events/components/events-list/events-list.component.html
(1 hunks)src/app/greencity/modules/events/components/events-list/events-list.component.ts
(3 hunks)
🔇 Additional comments (6)
src/app/greencity/modules/events/components/events-list/LikeResponse.ts (1)
1-7
: Well-structured interface for like/dislike functionality.This interface is clearly defined with appropriate properties for tracking like/dislike status and counts.
src/app/greencity/modules/events/components/events-list/events-list.component.html (1)
145-146
: Event handler names updated to match component implementation.The event handler names have been updated from
likeEvent($event)
anddislikeEvent($event)
toonLikeStatusChange($event)
andonDislikeStatusChange($event)
respectively, aligning with the new method names in the component class.src/app/greencity/modules/events/components/events-list/events-list.component.ts (4)
2-2
: Added EventDto import for the updated event handling logic.The import statement now includes
EventDto
, which is needed for the newupdateEventFromServer
method.
116-127
: New method to update event from server response.The new
updateEventFromServer
method replaces the removedrefreshEventInList
method with a more streamlined approach. It efficiently updates only the necessary properties (likes, dislikes, isLiked, isDisliked) while preserving the rest of the event data.
128-133
: New handler for like status changes.This handler efficiently updates an event in the list when its like status changes, using the spread operator to merge properties instead of making additional API calls.
135-140
: New handler for dislike status changes.This method mirrors the like status change handler, providing consistent handling for both types of reactions. This is a good example of code reuse pattern.
@@ -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'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
import { LikeResponse } from '../../services/LikeResponse'; | |
import { LikeResponse } from './LikeResponse'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (1)
src/app/greencity/shared/components/events-list-item/events-list-item.component.ts (1)
338-354
: Improved likePost implementation with proper response handlingThe updated
likePost
method now properly handles both successful (200) and "reset" (204) responses, updating the event object's like/dislike properties accordingly. Good error handling is also included.However, there's a minor inconsistency in the error message:
- (error) => console.error('Error in likeEvent:', error) + (error) => console.error('Error in likePost:', error)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
src/app/greencity/modules/events/services/LikeResponse.ts
(1 hunks)src/app/greencity/modules/events/services/events.service.ts
(2 hunks)src/app/greencity/shared/components/events-list-item/events-list-item.component.ts
(1 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
src/app/greencity/modules/events/services/events.service.ts (1)
src/app/greencity/modules/events/models/events.interface.ts (1)
EventDto
(8-32)
🔇 Additional comments (4)
src/app/greencity/modules/events/services/LikeResponse.ts (1)
1-6
: Interface changes look good and provide better metricsThe revised
LikeResponse
interface now provides a more comprehensive view of reaction metrics with numeric counts (likes
,dislikes
) and user state flags (isLiked
,isDisliked
). This is a good improvement over the previous boolean representation.src/app/greencity/modules/events/services/events.service.ts (3)
1-1
: Additional HttpResponse import added correctlyThe import of
HttpResponse
is correctly added to support the updated return types of the like/dislike methods.
175-177
: Standardized return type for dislikeEvent methodGreat improvement! The method now returns a properly typed response (
Observable<HttpResponse<EventDto>>
) instead ofObservable<any>
, which aligns with thelikeEvent
method. This standardization ensures consistency and better type safety.
171-173
:❓ Verification inconclusive
Improved type safety and response handling for likeEvent
The method now properly returns the full HTTP response object with appropriate typing, enabling status code checks in consuming components. This is a good improvement.
However, note that the versioning inconsistency raised in a previous review still exists - this method uses
-v2
suffix while other methods in this service use/v2/
in the path. Verify if this inconsistency is intentional or should be fixed.
🏁 Script executed:
#!/bin/bash # Check if there are other endpoints using -v2 suffix vs /v2/ path echo "Endpoints using -v2 suffix:" rg "this\.backEnd.*[^/]-v2" --type ts echo -e "\nEndpoints using /v2/ in path:" rg "this\.backEnd.*\/v2\/" --type tsLength of output: 664
Versioning Inconsistency – Please Verify
The improved type safety and response handling in
likeEvent
(and similarly indislikeEvent
) are great improvements. However, based on our searches, these endpoints use the-v2
suffix, and there’s an indication (from previous context) that other endpoints in this service might be structured with/v2/
in the path. I couldn’t clearly confirm/v2/
usage in this file (aside from the regex issue during search), so please review the endpoint versioning across the service to verify if the discrepancy is intentional or if the URLs should be aligned.
- Endpoints using
-v2
:
src/app/greencity/modules/events/services/events.service.ts
(e.g.,like-v2
,dislike-v2
)- Action Requested:
- Confirm whether the
-v2
suffix is the intentional pattern for these endpoints or if they should follow the/v2/
convention used elsewhere.
dislikePost(): void { | ||
this.eventService.dislikeEvent(this.event.id).subscribe( | ||
(res) => { | ||
if (res.status === 200 && res.body) { | ||
this.event = { | ||
...this.event, | ||
likes: res.body.likes, | ||
dislikes: res.body.dislikes, | ||
isLiked: res.body.isLiked, | ||
isDisliked: res.body.isDisliked | ||
}; | ||
} else if (res.status === 204) { | ||
this.event.isLiked = false; | ||
this.event.likes = Math.max(0, this.event.likes - 1); | ||
} | ||
|
||
this.likeStatusChange.emit(this.event); | ||
}, | ||
(error) => { | ||
console.error('Error in likeEvent:', error); | ||
} | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Logic inconsistency in dislikePost implementation
The dislikePost
method handles responses differently from likePost
:
- It uses object spread to update the event object in the 200 status case
- It's only updating
isLiked
andlikes
properties in the 204 case, not touchingisDisliked
ordislikes
- It emits
likeStatusChange
instead ofdislikeStatusChange
Fix these issues for consistent behavior:
dislikePost(): void {
this.eventService.dislikeEvent(this.event.id).subscribe(
(res) => {
if (res.status === 200 && res.body) {
- this.event = {
- ...this.event,
- likes: res.body.likes,
- dislikes: res.body.dislikes,
- isLiked: res.body.isLiked,
- isDisliked: res.body.isDisliked
- };
+ this.event.likes = res.body.likes;
+ this.event.dislikes = res.body.dislikes;
+ this.event.isLiked = res.body.isLiked;
+ this.event.isDisliked = res.body.isDisliked;
} else if (res.status === 204) {
- this.event.isLiked = false;
- this.event.likes = Math.max(0, this.event.likes - 1);
+ this.event.isDisliked = false;
+ this.event.dislikes = Math.max(0, this.event.dislikes - 1);
}
- this.likeStatusChange.emit(this.event);
+ this.dislikeStatusChange.emit(this.event);
},
(error) => {
- console.error('Error in likeEvent:', error);
+ console.error('Error in dislikePost:', error);
}
);
}
📝 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.
dislikePost(): void { | |
this.eventService.dislikeEvent(this.event.id).subscribe( | |
(res) => { | |
if (res.status === 200 && res.body) { | |
this.event = { | |
...this.event, | |
likes: res.body.likes, | |
dislikes: res.body.dislikes, | |
isLiked: res.body.isLiked, | |
isDisliked: res.body.isDisliked | |
}; | |
} else if (res.status === 204) { | |
this.event.isLiked = false; | |
this.event.likes = Math.max(0, this.event.likes - 1); | |
} | |
this.likeStatusChange.emit(this.event); | |
}, | |
(error) => { | |
console.error('Error in likeEvent:', error); | |
} | |
); | |
} | |
dislikePost(): void { | |
this.eventService.dislikeEvent(this.event.id).subscribe( | |
(res) => { | |
if (res.status === 200 && res.body) { | |
this.event.likes = res.body.likes; | |
this.event.dislikes = res.body.dislikes; | |
this.event.isLiked = res.body.isLiked; | |
this.event.isDisliked = res.body.isDisliked; | |
} else if (res.status === 204) { | |
this.event.isDisliked = false; | |
this.event.dislikes = Math.max(0, this.event.dislikes - 1); | |
} | |
this.dislikeStatusChange.emit(this.event); | |
}, | |
(error) => { | |
console.error('Error in dislikePost:', error); | |
} | |
); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🔭 Outside diff range comments (1)
src/app/greencity/modules/user/services/habit-comments/habit-comments.service.ts (1)
8-8
:⚠️ Potential issueUpdate required for CommentsDTO import.
The file needs to import CommentsDTO from the comments-model to match the interface requirements defined in CommentsService.
-import { AddedCommentDTO, CommentFormData, CommentsModel } from 'src/app/greencity/modules/comments/models/comments-model'; +import { AddedCommentDTO, CommentFormData, CommentsDTO, CommentsModel } from 'src/app/greencity/modules/comments/models/comments-model';
🧹 Nitpick comments (1)
src/app/greencity/modules/eco-news/services/eco-news-comments.service.ts (1)
63-65
: New postLikeV2 method looks good, but consider removing old postDislike method.The new postLikeV2 method correctly returns an Observable instead of Observable, allowing components to update with the latest comment data immediately after a like action. However, while you've added this new method, the old postDislike method (lines 25-32) still exists in the file, which could lead to confusion for developers.
Consider removing the old postDislike method since it's being replaced by postDislikeV2.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
src/app/greencity/modules/comments/components/comments-container/comments-container.component.ts
(1 hunks)src/app/greencity/modules/comments/components/comments-list/comments-list.component.ts
(3 hunks)src/app/greencity/modules/comments/components/like-comment/like-comment.component.html
(1 hunks)src/app/greencity/modules/comments/components/like-comment/like-comment.component.ts
(0 hunks)src/app/greencity/modules/comments/models/comments-model.ts
(2 hunks)src/app/greencity/modules/comments/services/comments.service.ts
(2 hunks)src/app/greencity/modules/eco-news/services/eco-news-comments.service.ts
(2 hunks)src/app/greencity/modules/events/services/events-comments.service.ts
(2 hunks)src/app/greencity/modules/user/services/habit-comments/habit-comments.service.ts
(1 hunks)
💤 Files with no reviewable changes (1)
- src/app/greencity/modules/comments/components/like-comment/like-comment.component.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/app/greencity/modules/events/services/events-comments.service.ts
🧰 Additional context used
🧬 Code Definitions (3)
src/app/greencity/modules/comments/components/comments-list/comments-list.component.ts (1)
src/app/greencity/modules/comments/models/comments-model.ts (1)
CommentsDTO
(13-31)
src/app/greencity/modules/eco-news/services/eco-news-comments.service.ts (1)
src/app/greencity/modules/comments/models/comments-model.ts (1)
CommentsDTO
(13-31)
src/app/greencity/modules/comments/services/comments.service.ts (1)
src/app/greencity/modules/comments/models/comments-model.ts (1)
CommentsDTO
(13-31)
🔇 Additional comments (11)
src/app/greencity/modules/comments/components/like-comment/like-comment.component.html (1)
2-2
:❓ Verification inconclusive
Button is no longer interactive
The click event handler has been removed from this button, making it non-interactive. If this is intentional as part of a broader refactoring (moving like functionality elsewhere), ensure the button has proper styling to indicate its non-interactive state to users.
🏁 Script executed:
#!/bin/bash # Search for any other files that might be handling the like functionality now rg -A 5 "pressLike" src/app/greencity/modules/comments/components/Length of output: 66
Below is the rewritten review comment. Please confirm that the removal of the click event was indeed intended as part of the refactoring, and if so, ensure that the inactive state of the button is clearly communicated through appropriate styling.
Attention: Click Event Missing on Like Button
The
<button class="cta-btn like">
insrc/app/greencity/modules/comments/components/like-comment/like-comment.component.html
currently lacks a click event binding. Our initial search for like-related handlers (e.g., “pressLike”) did not yield any results suggesting that this functionality has been moved elsewhere.
- Verify whether this removal is intentional.
- If the button is meant to remain non-interactive, consider applying a disabled or inactive style to signal this state to users.
- If the removal was accidental, please reinstate the click event handler so that the like functionality remains operative.
src/app/greencity/modules/comments/components/comments-container/comments-container.component.ts (1)
67-69
: Added dislike properties to reply objectThe addition of
currentUserDisliked
anddislikes
properties aligns with the updatedCommentsDTO
interface. This ensures newly created replies have the proper structure for tracking dislike interactions.src/app/greencity/modules/comments/models/comments-model.ts (1)
16-19
: Enhanced comment model with dislike functionalityThe
CommentsDTO
interface has been expanded to include dislike functionality, which enables tracking both user-specific dislike status and the total dislike count for each comment. This enhancement will facilitate displaying dislike metrics to admin users as specified in the PR title.src/app/greencity/modules/comments/components/comments-list/comments-list.component.ts (3)
86-90
: Improved comment update logic with immutabilityThe new
updateCommentData
method uses immutable pattern to update comments in the list. This is a better approach than direct mutation as it ensures proper change detection in Angular.
102-112
: Enhanced like functionality with improved error handlingThe
likeComment
method has been updated to use the newpostLikeV2
service method which returns the updated comment object. The subscription now uses the object-style syntax with separate handlers for success and error cases, which is more maintainable.I particularly like:
- The use of
finalize
to ensure the comment is removed from processing regardless of success/failure- The dynamic snackbar message based on whether the comment was liked or unliked
- The proper error handling with user feedback
120-130
: Enhanced dislike functionality with similar improvementsThe
dislikeComment
method has been updated with the same pattern used inlikeComment
, providing consistent behavior and error handling for both types of reactions.src/app/greencity/modules/eco-news/services/eco-news-comments.service.ts (2)
7-7
: Good update to include CommentsDTO in imports.The import statement has been properly updated to include CommentsDTO, which is necessary for the new method return types.
67-69
: postDislikeV2 implementation looks good.This method correctly implements the commented interface and returns a CommentsDTO object, which will provide immediate feedback to the UI about the updated comment state.
src/app/greencity/modules/comments/services/comments.service.ts (3)
3-3
: Good update to include CommentsDTO in imports.The import statement has been properly updated to include CommentsDTO, which is necessary for the new method signatures.
23-23
: Updated method signature to postLikeV2 looks good.This change from postLike to postLikeV2 with a return type of Observable provides more useful functionality to implementing services, allowing components to receive updated comment data immediately after a like action.
25-25
: Updated method signature to postDislikeV2 looks good.Similar to the like method, this change provides a more useful contract for implementations and improves the user experience by enabling immediate UI updates.
src/app/greencity/modules/user/services/habit-comments/habit-comments.service.ts
Outdated
Show resolved
Hide resolved
src/app/greencity/modules/user/services/habit-comments/habit-comments.service.ts
Outdated
Show resolved
Hide resolved
…or-admins-on-eco-news-page
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/app/greencity/shared/components/events-list-item/events-list-item.component.html (1)
105-105
: Clarify Computation of Net Likes InlineThe updated
<span>
now displays the net likes by subtractingevent.dislikes
fromevent.likes
. While this inline calculation is concise, consider handling potential edge cases (such as one of the values beingnull
orundefined
) using either a safe navigation approach or by computing the net likes within the component class. This would improve clarity and maintainability of the template code.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/app/greencity/shared/components/events-list-item/events-list-item.component.html
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: build (18.x)
Summary by CodeRabbit
New Features
LikeResponse
has been introduced to provide a structured response for like actions.Refactor
Bug Fixes