Skip to content
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

Communication: Remeber last scroll position when switching tabs #9614

Open
wants to merge 22 commits into
base: develop
Choose a base branch
from

Conversation

cremertim
Copy link
Contributor

@cremertim cremertim commented Oct 28, 2024

Checklist

General

Client

  • Important: I implemented the changes with a very good performance, prevented too many (unnecessary) REST calls and made sure the UI is responsive, even with large data (e.g. using paging).
  • I strictly followed the client coding and design guidelines.
  • I added multiple integration tests (Jest) related to the features (with a high test coverage), while following the test guidelines
  • I translated all newly inserted strings into English and German.

Motivation and Context

Description

I save the last scroll position of the user during the session. If he comes back to the same channel, he start at this channel again

Steps for Testing

Prerequisites:
-1 Student
-1 Course with a atleast 50 messages in an channel (you can use my test course: Tim Cremers Test course on ts2, i prepered the #organization channel with enough posts there)

  1. Log in to Artemis
  2. Navigate into the course
  3. Verify the channel starts at the bottom
  4. Scroll in the channel to some location (The highest and FULLY seen message in your viewport will be remembered!)
  5. Go to a different tab (e.g FAQ or exercises)
  6. Go back to channels
  7. Be at the position you scrolled to before
  8. Scroll somewhere
  9. Create a new message
  10. Scrollbar jumps to bottom

Testserver States

Note

These badges show the state of the test servers.
Green = Currently available, Red = Currently locked
Click on the badges to get to the test servers.







Review Progress

Performance Review

  • I (as a reviewer) confirm that the client changes (in particular related to REST calls and UI responsiveness) are implemented with a very good performance even for very large courses with more than 2000 students.
  • I (as a reviewer) confirm that the server changes (in particular related to database calls) are implemented with a very good performance even for very large courses with more than 2000 students.

Code Review

  • Code Review 1
  • Code Review 2

Manual Tests

  • Test 1
  • Test 2

Test Coverage

Screenshots

Summary by CodeRabbit

Summary by CodeRabbit

  • New Features

    • Streamlined message creation process with a new method for handling new messages.
    • Enhanced conversation messages component to save and restore scroll position, improving navigation between conversations.
  • Bug Fixes

    • Adjusted scrolling behavior to ensure smoother transitions when new messages are created.
  • Chores

    • Cleaned up event listeners to prevent memory leaks when the component is destroyed.
    • Added DOM element reference for improved component interaction.
    • Introduced new test cases for scroll position management and message handling.

@cremertim cremertim requested a review from a team as a code owner October 28, 2024 11:02
@github-actions github-actions bot added the client Pull requests that update TypeScript code. (Added Automatically!) label Oct 28, 2024
Copy link

@coderabbitai coderabbitai bot left a 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 and nitpick comments (1)
src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (1)

253-259: Add safety checks for scroll position restoration.

While the implementation works, consider adding these safety measures:

  1. Add null check for conversation ID
  2. Validate saved scroll position against current content height

Consider this safer implementation:

 const savedScrollPosition = sessionStorage.getItem(this.sessionStorageKey + this._activeConversation?.id);
-if (savedScrollPosition) {
+if (savedScrollPosition && this._activeConversation?.id) {
     const scrollPos = parseInt(savedScrollPosition, 10);
+    const maxScroll = this.content.nativeElement.scrollHeight;
+    if (scrollPos <= maxScroll) {
         this.content.nativeElement.scrollTop = parseInt(savedScrollPosition, 10);
+    } else {
+        this.content.nativeElement.scrollTop = maxScroll;
+    }
 } else {
     this.content.nativeElement.scrollTop = this.content.nativeElement.scrollHeight;
 }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between c442c93 and 0ad2e22.

📒 Files selected for processing (1)
  • src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (1)

Pattern src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

🔇 Additional comments (3)
src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (3)

42-42: LGTM: Well-structured storage key.

The sessionStorageKey follows proper naming conventions and provides good namespacing for scroll position storage.


142-142: LGTM: Proper event listener setup.

The scroll event listener is correctly added in ngAfterViewInit, following Angular best practices.


148-148: LGTM: Proper event listener cleanup.

The scroll event listener is correctly removed in ngOnDestroy, preventing memory leaks.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Outside diff range and nitpick comments (1)
src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (1)

42-42: Add type annotation for sessionStorageKey.

For better type safety and code clarity, explicitly declare the type of the storage key.

-    private sessionStorageKey = 'conversationId.scrollPosition.';
+    private readonly sessionStorageKey: string = 'conversationId.scrollPosition.';
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 0ad2e22 and 28a0dc6.

📒 Files selected for processing (1)
  • src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (1)

Pattern src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

coderabbitai[bot]
coderabbitai bot previously approved these changes Oct 28, 2024
@ls1intum ls1intum deleted a comment from coderabbitai bot Oct 28, 2024
Copy link

coderabbitai bot commented Oct 29, 2024

Walkthrough

The pull request introduces modifications to the ConversationMessagesComponent in an Angular application. Key changes include the consolidation of event handling for new message creation into a single method, handleNewMessageCreated(), which replaces the previous method calls. Additionally, enhancements to scroll position management have been implemented, including the introduction of a debounce mechanism and session storage for scroll positions. The overall structure of the HTML remains unchanged, ensuring consistent user interface functionality.

Changes

File Change Summary
src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.html Updated event handling for message creation to use handleNewMessageCreated() and modified tracking function from postsTrackByFn to postsGroupTrackByFn.
src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts Introduced new private variables and methods for scroll position management, including setupScrollDebounce, saveScrollPosition, and updated handleScrollOnNewMessage.
src/test/javascript/spec/component/overview/course-conversations/layout/conversation-messages/conversation-messages.component.spec.ts Added test cases for saving scroll position, scrolling to the last selected element, and scrolling to the bottom upon new message creation.
src/main/webapp/app/shared/metis/posting-thread/posting-thread.component.ts Added ElementRef injection to access the DOM element within the PostingThreadComponent.

Possibly related PRs

Suggested labels

small, bugfix, component:Communication, ready for review

Suggested reviewers

  • SimonEntholzer
  • sachmii
  • HawKhiem
  • krusche

📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 095f321 and b4da15b.

📒 Files selected for processing (4)
  • src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.html (3 hunks)
  • src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (12 hunks)
  • src/main/webapp/app/shared/metis/posting-thread/posting-thread.component.ts (2 hunks)
  • src/test/javascript/spec/component/overview/course-conversations/layout/conversation-messages/conversation-messages.component.spec.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.html
  • src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts
  • src/main/webapp/app/shared/metis/posting-thread/posting-thread.component.ts
  • src/test/javascript/spec/component/overview/course-conversations/layout/conversation-messages/conversation-messages.component.spec.ts

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a 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.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between c442c93 and 9726517.

📒 Files selected for processing (2)
  • src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.html (2 hunks)
  • src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (5 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.html (1)

Pattern src/main/webapp/**/*.html: @if and @for are new and valid Angular syntax replacing *ngIf and *ngFor. They should always be used over the old style.

src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (1)

Pattern src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

🔇 Additional comments (10)
src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.html (3)

99-99: LGTM! Good consolidation of event handling logic.

The change properly encapsulates the post creation and scroll behavior into a single method, which is a cleaner approach.


102-102: LGTM! Consistent event handling in mobile view.

The change maintains consistency with the modal implementation, using the same consolidated event handler.


112-115: LGTM! Consistent event handling across all views.

The changes maintain a unified approach to message creation handling across mobile and desktop views. This consistency will help ensure reliable scroll position management.

Let's verify the scroll position management implementation:

✅ Verification successful

Scroll position management is properly implemented and working as expected

The verification confirms that scroll position management is correctly implemented in the component:

  • Scroll position is saved to session storage using a debounced event handler
  • When creating new messages, the view automatically scrolls to the bottom
  • For existing conversations, the saved scroll position is restored
  • The implementation handles both new message creation and conversation switching scenarios
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for scroll position management implementation in the component
# Expected: Find scroll position related code in the component

# Look for scroll position related code in the component
rg -A 5 "scrollTo|scroll" src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts

# Look for session storage usage for scroll position
ast-grep --pattern 'sessionStorage.setItem($_, $_)'

Length of output: 4176

src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (7)

42-48: LGTM: Well-structured scroll position management setup.

The implementation uses appropriate types and follows Angular best practices:

  • Good use of sessionStorage for maintaining scroll position during session
  • Reasonable debounce time of 100ms for scroll events
  • Proper use of RxJS Subject for handling scroll events

102-102: LGTM: Proper initialization of scroll handling.

Correctly initializes scroll debounce setup in ngOnInit lifecycle hook.


146-146: Skip: Previously reviewed.

Skipping as previous review comments about adding null checks for content.nativeElement are still valid.

Also applies to: 152-152


250-262: Skip: Previously reviewed.

Skipping as previous review comments about improving scroll position restoration robustness are still valid.


285-287: Skip: Previously reviewed.

Skipping as previous review comments about adding null checks and type safety to saveScrollPosition are still valid.


289-292: LGTM: Well-structured message creation handler.

Good implementation that:

  • Follows single responsibility principle
  • Has clear and descriptive method name
  • Properly handles the workflow of creating a new message

148-153: LGTM: Proper cleanup implementation.

The component correctly implements memory leak prevention:

  • Uses takeUntil pattern for RxJS subscriptions
  • Properly implements OnDestroy
  • Cleans up event listeners

@github-actions github-actions bot added the tests label Oct 29, 2024
Copy link

@coderabbitai coderabbitai bot left a 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 and nitpick comments (3)
src/test/javascript/spec/component/overview/course-conversations/layout/conversation-messages/conversation-messages.component.spec.ts (2)

134-144: Improve test readability and maintainability.

Several improvements can be made to this test case:

  1. Use English comments instead of German
  2. Extract magic numbers into named constants
  3. Use more specific Jest matchers

Apply this diff to improve the test:

 it('should save the scroll position in sessionStorage', fakeAsync(() => {
-    // Überwache sessionStorage.setItem
+    // Monitor sessionStorage.setItem
+    const SCROLL_POSITION = 200;
+    const DEBOUNCE_DELAY = 100;
     const setItemSpy = jest.spyOn(sessionStorage, 'setItem');
     component.ngOnInit();
-    component.content.nativeElement.scrollTop = 200;
+    component.content.nativeElement.scrollTop = SCROLL_POSITION;
     component.saveScrollPosition();
-    tick(100);
+    tick(DEBOUNCE_DELAY);
     const expectedKey = `${component.sessionStorageKey}${component._activeConversation?.id}`;
-    const expectedValue = '200';
+    const expectedValue = SCROLL_POSITION.toString();
-    expect(setItemSpy).toHaveBeenCalledWith(expectedKey, expectedValue);
+    expect(setItemSpy).toHaveBeenCalledExactlyOnceWith(expectedKey, expectedValue);
 }));

146-152: Enhance test specificity and remove unnecessary calls.

The test can be improved in several ways:

  1. The initial scroll position seems arbitrary and its purpose is unclear
  2. The fixture.detectChanges() call appears unnecessary here
  3. The timing expectations could be more specific

Apply this diff to improve the test:

 it('should scroll to the bottom when a new message is created', fakeAsync(() => {
-    component.content.nativeElement.scrollTop = 100;
-    fixture.detectChanges();
+    // Set initial scroll position to simulate user scrolling up
+    const INITIAL_SCROLL_POSITION = 100;
+    component.content.nativeElement.scrollTop = INITIAL_SCROLL_POSITION;
     component.handleNewMessageCreated();
     tick();
-    expect(component.content.nativeElement.scrollTop).toBe(component.content.nativeElement.scrollHeight);
+    
+    // Verify scroll position is at the bottom
+    const expectedScrollPosition = component.content.nativeElement.scrollHeight;
+    expect(component.content.nativeElement.scrollTop).toBe(expectedScrollPosition);
+    expect(expectedScrollPosition).toBeGreaterThan(INITIAL_SCROLL_POSITION);
 }));
src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (1)

42-43: LGTM! Consider adding type annotations for better type safety.

The scroll management properties are well-structured. The debounce time of 100ms is appropriate for scroll events.

Add type annotations for better type safety:

-    sessionStorageKey = 'conversationId.scrollPosition.';
+    private readonly sessionStorageKey: string = 'conversationId.scrollPosition.';
-    private scrollDebounceTime = 100; // ms
+    private readonly scrollDebounceTime: number = 100; // ms

Also applies to: 47-49

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 9726517 and 9979342.

📒 Files selected for processing (2)
  • src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (5 hunks)
  • src/test/javascript/spec/component/overview/course-conversations/layout/conversation-messages/conversation-messages.component.spec.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (1)

Pattern src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

src/test/javascript/spec/component/overview/course-conversations/layout/conversation-messages/conversation-messages.component.spec.ts (1)

Pattern src/test/javascript/spec/**/*.ts: jest: true; mock: NgMocks; bad_practices: avoid_full_module_import; perf_improvements: mock_irrelevant_deps; service_testing: mock_http_for_logic; no_schema: avoid_NO_ERRORS_SCHEMA; expectation_specificity: true; solutions: {boolean: toBeTrue/False, reference: toBe, existence: toBeNull/NotNull, undefined: toBeUndefined, class_obj: toContainEntries/toEqual, spy_calls: {not_called: not.toHaveBeenCalled, once: toHaveBeenCalledOnce, with_value: toHaveBeenCalledWith|toHaveBeenCalledExactlyOnceWith}}

🔇 Additional comments (1)
src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (1)

102-102: LGTM! Proper lifecycle management.

The scroll management setup and cleanup are correctly placed in the appropriate lifecycle hooks.

Also applies to: 146-146, 152-152

Copy link

@coderabbitai coderabbitai bot left a 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

🧹 Outside diff range and nitpick comments (1)
src/main/webapp/app/shared/metis/posting-thread/posting-thread.component.ts (1)

21-21: Consider implementing OnDestroy for proper cleanup.

While using ElementRef with inject() is a good practice, ensure proper cleanup to prevent potential memory leaks.

Consider implementing NgOnDestroy:

export class PostingThreadComponent implements OnDestroy {
    elementRef = inject(ElementRef);
    
    ngOnDestroy(): void {
        // Clean up any subscriptions or references if needed
    }
}
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 9979342 and d9b1024.

📒 Files selected for processing (3)
  • src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (9 hunks)
  • src/main/webapp/app/shared/metis/posting-thread/posting-thread.component.ts (2 hunks)
  • src/test/javascript/spec/component/overview/course-conversations/layout/conversation-messages/conversation-messages.component.spec.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/test/javascript/spec/component/overview/course-conversations/layout/conversation-messages/conversation-messages.component.spec.ts
🧰 Additional context used
📓 Path-based instructions (2)
src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (1)

Pattern src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

src/main/webapp/app/shared/metis/posting-thread/posting-thread.component.ts (1)

Pattern src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

🔇 Additional comments (5)
src/main/webapp/app/shared/metis/posting-thread/posting-thread.component.ts (2)

1-1: LGTM! Modern dependency injection pattern used.

Good use of the modern inject() function for ElementRef injection, which aligns with Angular's latest best practices and provides better tree-shaking capabilities.

Also applies to: 21-21


Line range hint 1-21: Verify scroll position persistence implementation.

The component has been modified to support scroll position management, but the actual implementation logic seems to be in the conversation messages component.

Let's verify the integration:

✅ Verification successful

Based on the search results, I can now generate the final response:

Scroll position persistence is properly integrated with conversation messages component

The PostingThreadComponent correctly integrates with the scroll position management system:

  • It injects ElementRef which is used by the parent ConversationMessagesComponent to handle scroll position persistence
  • The parent component maintains scroll positions in session storage with key pattern conversationId.scrollPosition.*
  • Scroll position is saved with debouncing (100ms) and restored when conversation changes
  • The implementation includes proper cleanup in ngOnDestroy
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for scroll position related logic in conversation messages component
rg -A 5 "scroll" "src/main/webapp/app/overview/course-conversations/layout/conversation-messages"

# Look for session storage usage for scroll position
rg -A 5 "sessionStorage" "src/main/webapp/app/overview/course-conversations"

Length of output: 19111

src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (3)

44-51: LGTM! Well-structured property declarations for scroll management.

The new properties are well-organized and follow Angular best practices. The debounce time of 100ms is a good balance between responsiveness and performance.


59-59: LGTM! Appropriate use of ViewChildren for message tracking.

The switch to ViewChildren is correct for managing multiple PostingThreadComponent instances.


174-174: LGTM! Proper reset of scroll position saving flag.

Correctly prevents premature scroll position saving when switching conversations.

Copy link

@coderabbitai coderabbitai bot left a 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

🧹 Outside diff range and nitpick comments (2)
src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (2)

299-302: Consider a more descriptive method name.

The method name handleNewMessageCreated could be more descriptive about its actual behavior. Consider renaming it to createEmptyPostAndScrollToBottom to better reflect its functionality.

-    handleNewMessageCreated() {
+    createEmptyPostAndScrollToBottom() {
         this.createEmptyPost();
         this.scrollToBottomOfMessages();
     }

44-44: Consider persistent storage for scroll positions.

Currently, scroll positions are stored in sessionStorage, which means they're lost when the browser is closed. Consider using localStorage for persistence across sessions, or implementing a backend storage solution for a more robust user experience.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between d9b1024 and 82aff7f.

📒 Files selected for processing (1)
  • src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (9 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (1)

Pattern src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

🔇 Additional comments (5)
src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (5)

44-51: LGTM! Well-structured scroll management setup.

The new properties are well-organized and follow Angular best practices. The debounce time of 100ms provides a good balance between responsiveness and performance.


59-59: LGTM! Improved type safety.

The explicit typing of QueryList with PostingThreadComponent enhances type safety and code maintainability.


81-81: LGTM! Well-typed scroll position tracking.

The elementsAtScrollPosition property effectively tracks visible messages for scroll position management.


95-95: LGTM! Modern dependency injection approach.

Using inject() for Renderer2 follows modern Angular practices and ensures safe DOM manipulation.


107-107: LGTM! Proper initialization timing.

Calling setupScrollDebounce in ngOnInit ensures scroll management is initialized before view rendering.

coderabbitai[bot]
coderabbitai bot previously approved these changes Oct 29, 2024
Copy link
Contributor

@JohannesWt JohannesWt left a comment

Choose a reason for hiding this comment

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

Code looks good just few small remarks

tick(100);
const expectedKey = `${component.sessionStorageKey}${component._activeConversation?.id}`;
const expectedValue = '15';
expect(setItemSpy).toHaveBeenCalledWith(expectedKey, expectedValue);
Copy link
Contributor

Choose a reason for hiding this comment

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

could we be more specific here. This can be very helpful in debugging if there is a bug somewhere.

Suggested change
expect(setItemSpy).toHaveBeenCalledWith(expectedKey, expectedValue);
expect(setItemSpy).toHaveBeenCalledExactlyOnceWith(expectedKey, expectedValue);

Copy link

@coderabbitai coderabbitai bot left a 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

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 82aff7f and 4ad6553.

📒 Files selected for processing (2)
  • src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (9 hunks)
  • src/test/javascript/spec/component/overview/course-conversations/layout/conversation-messages/conversation-messages.component.spec.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/test/javascript/spec/component/overview/course-conversations/layout/conversation-messages/conversation-messages.component.spec.ts
🧰 Additional context used
📓 Path-based instructions (1)
src/main/webapp/app/overview/course-conversations/layout/conversation-messages/conversation-messages.component.ts (1)

Pattern src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

ItsaaaMeMario
ItsaaaMeMario previously approved these changes Nov 5, 2024
Copy link

@ItsaaaMeMario ItsaaaMeMario left a comment

Choose a reason for hiding this comment

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

Tested on TS2, everything works as expected. Last scroll position is remembered after changing tabs (Exercises,...) or to other channels. Scrollbar also jumps to bottom after sending a new message.

Malekos74
Malekos74 previously approved these changes Nov 6, 2024
Copy link

@Malekos74 Malekos74 left a comment

Choose a reason for hiding this comment

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

Tested on server: 02

Works as expected. The scrolling down after writing a message now also works. Great feature 👍🏽

FelberMartin
FelberMartin previously approved these changes Nov 8, 2024
Copy link
Contributor

@FelberMartin FelberMartin left a comment

Choose a reason for hiding this comment

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

Tested on TS2 and works as described. Both the scroll position is remembered, and scrolled to the bottom when sending a new message

Copy link
Contributor

@FelberMartin FelberMartin left a comment

Choose a reason for hiding this comment

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

Tested and works described.

One thing that I noticed - but probably belongs to a different ticket - is, when scrolling up and older posts are being fetched, the previously visible posts are not displayed anymore and only a loading circle is shown (see gif below). It would be nice to keep the previously loaded messages and only show a small loading indicator above the previous messages

ArtemisChatLoading

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
client Pull requests that update TypeScript code. (Added Automatically!) lock:artemis-test2 tests
Projects
Status: Ready For Review
Development

Successfully merging this pull request may close these issues.