mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-11-04 15:11:31 +08:00 
			
		
		
		
	Merge pull request #659 from TriliumNext/quick_search_in_autocomplete
Add full text search in autocomplete
This commit is contained in:
		
						commit
						29b062660d
					
				@ -30,10 +30,22 @@ async function autocompleteSourceForCKEditor(queryText) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function autocompleteSource(term, cb, options = {}) {
 | 
			
		||||
    const fastSearch = options.fastSearch === false ? false : true;
 | 
			
		||||
    if (fastSearch === false) {
 | 
			
		||||
        if (term.trim().length === 0){
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        cb(
 | 
			
		||||
            [{
 | 
			
		||||
                noteTitle: term,
 | 
			
		||||
                highlightedNotePathTitle: `Searching...`
 | 
			
		||||
            }]
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    const activeNoteId = appContext.tabManager.getActiveContextNoteId();
 | 
			
		||||
 | 
			
		||||
    let results = await server.get(`autocomplete?query=${encodeURIComponent(term)}&activeNoteId=${activeNoteId}`);
 | 
			
		||||
 | 
			
		||||
    let results = await server.get(`autocomplete?query=${encodeURIComponent(term)}&activeNoteId=${activeNoteId}&fastSearch=${fastSearch}`);
 | 
			
		||||
    if (term.trim().length >= 1 && options.allowCreatingNotes) {
 | 
			
		||||
        results = [
 | 
			
		||||
            {
 | 
			
		||||
@ -45,7 +57,7 @@ async function autocompleteSource(term, cb, options = {}) {
 | 
			
		||||
        ].concat(results);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (term.trim().length >= 1 && options.allowSearchNotes) {
 | 
			
		||||
    if (term.trim().length >= 1 && options.allowJumpToSearchNotes) {
 | 
			
		||||
        results = results.concat([
 | 
			
		||||
            {
 | 
			
		||||
                action: 'search-notes',
 | 
			
		||||
@ -95,12 +107,22 @@ function showRecentNotes($el) {
 | 
			
		||||
 | 
			
		||||
    $el.setSelectedNotePath("");
 | 
			
		||||
    $el.autocomplete("val", "");
 | 
			
		||||
    $el.autocomplete('open');
 | 
			
		||||
    $el.trigger('focus');
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    // simulate pressing down arrow to trigger autocomplete
 | 
			
		||||
    const e = $.Event('keydown');
 | 
			
		||||
    e.which = 40; // arrow down
 | 
			
		||||
    $el.trigger(e);
 | 
			
		||||
function fullTextSearch($el, options){
 | 
			
		||||
    const searchString = $el.autocomplete('val');
 | 
			
		||||
    if (options.fastSearch === false || searchString.trim().length === 0) {
 | 
			
		||||
        return;
 | 
			
		||||
    }    
 | 
			
		||||
    $el.trigger('focus');
 | 
			
		||||
    options.fastSearch = false;
 | 
			
		||||
    $el.autocomplete('val', '');
 | 
			
		||||
    $el.setSelectedNotePath("");
 | 
			
		||||
    $el.autocomplete('val', searchString);
 | 
			
		||||
    // Set a delay to avoid resetting to true before full text search (await server.get) is called.
 | 
			
		||||
    setTimeout(() => { options.fastSearch = true; }, 100);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function initNoteAutocomplete($el, options) {
 | 
			
		||||
@ -123,10 +145,14 @@ function initNoteAutocomplete($el, options) {
 | 
			
		||||
        .addClass("input-group-text show-recent-notes-button bx bx-time")
 | 
			
		||||
        .prop("title", "Show recent notes");
 | 
			
		||||
 | 
			
		||||
    const $fullTextSearchButton = $("<button>")
 | 
			
		||||
        .addClass("input-group-text full-text-search-button bx bx-search")
 | 
			
		||||
        .prop("title", "Full text search (Shift+Enter)");    
 | 
			
		||||
 | 
			
		||||
    const $goToSelectedNoteButton = $("<button>")
 | 
			
		||||
        .addClass("input-group-text go-to-selected-note-button bx bx-arrow-to-right");
 | 
			
		||||
 | 
			
		||||
    $el.after($clearTextButton).after($showRecentNotesButton);
 | 
			
		||||
    $el.after($clearTextButton).after($showRecentNotesButton).after($fullTextSearchButton);
 | 
			
		||||
 | 
			
		||||
    if (!options.hideGoToSelectedNoteButton) {
 | 
			
		||||
        $el.after($goToSelectedNoteButton);
 | 
			
		||||
@ -142,13 +168,18 @@ function initNoteAutocomplete($el, options) {
 | 
			
		||||
        return false;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $fullTextSearchButton.on('click', e => {
 | 
			
		||||
        fullTextSearch($el, options);
 | 
			
		||||
        return false;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    let autocompleteOptions = {};
 | 
			
		||||
    if (options.container) {
 | 
			
		||||
        autocompleteOptions.dropdownMenuContainer = options.container;
 | 
			
		||||
        autocompleteOptions.debug = true;   // don't close on blur
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (options.allowSearchNotes) {
 | 
			
		||||
    if (options.allowJumpToSearchNotes) {
 | 
			
		||||
        $el.on('keydown', (event) => {
 | 
			
		||||
            if (event.ctrlKey && event.key === 'Enter') {
 | 
			
		||||
                // Prevent Ctrl + Enter from triggering autoComplete.
 | 
			
		||||
@ -158,6 +189,14 @@ function initNoteAutocomplete($el, options) {
 | 
			
		||||
            }
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
    $el.on('keydown', async (event) => {
 | 
			
		||||
        if (event.shiftKey && event.key === 'Enter') {
 | 
			
		||||
            // Prevent Enter from triggering autoComplete.
 | 
			
		||||
            event.stopImmediatePropagation();
 | 
			
		||||
            event.preventDefault();
 | 
			
		||||
            fullTextSearch($el,options)
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
    
 | 
			
		||||
    $el.autocomplete({
 | 
			
		||||
        ...autocompleteOptions,
 | 
			
		||||
 | 
			
		||||
@ -58,7 +58,7 @@ export default class JumpToNoteDialog extends BasicWidget {
 | 
			
		||||
        noteAutocompleteService.initNoteAutocomplete(this.$autoComplete, {
 | 
			
		||||
            allowCreatingNotes: true,
 | 
			
		||||
            hideGoToSelectedNoteButton: true,
 | 
			
		||||
            allowSearchNotes: true,
 | 
			
		||||
            allowJumpToSearchNotes: true,
 | 
			
		||||
            container: this.$results
 | 
			
		||||
        })
 | 
			
		||||
            // clear any event listener added in previous invocation of this function
 | 
			
		||||
 | 
			
		||||
@ -70,7 +70,7 @@ export default class EmptyTypeWidget extends TypeWidget {
 | 
			
		||||
        noteAutocompleteService.initNoteAutocomplete(this.$autoComplete, {
 | 
			
		||||
            hideGoToSelectedNoteButton: true,
 | 
			
		||||
            allowCreatingNotes: true,
 | 
			
		||||
            allowSearchNotes: true,
 | 
			
		||||
            allowJumpToSearchNotes: true,
 | 
			
		||||
            container: this.$results
 | 
			
		||||
        })
 | 
			
		||||
            .on('autocomplete:noteselected', function(event, suggestion, dataset) {
 | 
			
		||||
 | 
			
		||||
@ -448,7 +448,7 @@ pre:not(.CodeMirror-line):not(.hljs) {
 | 
			
		||||
    padding-top: 8px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.show-recent-notes-button {
 | 
			
		||||
.show-recent-notes-button, .full-text-search-button {
 | 
			
		||||
    cursor: pointer;
 | 
			
		||||
    font-size: 1.3em;
 | 
			
		||||
    padding-left: 5px;
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,8 @@ function getAutocomplete(req: Request) {
 | 
			
		||||
        throw new ValidationError("Invalid query data type.");
 | 
			
		||||
    }
 | 
			
		||||
    const query = (req.query.query || "").trim();
 | 
			
		||||
    const fastSearch = String(req.query.fastSearch).toLowerCase() === "false" ? false : true;
 | 
			
		||||
    
 | 
			
		||||
    const activeNoteId = req.query.activeNoteId || 'none';
 | 
			
		||||
 | 
			
		||||
    let results;
 | 
			
		||||
@ -24,7 +26,7 @@ function getAutocomplete(req: Request) {
 | 
			
		||||
        results = getRecentNotes(activeNoteId);
 | 
			
		||||
    }
 | 
			
		||||
    else {
 | 
			
		||||
        results = searchService.searchNotesForAutocomplete(query);
 | 
			
		||||
        results = searchService.searchNotesForAutocomplete(query, fastSearch);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    const msTaken = Date.now() - timestampStarted;
 | 
			
		||||
 | 
			
		||||
@ -340,9 +340,9 @@ function findFirstNoteWithQuery(query: string, searchContext: SearchContext): BN
 | 
			
		||||
    return searchResults.length > 0 ? becca.notes[searchResults[0].noteId] : null;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function searchNotesForAutocomplete(query: string) {
 | 
			
		||||
function searchNotesForAutocomplete(query: string, fastSearch: boolean = true) {
 | 
			
		||||
    const searchContext = new SearchContext({
 | 
			
		||||
        fastSearch: true,
 | 
			
		||||
        fastSearch: fastSearch,
 | 
			
		||||
        includeArchivedNotes: false,
 | 
			
		||||
        includeHiddenNotes: true,
 | 
			
		||||
        fuzzyAttributeSearch: true,
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user