Skip to content

Commit

Permalink
feat(search): Use proper editor API for search highlighting
Browse files Browse the repository at this point in the history
Signed-off-by: Elizabeth Danzberger <[email protected]>
  • Loading branch information
elzody committed Aug 11, 2024
1 parent 19b2f63 commit b4d0c7d
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 35 deletions.
4 changes: 3 additions & 1 deletion src/components/Page.vue
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
</h1>
<LandingPageWidgets v-if="isLandingPage" />
<TextEditor :key="`text-editor-${currentPage.id}`" ref="texteditor" />
<SearchDialog />
<SearchDialog :show="shouldShowSearchDialog" />
</div>
</template>

Expand All @@ -125,6 +125,7 @@ import { mapActions, mapState } from 'pinia'
import { useRootStore } from '../stores/root.js'
import { useCollectivesStore } from '../stores/collectives.js'
import { usePagesStore } from '../stores/pages.js'
import { useSearchStore } from '../stores/search.js'
import pageMixin from '../mixins/pageMixin.js'
import { showError } from '@nextcloud/dialogs'

Expand Down Expand Up @@ -175,6 +176,7 @@ export default {
'isTemplatePage',
'isLandingPage',
]),
...mapState(useSearchStore, ['shouldShowSearchDialog']),

hasSidebarToggle() {
return !this.showing('sidebar')
Expand Down
48 changes: 26 additions & 22 deletions src/components/SearchDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
-->

<template>
<div v-if="totalMatches !== null" class="search-dialog__container">
<div v-if="shouldShow" class="search-dialog__container">
<div class="search-dialog__buttons">
<NcButton alignment="center-reverse"
type="tertiary"
Expand Down Expand Up @@ -38,15 +38,15 @@
<div class="search-dialog__info">
<span v-if="matchAll">
{{ t('collectives', 'Found {matches} matches for "{query}"', {
matches: totalMatches,
matches: results.totalMatches ?? 0,
query: searchQuery,
}) }}
</span>

<span v-else>
{{ t('collectives', 'Match {index} of {matches} for "{query}"', {
index: matchIndex + 1,
matches: totalMatches,
index: results.matchIndex + 1,
matches: results.totalMatches,
query: searchQuery,
}) }}
</span>
Expand All @@ -61,7 +61,6 @@
</template>

<script>
import { subscribe } from '@nextcloud/event-bus'
import { NcButton, NcCheckboxRadioSwitch } from '@nextcloud/vue'
import { translate as t } from '@nextcloud/l10n'
import { mapActions, mapState } from 'pinia'
Expand All @@ -81,16 +80,23 @@ export default {
Close,
},

props: {
show: {
type: Boolean,
default: false,
},
},

data() {
return {
totalMatches: null,
matchIndex: 0,
}
return {}
},

computed: {
...mapState(useSearchStore, ['searchQuery', 'matchAll']),

...mapState(useSearchStore, [
'searchQuery',
'matchAll',
'results',
]),
isHighlightAllChecked: {
get() {
return this.matchAll
Expand All @@ -99,36 +105,34 @@ export default {
this.toggleMatchAll()
},
},
},

created() {
subscribe('text:editor:search-results', ({ results, index }) => {
this.totalMatches = results
this.matchIndex = index
})
shouldShow() {
return this.show && this.results.totalMatches !== null
},
},

methods: {
t,
...mapActions(useSearchStore, [
'setSearchQuery',
'toggleMatchAll',
'nextSearch',
'previousSearch',
'showSearchDialog',
'searchNext',
'searchPrevious',
]),

previous() {
this.previousSearch()
this.searchPrevious()
this.scrollIntoView()
},

next() {
this.nextSearch()
this.searchNext()
this.scrollIntoView()
},

clearSearch() {
this.setSearchQuery('')
this.showSearchDialog(false)
},

scrollIntoView() {
Expand Down
35 changes: 29 additions & 6 deletions src/mixins/editorMixin.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { useSearchStore } from '../stores/search.js'
import linkHandlerMixin from '../mixins/linkHandlerMixin.js'
import PageInfoBar from '../components/Page/PageInfoBar.vue'
import { editorApiReaderFileId } from '../constants.js'
import { emit } from '@nextcloud/event-bus'
import { subscribe } from '@nextcloud/event-bus'

export default {
mixins: [
Expand All @@ -37,8 +37,8 @@ export default {
'shareTokenParam',
'showing',
]),
...mapState(useSearchStore, ['searchQuery', 'matchAll']),
...mapState(useCollectivesStore, ['currentCollectiveCanEdit']),
...mapState(useSearchStore, ['searchQuery']),
...mapState(usePagesStore, ['currentPage', 'pageFilePath']),

pageContent() {
Expand All @@ -62,11 +62,33 @@ export default {
},
},

created() {
subscribe('collectives:next-search', () => {
this.editor?.searchNext()
this.reader?.searchNext()
})

subscribe('collectives:previous-search', () => {
this.editor?.searchPrevious()
this.reader?.searchPrevious()
})
},

watch: {
'showOutline'(value) {
this.editor?.setShowOutline(value)
this.reader?.setShowOutline(value)
},
'searchQuery'(value) {
this.editor?.setSearchQuery(value)
this.reader?.setSearchQuery(value)
},
'matchAll'(newValue, oldValue) {
if (newValue !== oldValue) {
this.editor?.setSearchQuery(this.searchQuery, newValue)
this.reader?.setSearchQuery(this.searchQuery, newValue)
}
},
},

beforeDestroy() {
Expand All @@ -76,6 +98,7 @@ export default {

methods: {
...mapActions(useRootStore, ['done', 'hide', 'show']),
...mapActions(useSearchStore, ['showSearchDialog', 'setSearchResults']),

async setupReader() {
const fileId = this.editorApiFlags.includes(editorApiReaderFileId)
Expand Down Expand Up @@ -107,10 +130,10 @@ export default {
const element = document.querySelector(`[href="${document.location.hash}"]`)
element?.click()
}

if (this.searchQuery && this.searchQuery !== '') {
emit('text:editor:search', { query: this.searchQuery })
}
},
onSearch: (results) => {
this.setSearchResults(results)
this.showSearchDialog(true)
},
})

Expand Down
18 changes: 12 additions & 6 deletions src/stores/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,30 @@ export const useSearchStore = defineStore('search', {
state: () => ({
searchQuery: '',
matchAll: true,
shouldShowSearchDialog: false,
results: null,
}),

actions: {
setSearchQuery(query) {
this.searchQuery = query
emit('text:editor:search', { query: this.searchQuery, matchAll: this.matchAll })
},
showSearchDialog(value) {
this.shouldShowSearchDialog = value
},
toggleMatchAll() {
this.matchAll = !this.matchAll
emit('text:editor:search', { query: this.searchQuery, matchAll: this.matchAll })
},
nextSearch() {
setSearchResults(results) {
this.results = results
},
searchNext() {
emit('collectives:next-search')
this.matchAll = false
emit('text:editor:search-next', {})
},
previousSearch() {
searchPrevious() {
emit('collectives:previous-search')
this.matchAll = false
emit('text:editor:search-previous', {})
},
},
})

0 comments on commit b4d0c7d

Please sign in to comment.