Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for histories #210

Merged
merged 1 commit into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading