This commit is contained in:
Simon Cambier
2022-09-21 13:11:30 +02:00
parent 5b64f54aa4
commit 60de958d72
6 changed files with 116 additions and 59 deletions

View File

@@ -29,3 +29,22 @@
.omnisearch-highlight { .omnisearch-highlight {
} }
.omnisearch-input-container {
display: flex;
flex-direction: row;
gap: 5px;
}
.omnisearch-input-field {
position: relative;
flex-grow: 1;
}
.omnisearch-input__context {
position: absolute;
right: 1em;
top: calc(50% - 0.75em);
color: var(--text-faint);
font-size: small;
}

View File

@@ -4,6 +4,7 @@
import { createEventDispatcher, onMount, tick } from 'svelte' import { createEventDispatcher, onMount, tick } from 'svelte'
export let value = '' export let value = ''
export let label = ''
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
let elInput: HTMLInputElement let elInput: HTMLInputElement
@@ -22,13 +23,22 @@
}, 100) }, 100)
</script> </script>
<div class="omnisearch-input-container">
<div class="omnisearch-input-field">
<input <input
bind:value bind:value
bind:this={elInput} bind:this="{elInput}"
on:input={debouncedOnInput} on:input="{debouncedOnInput}"
on:compositionstart={_ => toggleInputComposition(true)} on:compositionstart="{_ => toggleInputComposition(true)}"
on:compositionend={_ => toggleInputComposition(false)} on:compositionend="{_ => toggleInputComposition(false)}"
type="text" type="text"
class="prompt-input" class="prompt-input"
placeholder="Type to search through your notes" placeholder="Type to search through your notes"
spellcheck="false" /> spellcheck="false" />
<span class="omnisearch-input__context">
{label}
</span>
</div>
<slot></slot>
</div>

View File

@@ -140,9 +140,10 @@
} }
</script> </script>
<div class="modal-title">Omnisearch - File</div> <InputSearch
<div class="modal-content"> value={searchQuery}
<InputSearch value={searchQuery} on:input={e => (searchQuery = e.detail)} /> on:input={e => (searchQuery = e.detail)}
label="Omnisearch - File" />
<ModalContainer> <ModalContainer>
{#if groupedOffsets.length && note} {#if groupedOffsets.length && note}
@@ -161,7 +162,6 @@
</div> </div>
{/if} {/if}
</ModalContainer> </ModalContainer>
</div>
<div class="prompt-instructions"> <div class="prompt-instructions">
<div class="prompt-instruction"> <div class="prompt-instruction">

View File

@@ -11,7 +11,7 @@
import ResultItemVault from './ResultItemVault.svelte' import ResultItemVault from './ResultItemVault.svelte'
import { Query } from 'src/query' import { Query } from 'src/query'
import { saveSearchHistory, searchHistory } from 'src/search-history' import { saveSearchHistory, searchHistory } from 'src/search-history'
import { settings } from 'src/settings' import { settings } from '../settings'
export let modal: OmnisearchVaultModal export let modal: OmnisearchVaultModal
let selectedIndex = 0 let selectedIndex = 0
@@ -53,6 +53,7 @@
} }
searchQuery = searchHistory[historySearchIndex] searchQuery = searchHistory[historySearchIndex]
} }
function nextSearchHistory() { function nextSearchHistory() {
if (--historySearchIndex < 0) { if (--historySearchIndex < 0) {
historySearchIndex = searchHistory.length ? searchHistory.length - 1 : 0 historySearchIndex = searchHistory.length ? searchHistory.length - 1 : 0
@@ -66,7 +67,7 @@
(a, b) => b.score - a.score (a, b) => b.score - a.score
) )
selectedIndex = 0 selectedIndex = 0
scrollIntoView() await scrollIntoView()
} }
function onClick(evt?: MouseEvent | KeyboardEvent) { function onClick(evt?: MouseEvent | KeyboardEvent) {
@@ -167,23 +168,29 @@
} }
</script> </script>
<div class="modal-title">Omnisearch - Vault</div> <InputSearch
<div class="modal-content"> value="{searchQuery}"
<InputSearch value={searchQuery} on:input={e => (searchQuery = e.detail)} /> on:input="{e => (searchQuery = e.detail)}"
label="Omnisearch - Vault">
{#if $settings.showCreateButton}
<button on:click="{createNoteAndCloseModal}">Create note</button>
{/if}
</InputSearch>
<ModalContainer> <ModalContainer>
{#each resultNotes as result, i} {#each resultNotes as result, i}
<ResultItemVault <ResultItemVault
selected={i === selectedIndex} selected="{i === selectedIndex}"
note={result} note="{result}"
on:mousemove={e => (selectedIndex = i)} on:mousemove="{_ => (selectedIndex = i)}"
on:click={onClick} /> on:click="{onClick}" />
{/each} {/each}
{#if !resultNotes.length && searchQuery} {#if !resultNotes.length && searchQuery}
<center> We found 0 result for your search here. </center> <div style="text-align: center;">
We found 0 result for your search here.
</div>
{/if} {/if}
</ModalContainer> </ModalContainer>
</div>
<div class="prompt-instructions"> <div class="prompt-instructions">
<div class="prompt-instruction"> <div class="prompt-instruction">

View File

@@ -1,4 +1,4 @@
import { App, Modal, TFile, Platform } from 'obsidian' import { App, Modal, TFile } from 'obsidian'
import ModalVault from './components/ModalVault.svelte' import ModalVault from './components/ModalVault.svelte'
import ModalInFile from './components/ModalInFile.svelte' import ModalInFile from './components/ModalInFile.svelte'
import { eventBus, isInputComposition } from './globals' import { eventBus, isInputComposition } from './globals'
@@ -6,14 +6,14 @@ import { settings } from './settings'
import { get } from 'svelte/store' import { get } from 'svelte/store'
abstract class OmnisearchModal extends Modal { abstract class OmnisearchModal extends Modal {
constructor(app: App) { protected constructor(app: App) {
super(app) super(app)
// Remove all the default modal's children // Remove all the default modal's children
// so that we can more easily customize it // so that we can more easily customize it
const closeEl = this.containerEl.find('.modal-close-button') // const closeEl = this.containerEl.find('.modal-close-button')
this.modalEl.replaceChildren() this.modalEl.replaceChildren()
this.modalEl.append(closeEl) // this.modalEl.append(closeEl)
this.modalEl.addClass('omnisearch-modal', 'prompt') this.modalEl.addClass('omnisearch-modal', 'prompt')
// this.modalEl.removeClass('modal') // this.modalEl.removeClass('modal')
this.modalEl.tabIndex = -1 this.modalEl.tabIndex = -1

View File

@@ -1,7 +1,7 @@
import { Plugin, PluginSettingTab, Setting, SliderComponent } from 'obsidian' import { Plugin, PluginSettingTab, Setting, SliderComponent } from 'obsidian'
import { notesCacheFilePath, searchIndexFilePath } from './globals' import { notesCacheFilePath, searchIndexFilePath } from './globals'
import type OmnisearchPlugin from './main' import type OmnisearchPlugin from './main'
import { get, readable, writable } from 'svelte/store' import { get, writable } from 'svelte/store'
interface WeightingSettings { interface WeightingSettings {
weightBasename: number weightBasename: number
@@ -17,6 +17,7 @@ export interface OmnisearchSettings extends WeightingSettings {
ribbonIcon: boolean ribbonIcon: boolean
showShortName: boolean showShortName: boolean
showContext: boolean showContext: boolean
showCreateButton: boolean
CtrlJK: boolean CtrlJK: boolean
CtrlNP: boolean CtrlNP: boolean
storeIndexInFile: boolean storeIndexInFile: boolean
@@ -61,8 +62,7 @@ export class SettingsTab extends PluginSettingTab {
const diacriticsDesc = new DocumentFragment() const diacriticsDesc = new DocumentFragment()
diacriticsDesc.createSpan({}, span => { diacriticsDesc.createSpan({}, span => {
span.innerHTML = `Normalize diacritics in search terms. Words like "brûlée" or "žluťoučký" will be indexed as "brulee" and "zlutoucky".<br/> span.innerHTML = `Normalize diacritics in search terms. Words like "brûlée" or "žluťoučký" will be indexed as "brulee" and "zlutoucky".<br/>
<strong>Needs a restart to fully take effect.</strong> <strong>Needs a restart to fully take effect.</strong>`
`
}) })
new Setting(containerEl) new Setting(containerEl)
.setName('Ignore diacritics') .setName('Ignore diacritics')
@@ -77,6 +77,7 @@ export class SettingsTab extends PluginSettingTab {
}) })
) )
// Store index
const serializedIndexDesc = new DocumentFragment() const serializedIndexDesc = new DocumentFragment()
serializedIndexDesc.createSpan({}, span => { serializedIndexDesc.createSpan({}, span => {
span.innerHTML = `The search index is stored on disk, instead of being rebuilt at every startup. span.innerHTML = `The search index is stored on disk, instead of being rebuilt at every startup.
@@ -91,8 +92,8 @@ export class SettingsTab extends PluginSettingTab {
.setDesc(serializedIndexDesc) .setDesc(serializedIndexDesc)
.addToggle(toggle => .addToggle(toggle =>
toggle.setValue(get(settings).storeIndexInFile).onChange(async v => { toggle.setValue(get(settings).storeIndexInFile).onChange(async v => {
app.vault.adapter.remove(notesCacheFilePath) await app.vault.adapter.remove(notesCacheFilePath)
app.vault.adapter.remove(searchIndexFilePath) await app.vault.adapter.remove(searchIndexFilePath)
settings.update(s => { settings.update(s => {
s.storeIndexInFile = v s.storeIndexInFile = v
return s return s
@@ -145,10 +146,29 @@ export class SettingsTab extends PluginSettingTab {
}) })
) )
// Show "Create note" button
const createBtnDesc = new DocumentFragment()
createBtnDesc.createSpan({}, span => {
span.innerHTML = `Shows a button next to the search input, to create a note.
Acts the same as the <code>shift ↵</code> shortcut, can be useful for mobile device users.`
})
new Setting(containerEl)
.setName('Show "Create note" button')
.setDesc(createBtnDesc)
.addToggle(toggle =>
toggle.setValue(get(settings).showCreateButton).onChange(async v => {
settings.update(s => {
s.showCreateButton = v
return s
})
await saveSettings(this.plugin)
})
)
// Show notices // Show notices
new Setting(containerEl) new Setting(containerEl)
.setName('Show indexing notices') .setName('Show indexing notices')
.setDesc('Show a notice when indexing is done, usually at startup.') .setDesc('Shows a notice when indexing is done, usually at startup.')
.addToggle(toggle => .addToggle(toggle =>
toggle.setValue(get(settings).showIndexingNotices).onChange(async v => { toggle.setValue(get(settings).showIndexingNotices).onChange(async v => {
settings.update(s => { settings.update(s => {
@@ -258,6 +278,7 @@ export const DEFAULT_SETTINGS: OmnisearchSettings = {
showShortName: false, showShortName: false,
ribbonIcon: true, ribbonIcon: true,
showContext: true, showContext: true,
showCreateButton: false,
weightBasename: 2, weightBasename: 2,
weightH1: 1.5, weightH1: 1.5,