Files
frontend/src/components/common/HighlightText.tsx
lan d8d2b03f94
Some checks failed
Frontend CI / ota-android (push) Successful in 1m19s
Frontend CI / ota-ios (push) Successful in 1m50s
Frontend CI / build-and-push-web (push) Successful in 3m28s
Frontend CI / build-android-apk (push) Failing after 8m56s
feat(message): implement message search functionality
Add ability to search messages within a specific conversation. This includes:
- New `MessageSearchScreen` for displaying search results.
- `MessageRepository.searchByConversation` to query messages by keyword and conversation ID.
- Integration of search entry points in `GroupInfoScreen` and `PrivateChatInfoScreen`.
- Support for scrolling to a specific message sequence (`scrollToSeq`) when navigating from search results.
- Enhanced `HighlightText` component to support custom highlight styles.

feat(message): implement message search functionality
2026-05-14 02:26:32 +08:00

54 lines
1.5 KiB
TypeScript

import React, { useMemo } from 'react';
import { Text, TextStyle, StyleProp } from 'react-native';
interface HighlightTextProps {
text: string;
keyword: string;
style?: StyleProp<TextStyle>;
highlightStyle?: StyleProp<TextStyle>;
}
const HighlightText: React.FC<HighlightTextProps> = ({ text, keyword, style, highlightStyle }) => {
const parts = useMemo(() => {
if (!text || !keyword) return [{ text, highlight: false }];
const result: Array<{ text: string; highlight: boolean }> = [];
const lowerText = text.toLowerCase();
const lowerKeyword = keyword.toLowerCase();
let lastIndex = 0;
let searchFrom = 0;
while (searchFrom < lowerText.length) {
const index = lowerText.indexOf(lowerKeyword, searchFrom);
if (index === -1) break;
if (index > lastIndex) {
result.push({ text: text.substring(lastIndex, index), highlight: false });
}
result.push({ text: text.substring(index, index + keyword.length), highlight: true });
lastIndex = index + keyword.length;
searchFrom = lastIndex;
}
if (lastIndex < text.length) {
result.push({ text: text.substring(lastIndex), highlight: false });
}
return result.length > 0 ? result : [{ text, highlight: false }];
}, [text, keyword]);
return (
<Text style={style}>
{parts.map((part, i) =>
part.highlight ? (
<Text key={i} style={highlightStyle}>{part.text}</Text>
) : (
<Text key={i}>{part.text}</Text>
)
)}
</Text>
);
};
export default HighlightText;