mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-24 12:44:18 +08:00
feat(session-manager): highlight search keywords in session titles and messages
This commit is contained in:
@@ -15,6 +15,7 @@ import {
|
||||
getProviderIconName,
|
||||
getProviderLabel,
|
||||
getSessionKey,
|
||||
highlightText,
|
||||
} from "./utils";
|
||||
|
||||
interface SessionItemProps {
|
||||
@@ -23,6 +24,7 @@ interface SessionItemProps {
|
||||
selectionMode: boolean;
|
||||
isChecked: boolean;
|
||||
isCheckDisabled?: boolean;
|
||||
searchQuery?: string;
|
||||
onSelect: (key: string) => void;
|
||||
onToggleChecked: (checked: boolean) => void;
|
||||
}
|
||||
@@ -33,6 +35,7 @@ export function SessionItem({
|
||||
selectionMode,
|
||||
isChecked,
|
||||
isCheckDisabled = false,
|
||||
searchQuery,
|
||||
onSelect,
|
||||
onToggleChecked,
|
||||
}: SessionItemProps) {
|
||||
@@ -82,7 +85,9 @@ export function SessionItem({
|
||||
{getProviderLabel(session.providerId, t)}
|
||||
</TooltipContent>
|
||||
</Tooltip>
|
||||
<span className="text-sm font-medium truncate flex-1">{title}</span>
|
||||
<span className="text-sm font-medium truncate flex-1">
|
||||
{searchQuery ? highlightText(title, searchQuery) : title}
|
||||
</span>
|
||||
<ChevronRight
|
||||
className={cn(
|
||||
"size-4 text-muted-foreground/50 shrink-0 transition-transform",
|
||||
|
||||
@@ -769,6 +769,7 @@ export function SessionManagerPage({ appId }: { appId: string }) {
|
||||
session={session}
|
||||
isSelected={isSelected}
|
||||
selectionMode={selectionMode}
|
||||
searchQuery={search}
|
||||
isChecked={selectedSessionKeys.has(
|
||||
getSessionKey(session),
|
||||
)}
|
||||
@@ -1005,6 +1006,7 @@ export function SessionManagerPage({ appId }: { appId: string }) {
|
||||
message={message}
|
||||
index={index}
|
||||
isActive={activeMessageIndex === index}
|
||||
searchQuery={search}
|
||||
setRef={(el) => {
|
||||
if (el) messageRefs.current.set(index, el);
|
||||
}}
|
||||
|
||||
@@ -9,12 +9,18 @@ import {
|
||||
} from "@/components/ui/tooltip";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { SessionMessage } from "@/types";
|
||||
import { formatTimestamp, getRoleLabel, getRoleTone } from "./utils";
|
||||
import {
|
||||
formatTimestamp,
|
||||
getRoleLabel,
|
||||
getRoleTone,
|
||||
highlightText,
|
||||
} from "./utils";
|
||||
|
||||
interface SessionMessageItemProps {
|
||||
message: SessionMessage;
|
||||
index: number;
|
||||
isActive: boolean;
|
||||
searchQuery?: string;
|
||||
setRef: (el: HTMLDivElement | null) => void;
|
||||
onCopy: (content: string) => void;
|
||||
}
|
||||
@@ -22,6 +28,7 @@ interface SessionMessageItemProps {
|
||||
export function SessionMessageItem({
|
||||
message,
|
||||
isActive,
|
||||
searchQuery,
|
||||
setRef,
|
||||
onCopy,
|
||||
}: SessionMessageItemProps) {
|
||||
@@ -68,7 +75,9 @@ export function SessionMessageItem({
|
||||
)}
|
||||
</div>
|
||||
<div className="whitespace-pre-wrap break-words [overflow-wrap:anywhere] text-sm leading-relaxed min-w-0">
|
||||
{message.content}
|
||||
{searchQuery
|
||||
? highlightText(message.content, searchQuery)
|
||||
: message.content}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import type { ReactNode } from "react";
|
||||
import { createElement } from "react";
|
||||
import { SessionMeta } from "@/types";
|
||||
|
||||
export const getSessionKey = (session: SessionMeta) =>
|
||||
@@ -78,3 +80,23 @@ export const formatSessionTitle = (session: SessionMeta) => {
|
||||
session.sessionId.slice(0, 8)
|
||||
);
|
||||
};
|
||||
|
||||
export const highlightText = (text: string, query: string): ReactNode => {
|
||||
if (!query) return text;
|
||||
const escaped = query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
||||
const parts = text.split(new RegExp(`(${escaped})`, "gi"));
|
||||
if (parts.length === 1) return text;
|
||||
return parts.map((part, i) =>
|
||||
i % 2 === 1
|
||||
? createElement(
|
||||
"mark",
|
||||
{
|
||||
key: i,
|
||||
className:
|
||||
"bg-yellow-200/60 dark:bg-yellow-500/30 text-inherit rounded-sm px-0.5",
|
||||
},
|
||||
part,
|
||||
)
|
||||
: part,
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user