Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,14 @@
<div class="com-h-full">
<div *ngFor="let group of groupedMessages">
<h3 class="grouped-date">{{ moment(group.date).format('MMMM D, YYYY') }}</h3>
<div *ngFor="let message of group.messages">
<div *ngFor="let message of group.messages" [attr.id]="'message-' + message.id">
<!-- Show "You left off here" divider for the first unread message -->
<div *ngIf="scrollToMessageId === message.id" class="last-read-divider">
<div class="divider-line"></div>
<span class="divider-text">You left off here</span>
<div class="divider-line"></div>
</div>

<app-message
[message]="message"
[canReply]="!blocked"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@
.grouped-date::after {
@apply com-ml-3;
}

.last-read-divider {
@apply com-flex com-items-center com-my-3 com-px-3;

.divider-line {
@apply com-flex-1 com-border-0 com-border-t com-border-solid com-border-red-500;
}

.divider-text {
@apply com-mx-3 com-text-xs com-font-medium com-text-red-500 com-whitespace-nowrap;
}
}
}

.blocked-text {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export class DiscussionPersonalChatComponent implements OnInit, OnDestroy {
chatChannelSubscription;
chatMessageForm;
showEmojiForm = false;
scrollToMessageId: number | null = null;
@ViewChild('inputElement', { static: true }) inputElement: ElementRef;
@ViewChild('messagesContainer') private messagesContainer: ElementRef;

Expand Down Expand Up @@ -99,6 +100,15 @@ export class DiscussionPersonalChatComponent implements OnInit, OnDestroy {
// TODO find a fix to this settimeout for scrolling to bottom on every new message loaded
setTimeout(() => {
try {
// If there's a scroll target message (first unread), scroll to it
if (this.scrollToMessageId) {
const messageElement = document.getElementById(`message-${this.scrollToMessageId}`);
Copy link

Copilot AI Oct 14, 2025

Choose a reason for hiding this comment

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

Using document.getElementById for DOM manipulation in Angular is not recommended. Consider using ViewChild, template reference variables, or the Renderer2 service for better Angular integration and testability.

Copilot uses AI. Check for mistakes.
if (messageElement) {
messageElement.scrollIntoView({ behavior: 'smooth', block: 'start' });
return;
}
}
// Otherwise, scroll to bottom as usual
this.messagesContainer.nativeElement.scrollTop = this.messagesContainer.nativeElement.scrollHeight + 300;
} catch (err) {
console.log(err);
Expand Down Expand Up @@ -131,7 +141,13 @@ export class DiscussionPersonalChatComponent implements OnInit, OnDestroy {
this.messages.unshift(...data.user_messages.reverse());
this.groupedMessages = this.groupMessagesByDate(this.messages);
this.loadingMessages = false;

// On first load, find the first unread message to scroll to
if (this.nextPage === 1) {
const firstUnreadMessage = this.messages.find((msg) => !msg.read);
Copy link

Copilot AI Oct 14, 2025

Choose a reason for hiding this comment

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

The logic assumes that messages have a 'read' property, but this should be validated or documented. Consider adding a type guard or null check to ensure the property exists and is properly typed.

Copilot uses AI. Check for mistakes.
if (firstUnreadMessage) {
this.scrollToMessageId = firstUnreadMessage.id;
}
this.scrollToBottom();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { NoWhitespaceValidator } from 'apps/shared-helper-modules/custom-validat
import { ICurrentUser } from 'apps/shared-models/current_user.model';
import { IUserMessage } from 'apps/shared-models/user_message.model';
import { IEditorValidator } from '@commudle/editor';
// import { UserMessageReceiptHandlerService } from '@commudle/shared-services';
import { UserMessageReceiptHandlerService } from 'libs/shared/components/src/lib/services/user-message-receipt-handler.service';
import * as moment from 'moment';
import { SVotesService } from 'apps/shared-components/services/s-votes.service';

Expand Down Expand Up @@ -46,7 +46,7 @@ export class MessageComponent implements OnInit {

constructor(
private fb: FormBuilder,
// private userMessageReceiptHandlerService: UserMessageReceiptHandlerService,
private userMessageReceiptHandlerService: UserMessageReceiptHandlerService,
private injector: Injector,
private votesService: SVotesService,
) {}
Expand Down Expand Up @@ -76,9 +76,9 @@ export class MessageComponent implements OnInit {
}

markAsRead(messageId: number, { visible }: { visible: boolean }): void {
// if (messageId && visible) {
// this.userMessageReceiptHandlerService.addMessageReceipt(messageId, new Date());
// }
if (messageId && visible) {
this.userMessageReceiptHandlerService.addMessageReceipt(messageId, new Date());
}
}

onHoverEnter(id) {
Expand Down