mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-05-23 22:20:23 +09:00
feat: model selection add search input
This commit is contained in:
parent
e3600f5acb
commit
6593e05fcb
@ -96,6 +96,7 @@ import {
|
||||
List,
|
||||
ListItem,
|
||||
Modal,
|
||||
SearchSelector,
|
||||
Selector,
|
||||
showConfirm,
|
||||
showPrompt,
|
||||
@ -678,7 +679,7 @@ export function ChatActions(props: {
|
||||
/>
|
||||
|
||||
{showModelSelector && (
|
||||
<Selector
|
||||
<SearchSelector
|
||||
defaultSelectedValue={`${currentModel}@${currentProviderName}`}
|
||||
items={models.map((m) => ({
|
||||
title: `${m.displayName}${
|
||||
|
@ -311,4 +311,21 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-search {
|
||||
border-bottom: 1px solid var(--gray-200);
|
||||
}
|
||||
|
||||
&-search-input {
|
||||
width: 100% !important;
|
||||
max-width: 100% !important;
|
||||
padding: 8px 12px;
|
||||
border: none;
|
||||
outline: none;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
&-search-input:focus {
|
||||
background-color: var(--gray-50);
|
||||
}
|
||||
}
|
||||
|
@ -465,7 +465,108 @@ export function showImageModal(
|
||||
),
|
||||
});
|
||||
}
|
||||
export function SearchSelector<T>(props: {
|
||||
items: Array<{
|
||||
title: string;
|
||||
subTitle?: string;
|
||||
value: T;
|
||||
disable?: boolean;
|
||||
}>;
|
||||
defaultSelectedValue?: T[] | T;
|
||||
onSelection?: (selection: T[]) => void;
|
||||
onClose?: () => void;
|
||||
multiple?: boolean;
|
||||
}) {
|
||||
const [selectedValues, setSelectedValues] = useState<T[]>(
|
||||
Array.isArray(props.defaultSelectedValue)
|
||||
? props.defaultSelectedValue
|
||||
: props.defaultSelectedValue !== undefined
|
||||
? [props.defaultSelectedValue]
|
||||
: [],
|
||||
);
|
||||
|
||||
// 添加搜索状态
|
||||
const [searchQuery, setSearchQuery] = useState("");
|
||||
|
||||
const handleSelection = (e: MouseEvent, value: T) => {
|
||||
if (props.multiple) {
|
||||
e.stopPropagation();
|
||||
const newSelectedValues = selectedValues.includes(value)
|
||||
? selectedValues.filter((v) => v !== value)
|
||||
: [...selectedValues, value];
|
||||
setSelectedValues(newSelectedValues);
|
||||
props.onSelection?.(newSelectedValues);
|
||||
} else {
|
||||
setSelectedValues([value]);
|
||||
props.onSelection?.([value]);
|
||||
props.onClose?.();
|
||||
}
|
||||
};
|
||||
|
||||
// 过滤列表项
|
||||
const filteredItems = props.items.filter(
|
||||
(item) =>
|
||||
item.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
||||
(item.subTitle &&
|
||||
item.subTitle.toLowerCase().includes(searchQuery.toLowerCase())),
|
||||
);
|
||||
|
||||
return (
|
||||
<div className={styles["selector"]} onClick={() => props.onClose?.()}>
|
||||
<div
|
||||
className={styles["selector-content"]}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<List>
|
||||
{/* 搜索框 */}
|
||||
<div className={styles["selector-search"]}>
|
||||
<input
|
||||
type="text"
|
||||
className={styles["selector-search-input"]}
|
||||
placeholder="search model"
|
||||
value={searchQuery}
|
||||
onChange={(e) => setSearchQuery(e.target.value)}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
/>
|
||||
</div>
|
||||
{filteredItems.map((item, i) => {
|
||||
const selected = selectedValues.includes(item.value);
|
||||
return (
|
||||
<ListItem
|
||||
className={`${styles["selector-item"]} ${
|
||||
item.disable && styles["selector-item-disabled"]
|
||||
}`}
|
||||
key={i}
|
||||
title={item.title}
|
||||
subTitle={item.subTitle}
|
||||
onClick={(e) => {
|
||||
if (item.disable) {
|
||||
e.stopPropagation();
|
||||
} else {
|
||||
handleSelection(e, item.value);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{selected ? (
|
||||
<div
|
||||
style={{
|
||||
height: 10,
|
||||
width: 10,
|
||||
backgroundColor: "var(--primary)",
|
||||
borderRadius: 10,
|
||||
}}
|
||||
></div>
|
||||
) : (
|
||||
<></>
|
||||
)}
|
||||
</ListItem>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
export function Selector<T>(props: {
|
||||
items: Array<{
|
||||
title: string;
|
||||
|
Loading…
Reference in New Issue
Block a user