mirror of
https://github.com/enricoros/big-AGI.git
synced 2026-05-10 21:50:14 -07:00
Selective Search
This commit is contained in:
@@ -30,7 +30,7 @@ import { useUIPreferencesStore } from '~/common/state/store-ui';
|
||||
|
||||
import { ChatDrawerItemMemo, FolderChangeRequest } from './ChatDrawerItem';
|
||||
import { ChatFolderList } from './folders/ChatFolderList';
|
||||
import { ChatNavGrouping, ChatSearchSorting, isDrawerSearching, useChatDrawerRenderItems } from './useChatDrawerRenderItems';
|
||||
import { ChatNavGrouping, ChatSearchDepth, ChatSearchSorting, isDrawerSearching, useChatDrawerRenderItems } from './useChatDrawerRenderItems';
|
||||
import { ClearFolderText } from '../layout-bar/useFolderDropdown';
|
||||
import { useChatDrawerFilters } from '../../store-app-chat';
|
||||
|
||||
@@ -78,6 +78,7 @@ function ChatDrawer(props: {
|
||||
// local state
|
||||
const [navGrouping, setNavGrouping] = React.useState<ChatNavGrouping>('date');
|
||||
const [searchSorting, setSearchSorting] = React.useState<ChatSearchSorting>('date');
|
||||
const [searchDepth, setSearchDepth] = React.useState<ChatSearchDepth>('attachments'); // default: full search
|
||||
const [debouncedSearchQuery, setDebouncedSearchQuery] = React.useState('');
|
||||
const [folderChangeRequest, setFolderChangeRequest] = React.useState<FolderChangeRequest | null>(null);
|
||||
|
||||
@@ -92,7 +93,7 @@ function ChatDrawer(props: {
|
||||
} = useChatDrawerFilters();
|
||||
const { activeFolder, allFolders, enableFolders, toggleEnableFolders } = useFolders(props.activeFolderId);
|
||||
const { filteredChatsCount, filteredChatIDs, filteredChatsAreEmpty, filteredChatsBarBasis, filteredChatsIncludeActive, renderNavItems } = useChatDrawerRenderItems(
|
||||
props.activeConversationId, props.chatPanesConversationIds, debouncedSearchQuery, activeFolder, allFolders, filterHasStars, filterHasImageAssets, filterHasDocFragments, navGrouping, searchSorting, showRelativeSize,
|
||||
props.activeConversationId, props.chatPanesConversationIds, debouncedSearchQuery, activeFolder, allFolders, filterHasStars, filterHasImageAssets, filterHasDocFragments, navGrouping, searchSorting, showRelativeSize, searchDepth,
|
||||
);
|
||||
const [uiComplexityMode, contentScaling] = useUIPreferencesStore(useShallow((state) => [state.complexityMode, state.contentScaling]));
|
||||
const zenMode = uiComplexityMode === 'minimal';
|
||||
@@ -210,7 +211,7 @@ function ChatDrawer(props: {
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
) : (
|
||||
// While searching, show the sorting options
|
||||
// While searching, show the sorting and depth options
|
||||
<Menu placement='bottom-start' sx={{ minWidth: 180, zIndex: themeZIndexOverMobileDrawer /* need to be on top of the Modal on Mobile */ }}>
|
||||
<ListItem>
|
||||
<Typography level='body-sm'>Sort By</Typography>
|
||||
@@ -223,11 +224,27 @@ function ChatDrawer(props: {
|
||||
<ListItemDecorator>{searchSorting === 'date' && <CheckRoundedIcon />}</ListItemDecorator>
|
||||
Date
|
||||
</MenuItem>
|
||||
<ListDivider />
|
||||
<ListItem>
|
||||
<Typography level='body-sm'>Search In</Typography>
|
||||
</ListItem>
|
||||
<MenuItem selected={searchDepth === 'titles'} onClick={() => setSearchDepth('titles')}>
|
||||
<ListItemDecorator>{searchDepth === 'titles' && <CheckRoundedIcon />}</ListItemDecorator>
|
||||
Titles
|
||||
</MenuItem>
|
||||
<MenuItem selected={searchDepth === 'content'} onClick={() => setSearchDepth('content')}>
|
||||
<ListItemDecorator>{searchDepth === 'content' && <CheckRoundedIcon />}</ListItemDecorator>
|
||||
Titles + Content
|
||||
</MenuItem>
|
||||
<MenuItem selected={searchDepth === 'attachments'} onClick={() => setSearchDepth('attachments')}>
|
||||
<ListItemDecorator>{searchDepth === 'attachments' && <CheckRoundedIcon />}</ListItemDecorator>
|
||||
Full
|
||||
</MenuItem>
|
||||
</Menu>
|
||||
)}
|
||||
</Dropdown>
|
||||
), [
|
||||
filterHasDocFragments, filterHasImageAssets, filterHasStars, isSearching, navGrouping, searchSorting, showPersonaIcons, showRelativeSize,
|
||||
filterHasDocFragments, filterHasImageAssets, filterHasStars, isSearching, navGrouping, searchSorting, searchDepth, showPersonaIcons, showRelativeSize,
|
||||
toggleFilterHasDocFragments, toggleFilterHasImageAssets, toggleFilterHasStars, toggleShowPersonaIcons, toggleShowRelativeSize,
|
||||
]);
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ export type ChatNavGrouping = false | 'date' | 'persona' | 'dimension';
|
||||
|
||||
export type ChatSearchSorting = 'frequency' | 'date';
|
||||
|
||||
export type ChatSearchDepth = 'titles' | 'content' | 'attachments';
|
||||
|
||||
|
||||
function messageHasDocAttachmentFragments(message: DMessage): boolean {
|
||||
@@ -87,6 +88,7 @@ export function useChatDrawerRenderItems(
|
||||
grouping: ChatNavGrouping,
|
||||
searchSorting: ChatSearchSorting,
|
||||
showRelativeSize: boolean,
|
||||
searchDepth: ChatSearchDepth,
|
||||
): ChatDrawerRenderItems {
|
||||
|
||||
const stabilizeRenderItems = React.useRef<ChatDrawerRenderItems>();
|
||||
@@ -111,8 +113,8 @@ export function useChatDrawerRenderItems(
|
||||
let hasStars = false, hasImages = false, hasDocs = false;
|
||||
for (const _m of _c.messages) {
|
||||
_m.userFlags?.forEach(flag => messageFlags.add(flag));
|
||||
if (isSearching) {
|
||||
const messageText = messageFragmentsReduceText(_m.fragments, '\n');
|
||||
if (isSearching && searchDepth !== 'titles') {
|
||||
const messageText = messageFragmentsReduceText(_m.fragments, '\n', searchDepth !== 'attachments');
|
||||
if (messageText) lcMessageSearchText += messageText.toLowerCase() + '\n';
|
||||
}
|
||||
if (!hasStars && messageHasStarredFragments(_m)) hasStars = true;
|
||||
@@ -134,6 +136,7 @@ export function useChatDrawerRenderItems(
|
||||
const titleFrequency = title.toLowerCase().split(lcTextQuery).length - 1;
|
||||
const messageFrequency = lcMessageSearchText.split(lcTextQuery).length - 1;
|
||||
searchFrequency = titleFrequency + messageFrequency;
|
||||
if (searchFrequency === 0) return null;
|
||||
}
|
||||
|
||||
// union of message flags -> emoji string
|
||||
@@ -164,7 +167,7 @@ export function useChatDrawerRenderItems(
|
||||
searchFrequency,
|
||||
};
|
||||
})
|
||||
.filter(item => !!item && (!isSearching || item.searchFrequency > 0)) as ChatNavigationItemData[];
|
||||
.filter(item => !!item) as ChatNavigationItemData[];
|
||||
|
||||
// check if the active conversation has an item in the list
|
||||
const filteredChatsIncludeActive = chatNavItems.some(_c => _c.conversationId === activeConversationId);
|
||||
@@ -181,7 +184,7 @@ export function useChatDrawerRenderItems(
|
||||
if (isSearching) {
|
||||
|
||||
// start growing the render array from the nav array
|
||||
renderNavItems = [...chatNavItems]
|
||||
renderNavItems = [...chatNavItems];
|
||||
|
||||
// only prepend a 'Results' group if there are results
|
||||
if (chatNavItems.length)
|
||||
|
||||
@@ -233,7 +233,7 @@ export function messageSetUserFlag(message: Pick<DMessage, 'userFlags'>, flag: D
|
||||
|
||||
// helpers during the transition from V3
|
||||
|
||||
export function messageFragmentsReduceText(fragments: DMessageFragment[], fragmentSeparator: string = '\n\n'): string {
|
||||
export function messageFragmentsReduceText(fragments: DMessageFragment[], fragmentSeparator: string = '\n\n', excludeAttachmentFragments?: boolean): string {
|
||||
|
||||
return fragments
|
||||
.map(fragment => {
|
||||
@@ -253,6 +253,8 @@ export function messageFragmentsReduceText(fragments: DMessageFragment[], fragme
|
||||
}
|
||||
break;
|
||||
case isAttachmentFragment(fragment):
|
||||
if (excludeAttachmentFragments)
|
||||
return '';
|
||||
switch (fragment.part.pt) {
|
||||
case 'doc':
|
||||
return fragment.part.data.text;
|
||||
|
||||
Reference in New Issue
Block a user