feat(db): add getLastMessageByConversation and update conversation list preview
Add `getLastMessageByConversation` to `MessageRepository` to allow fetching the most recent message for a specific conversation. Update `ConversationListRow` to use this new repository method as a fallback when message segments are missing, ensuring the conversation list preview displays the last message content correctly.
This commit is contained in:
@@ -18,6 +18,7 @@ export interface IMessageRepository {
|
||||
clearConversation(conversationId: string): Promise<void>;
|
||||
search(keyword: string): Promise<CachedMessage[]>;
|
||||
getStats(): Promise<{ totalMessages: number; totalConversations: number }>;
|
||||
getLastMessageByConversation(conversationId: string): Promise<CachedMessage | null>;
|
||||
}
|
||||
|
||||
export class MessageRepository implements IMessageRepository {
|
||||
@@ -147,6 +148,15 @@ export class MessageRepository implements IMessageRepository {
|
||||
const convCount = await this.dataSource.getFirst<{ count: number }>(`SELECT COUNT(*) as count FROM conversations`);
|
||||
return { totalMessages: msgCount?.count || 0, totalConversations: convCount?.count || 0 };
|
||||
}
|
||||
|
||||
async getLastMessageByConversation(conversationId: string): Promise<CachedMessage | null> {
|
||||
const r = await this.dataSource.getFirst<any>(
|
||||
`SELECT * FROM messages WHERE conversationId = ? AND status != 'deleted' ORDER BY seq DESC LIMIT 1`,
|
||||
[conversationId]
|
||||
);
|
||||
if (!r) return null;
|
||||
return { ...r, isRead: r.isRead === 1, segments: r.segments ? JSON.parse(r.segments) : undefined };
|
||||
}
|
||||
}
|
||||
|
||||
export const messageRepository = new MessageRepository();
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
MessageSegment,
|
||||
} from '../../../types/dto';
|
||||
import { authService } from '../../../services';
|
||||
import { userCacheRepository } from '@/database';
|
||||
import { userCacheRepository, messageRepository } from '@/database';
|
||||
import { Avatar, Text } from '../../../components/common';
|
||||
|
||||
const AnimatedTouchable = Animated.createAnimatedComponent(TouchableOpacity);
|
||||
@@ -34,7 +34,8 @@ const AsyncMessagePreview: React.FC<{
|
||||
status?: string;
|
||||
isGroupChat?: boolean;
|
||||
senderName?: string;
|
||||
}> = ({ segments, status, isGroupChat, senderName }) => {
|
||||
conversationId?: string;
|
||||
}> = ({ segments, status, isGroupChat, senderName, conversationId }) => {
|
||||
const [displayText, setDisplayText] = useState<string>('');
|
||||
const isMountedRef = useRef(true);
|
||||
|
||||
@@ -49,19 +50,33 @@ const AsyncMessagePreview: React.FC<{
|
||||
return;
|
||||
}
|
||||
|
||||
const initialText = extractTextFromSegments(segments);
|
||||
let effectiveSegments = segments;
|
||||
|
||||
// 当 segments 为空时,从本地 SQLite 回退查询
|
||||
if ((!effectiveSegments || effectiveSegments.length === 0) && conversationId) {
|
||||
try {
|
||||
const lastMsg = await messageRepository.getLastMessageByConversation(conversationId);
|
||||
if (lastMsg?.segments) {
|
||||
effectiveSegments = Array.isArray(lastMsg.segments)
|
||||
? lastMsg.segments
|
||||
: JSON.parse(lastMsg.segments);
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
const initialText = extractTextFromSegments(effectiveSegments);
|
||||
if (isMountedRef.current) {
|
||||
setDisplayText(initialText);
|
||||
}
|
||||
|
||||
const hasAtWithoutNickname = segments?.some(
|
||||
const hasAtWithoutNickname = effectiveSegments?.some(
|
||||
(s) => s.type === 'at' && s.data.user_id !== 'all' && !s.data.nickname
|
||||
);
|
||||
|
||||
if (hasAtWithoutNickname) {
|
||||
try {
|
||||
const asyncText = await extractTextFromSegmentsAsync(
|
||||
segments,
|
||||
effectiveSegments,
|
||||
userCacheRepository.get.bind(userCacheRepository),
|
||||
authService.getUserById.bind(authService)
|
||||
);
|
||||
@@ -79,7 +94,7 @@ const AsyncMessagePreview: React.FC<{
|
||||
return () => {
|
||||
isMountedRef.current = false;
|
||||
};
|
||||
}, [segments, status]);
|
||||
}, [segments, status, conversationId]);
|
||||
|
||||
if (!displayText) return null;
|
||||
|
||||
@@ -363,6 +378,7 @@ const ConversationListRowInner: React.FC<ConversationListRowProps> = ({
|
||||
status={item.last_message?.status}
|
||||
isGroupChat={isGroupChat}
|
||||
senderName={getSenderName()}
|
||||
conversationId={item.id}
|
||||
/>
|
||||
)}
|
||||
</Text>
|
||||
|
||||
Reference in New Issue
Block a user