Skip to content

Commit

Permalink
feat: add support for histories (#210)
Browse files Browse the repository at this point in the history
  • Loading branch information
razonyang authored Feb 19, 2024
1 parent 88d6d7d commit 4e28dfa
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 5 deletions.
14 changes: 13 additions & 1 deletion assets/search/js/form.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import i18n from './i18n'
import Renderer from './renderer'
import engine from './engine'
import Spinner from './spinner'
import { default as Historiographer } from './historiographer'

export default class Form {
// Original page title.
Expand Down Expand Up @@ -174,6 +175,10 @@ export default class Form {
this.input.addEventListener('search', () => {
this.submit()
})
document.addEventListener('search:input:change', (e) => {
this.input.value = e.detail.value
this.submit()
})

this.language = this.ele.querySelector('.search-filter-lang') as HTMLElement
this.language?.addEventListener('change', () => {
Expand Down Expand Up @@ -243,14 +248,21 @@ export default class Form {
const query = this.getQuery()
this.updatePage(query)

this.spinner.show()
const sorting = this.getSorting()
const lang = this.getLanguage()
const years = this.getYears()
const taxonomies = this.getTaxonomies()

if (query === '' && Object.values(taxonomies).filter((item) => item.length > 0).length == 0) {
this.renderer.renderHistories()
return
}

this.spinner.show()
engine.search(query, sorting, lang, years, taxonomies).then(({ results, time }) => {
this.renderer.render(query, results, time)
}).finally(() => {
Historiographer.save(query)
this.spinner.hide()
})
}
Expand Down
35 changes: 35 additions & 0 deletions assets/search/js/historiographer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import params from '@params'

class Historiographer {
private key = 'search-histories'

get() {
let histories = JSON.parse(localStorage.getItem(this.key) ?? '[]')
if (!(histories instanceof Array)) {
histories = []
}

return histories.slice(0, params.historiesCount)
}

save(query: string): void {
if (query === '') {
return
}

let histories = this.get()
histories = histories.filter((history) => history.query !== query)
histories.unshift({
query: query,
date: (new Date()),
})

if (histories.length > params.historiesCount) {
histories.pop()
}

localStorage.setItem(this.key, JSON.stringify(histories))
}
}

export default (new Historiographer())
7 changes: 5 additions & 2 deletions assets/search/js/modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@ export default class Modal {

private container: HTMLElement

private renderer: Renderer

private form: Form

private shortcuts: Shortcuts

constructor() {
const spinner = new Spinner('.search-modal .search-spinner')
const renderer = new Renderer('.search-modal .search-results', '.search-modal .search-stat', spinner)
this.form = new Form(spinner, renderer)
this.renderer = new Renderer('.search-modal .search-results', '.search-modal .search-stat', spinner)
this.form = new Form(spinner, this.renderer)
this.shortcuts = new Shortcuts([
closeShortcut,
searchShortcut,
Expand Down Expand Up @@ -99,6 +101,7 @@ export default class Modal {
${this.renderFooter()}
</div>`
this.wrapper.appendChild(this.container)
this.renderer.renderHistories()
}

renderFooter(): string {
Expand Down
28 changes: 28 additions & 0 deletions assets/search/js/renderer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { default as params } from '@params'
import i18n from './i18n'
import Spinner from './spinner'
import { default as Historiographer } from './historiographer'

export default class Renderer {
private initialized = false
Expand Down Expand Up @@ -209,6 +210,33 @@ export default class Renderer {
observer.observe(container, { childList: true });
}

renderHistories() {
this.results = []
this.clean()
const histories = Historiographer.get()
let html = ''
histories.forEach((history) => {
html += `<a title="${history.query}" data-query="${history.query}" href="#" class="search-result search-history" aria-selected="false">
<div class="search-result-icon">${params.icons['history']}</div>
<div class="search-result-content">
<div class="search-result-title">${history.query}</div>
<div class="search-result-desc">${history.date ? history.date.toLocaleString() : ''}</div>
</div>
</a>`
})
this.getContainer().insertAdjacentHTML('beforeend', html)
this.getContainer().querySelectorAll('.search-history').forEach((ele) => {
ele.addEventListener('click', (e) => {
e.preventDefault()
document.dispatchEvent(new CustomEvent('search:input:change', {
detail: {
value: ele.getAttribute('data-query')
}
}))
})
})
}

activeResult(target) {
if (target.ariaSelected === 'true') {
return
Expand Down
7 changes: 5 additions & 2 deletions assets/search/js/search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ export default class Search {

private shortcuts: Shortcuts

private renderer: Renderer

constructor() {
const container = document.querySelector('.search-container') as HTMLElement
if (!container) {
Expand All @@ -19,8 +21,8 @@ export default class Search {
this.container = container

const spinner = new Spinner('.search-container .search-spinner')
const renderer = new Renderer('.search-container .search-results', '.search-container .search-stat', spinner)
this.form = new Form(spinner, renderer)
this.renderer = new Renderer('.search-container .search-results', '.search-container .search-stat', spinner)
this.form = new Form(spinner, this.renderer)
this.form.modal = false

this.shortcuts = new Shortcuts([Navigate, Select])
Expand All @@ -34,6 +36,7 @@ export default class Search {
<div class="search-footer">${this.shortcuts.render()}</div>`
this.container.insertAdjacentHTML('beforeend', html)
this.form.init()
this.renderer.renderHistories()
}
}

Expand Down
1 change: 1 addition & 0 deletions hugo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,4 @@ expand_results_meta = false
lazy_loading = true
filter_taxonomies = true
filter_years = true
histories_count = 5
2 changes: 2 additions & 0 deletions layouts/partials/search/assets/js-resource.html
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
{{- $icons := dict
"page" (partial "icons/icon" (dict "vendor" "bootstrap" "name" "file-earmark-richtext" "size" "2em"))
"heading" (partial "icons/icon" (dict "vendor" "bootstrap" "name" "hash" "size" "2em"))
"history" (partial "icons/icon" (dict "vendor" "bootstrap" "name" "clock" "size" "2em"))
"meta" (partial "icons/icon" (dict "vendor" "bootstrap" "name" "info-circle" "size" "2em"))
"search" (partial "icons/icon" (dict "vendor" "bootstrap" "name" "search" "size" "1.25em"))
"spinner" (partial "icons/icon" (dict "vendor" "bootstrap" "name" "arrow-clockwise" "size" "1.25em"))
Expand Down Expand Up @@ -89,6 +90,7 @@
"icons" $icons
"indices" $indices
"i18n" $i18n.Values
"historiesCount" (default 5 site.Params.search.histories_count)
"defaultLang" $defaultLang
"langs" $langs.Values
"years" $years
Expand Down

0 comments on commit 4e28dfa

Please sign in to comment.