Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 248b1b0

Browse files
author
David
committed
chore(release): v1.101.0
- Add group-chat awareness to WhatsApp history (isGroup/groupName/fromName) - ChatList renders group names; ChatMessages surfaces per-message sender in group threads
1 parent c02d0fe commit 248b1b0

7 files changed

Lines changed: 81 additions & 10 deletions

File tree

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [1.101.0] - 2026-05-21
6+
7+
### Added
8+
- **Group-chat awareness in WhatsApp history**`WhatsAppChatSummary` gains `isGroup`, `groupName`, and `fromName`. `ChatList` now renders group chats with their group name and `ChatMessages` surfaces the originating sender for each message in a group thread. ~13 lines of new SCSS in `whatsapp-history.scss` style the group-chat affordances.
9+
510
## [1.100.0] - 2026-05-21
611

712
### Added

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "tide-commander",
3-
"version": "1.100.0",
3+
"version": "1.101.0",
44
"description": "Visual multi-agent orchestrator and manager for Claude Code with 3D/2D interface",
55
"repository": {
66
"type": "git",

src/packages/client/components/WhatsAppHistory/ChatList.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ export function ChatList({
6464
const icon = messageTypeIcon(chat.lastMessageType);
6565
const previewBase = chat.lastMessagePreview || `[${chat.lastMessageType}]`;
6666
const isSelected = chat.chatId === selectedChatId;
67+
const formattedJid = formatChatId(chat.chatId);
68+
const resolvedName = chat.isGroup ? chat.groupName : chat.fromName;
69+
const displayName = resolvedName || formattedJid;
70+
const showJidSubtitle = !!resolvedName && resolvedName !== formattedJid;
6771
return (
6872
<li
6973
key={chat.chatId}
@@ -75,13 +79,18 @@ export function ChatList({
7579
onClick={() => onSelect(chat.chatId)}
7680
>
7781
<div className="whatsapp-history-chatlist__row">
78-
<span className="whatsapp-history-chatlist__name">
79-
{formatChatId(chat.chatId)}
82+
<span className="whatsapp-history-chatlist__name" title={chat.chatId}>
83+
{displayName}
8084
</span>
8185
<span className="whatsapp-history-chatlist__time">
8286
{formatRelativeTime(chat.lastTimestamp, now)}
8387
</span>
8488
</div>
89+
{showJidSubtitle && (
90+
<div className="whatsapp-history-chatlist__row whatsapp-history-chatlist__row--jid">
91+
<span className="whatsapp-history-chatlist__jid">{formattedJid}</span>
92+
</div>
93+
)}
8594
<div className="whatsapp-history-chatlist__row whatsapp-history-chatlist__row--secondary">
8695
<span className="whatsapp-history-chatlist__preview">
8796
{chat.lastDirection === 'outbound' && (

src/packages/client/components/WhatsAppHistory/ChatMessages.tsx

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
import React, { useEffect, useRef } from 'react';
1+
import React, { useCallback, useEffect, useLayoutEffect, useRef } from 'react';
22
import { useTranslation } from 'react-i18next';
33
import type { WhatsAppMessageEvent } from '../../../shared/event-types';
44
import { MessageBubble } from './MessageBubble';
55
import { ChatFilters, type DirectionFilter, type TypeFilter } from './ChatFilters';
66
import { formatChatId } from './format';
77

8+
const AUTO_LOAD_THRESHOLD_PX = 80;
9+
810
interface ChatMessagesProps {
911
chatId: string | null;
1012
messages: WhatsAppMessageEvent[];
@@ -35,15 +37,50 @@ export function ChatMessages({
3537
const { t } = useTranslation(['config']);
3638
const scrollRef = useRef<HTMLDivElement>(null);
3739
const lastChatIdRef = useRef<string | null>(null);
40+
const initialScrolledRef = useRef(false);
41+
const prependAnchorRef = useRef<number | null>(null);
3842

43+
// Reset the "first scroll-to-bottom done" flag whenever chat changes.
3944
useEffect(() => {
40-
if (!scrollRef.current) return;
4145
if (lastChatIdRef.current !== chatId) {
4246
lastChatIdRef.current = chatId;
43-
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
47+
initialScrolledRef.current = false;
4448
}
49+
}, [chatId]);
50+
51+
// After messages first arrive for a chat, scroll to the bottom (newest).
52+
useLayoutEffect(() => {
53+
if (!scrollRef.current) return;
54+
if (initialScrolledRef.current) return;
55+
if (messages.length === 0) return;
56+
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
57+
initialScrolledRef.current = true;
4558
}, [chatId, messages.length]);
4659

60+
// When older messages are prepended via Load-more, preserve the visual
61+
// anchor so the viewport doesn't jump.
62+
useLayoutEffect(() => {
63+
if (!scrollRef.current) return;
64+
if (prependAnchorRef.current === null) return;
65+
const diff = scrollRef.current.scrollHeight - prependAnchorRef.current;
66+
prependAnchorRef.current = null;
67+
if (diff > 0) scrollRef.current.scrollTop += diff;
68+
}, [messages.length]);
69+
70+
const triggerLoadMore = useCallback(() => {
71+
if (!hasMore || loadingMore || loading) return;
72+
if (scrollRef.current) {
73+
prependAnchorRef.current = scrollRef.current.scrollHeight;
74+
}
75+
onLoadMore();
76+
}, [hasMore, loadingMore, loading, onLoadMore]);
77+
78+
const handleScroll = useCallback((e: React.UIEvent<HTMLDivElement>) => {
79+
if (!initialScrolledRef.current) return;
80+
const el = e.currentTarget;
81+
if (el.scrollTop <= AUTO_LOAD_THRESHOLD_PX) triggerLoadMore();
82+
}, [triggerLoadMore]);
83+
4784
if (!chatId) {
4885
return (
4986
<div className="whatsapp-history-messages whatsapp-history-messages--empty">
@@ -67,13 +104,17 @@ export function ChatMessages({
67104
/>
68105
</div>
69106

70-
<div className="whatsapp-history-messages__scroll" ref={scrollRef}>
107+
<div
108+
className="whatsapp-history-messages__scroll"
109+
ref={scrollRef}
110+
onScroll={handleScroll}
111+
>
71112
{hasMore && (
72113
<div className="whatsapp-history-messages__load-more-row">
73114
<button
74115
type="button"
75116
className="whatsapp-history-messages__load-more"
76-
onClick={onLoadMore}
117+
onClick={triggerLoadMore}
77118
disabled={loadingMore || loading}
78119
>
79120
{loadingMore

src/packages/client/styles/components/whatsapp-history.scss

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,19 @@
190190
font-size: 11px;
191191
color: $text-muted;
192192
}
193+
194+
&--jid {
195+
font-size: 10px;
196+
color: $text-muted;
197+
}
198+
}
199+
200+
&__jid {
201+
overflow: hidden;
202+
text-overflow: ellipsis;
203+
white-space: nowrap;
204+
font-family: monospace;
205+
opacity: 0.7;
193206
}
194207

195208
&__name {

src/packages/shared/whatsapp-types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ export interface WhatsAppChatSummary {
88
lastMessageType: WhatsAppMessageType;
99
lastDirection: MessageDirection;
1010
messageCount: number;
11+
isGroup: boolean;
12+
groupName?: string;
13+
fromName?: string;
1114
unreadCount: number;
1215
}
1316

0 commit comments

Comments
 (0)