Make search great again
This commit is contained in:
@ -1,19 +1,126 @@
|
||||
import { AnimeNotifier } from "../AnimeNotifier"
|
||||
|
||||
// Search page reference
|
||||
var emptySearchHTML = ""
|
||||
var searchPage: HTMLElement
|
||||
var correctResponseRendered = {
|
||||
"anime": false,
|
||||
"character": false,
|
||||
"forum": false,
|
||||
"soundtrack": false,
|
||||
"user": false
|
||||
}
|
||||
|
||||
// Containers for all the search results
|
||||
var animeSearchResults: HTMLElement
|
||||
var characterSearchResults: HTMLElement
|
||||
var forumSearchResults: HTMLElement
|
||||
var soundtrackSearchResults: HTMLElement
|
||||
var userSearchResults: HTMLElement
|
||||
|
||||
// Search
|
||||
export function search(arn: AnimeNotifier, search: HTMLInputElement, e: KeyboardEvent) {
|
||||
export async function search(arn: AnimeNotifier, search: HTMLInputElement, e: KeyboardEvent) {
|
||||
if(e.ctrlKey || e.altKey) {
|
||||
return
|
||||
}
|
||||
|
||||
let term = search.value
|
||||
let term = search.value.trim()
|
||||
let searchPageActivated = (searchPage === arn.app.content.children[0])
|
||||
|
||||
if(!term || term.length < 1) {
|
||||
arn.app.content.innerHTML = "Please enter at least 1 character to start searching."
|
||||
return
|
||||
// Reset
|
||||
correctResponseRendered.anime = false
|
||||
correctResponseRendered.character = false
|
||||
correctResponseRendered.forum = false
|
||||
correctResponseRendered.soundtrack = false
|
||||
correctResponseRendered.user = false
|
||||
|
||||
// Set browser URL
|
||||
let url = "/search/" + term
|
||||
history.pushState(url, null, url)
|
||||
arn.app.currentPath = url
|
||||
|
||||
// Unmount mountables to improve visual responsiveness on key press
|
||||
arn.unmountMountables()
|
||||
|
||||
// Show loading spinner
|
||||
arn.loading(true)
|
||||
|
||||
try {
|
||||
// Fetch empty search frame if needed
|
||||
if(emptySearchHTML === "") {
|
||||
let response = await fetch("/_/empty-search")
|
||||
emptySearchHTML = await response.text()
|
||||
}
|
||||
|
||||
if(!searchPageActivated) {
|
||||
if(!searchPage) {
|
||||
searchPage = document.createElement("div")
|
||||
searchPage.innerHTML = emptySearchHTML
|
||||
}
|
||||
|
||||
arn.app.content.innerHTML = ""
|
||||
arn.app.content.appendChild(searchPage)
|
||||
}
|
||||
|
||||
if(!animeSearchResults) {
|
||||
animeSearchResults = document.getElementById("anime-search-results")
|
||||
characterSearchResults = document.getElementById("character-search-results")
|
||||
forumSearchResults = document.getElementById("forum-search-results")
|
||||
soundtrackSearchResults = document.getElementById("soundtrack-search-results")
|
||||
userSearchResults = document.getElementById("user-search-results")
|
||||
}
|
||||
|
||||
if(!term || term.length < 1) {
|
||||
await arn.innerHTML(searchPage, emptySearchHTML)
|
||||
arn.app.emit("DOMContentLoaded")
|
||||
return
|
||||
}
|
||||
|
||||
// Start searching
|
||||
fetch("/_/anime-search/" + term)
|
||||
.then(showResponseInElement(arn, url, "anime", animeSearchResults))
|
||||
.catch(console.error)
|
||||
|
||||
fetch("/_/character-search/" + term)
|
||||
.then(showResponseInElement(arn, url, "character", characterSearchResults))
|
||||
.catch(console.error)
|
||||
|
||||
fetch("/_/forum-search/" + term)
|
||||
.then(showResponseInElement(arn, url, "forum", forumSearchResults))
|
||||
.catch(console.error)
|
||||
|
||||
fetch("/_/soundtrack-search/" + term)
|
||||
.then(showResponseInElement(arn, url, "soundtrack", soundtrackSearchResults))
|
||||
.catch(console.error)
|
||||
|
||||
fetch("/_/user-search/" + term)
|
||||
.then(showResponseInElement(arn, url, "user", userSearchResults))
|
||||
.catch(console.error)
|
||||
} catch(err) {
|
||||
console.error(err)
|
||||
} finally {
|
||||
arn.loading(false)
|
||||
}
|
||||
}
|
||||
|
||||
arn.diff("/search/" + term)
|
||||
function showResponseInElement(arn: AnimeNotifier, url: string, typeName: string, element: HTMLElement) {
|
||||
return async response => {
|
||||
let html = await response.text()
|
||||
|
||||
if(arn.app.currentPath !== url) {
|
||||
// Return if this result would overwrite the already arrived correct result
|
||||
if(correctResponseRendered[typeName]) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
correctResponseRendered[typeName] = true
|
||||
}
|
||||
|
||||
await arn.innerHTML(element, html)
|
||||
|
||||
// Emit content loaded event
|
||||
arn.app.emit("DOMContentLoaded")
|
||||
}
|
||||
}
|
||||
|
||||
// Search database
|
||||
@ -67,7 +174,7 @@ export function searchDB(arn: AnimeNotifier, input: HTMLInputElement, e: Keyboar
|
||||
} else {
|
||||
link.href = "/" + dataType.toLowerCase() + "/" + record.id
|
||||
}
|
||||
|
||||
|
||||
link.target = "_blank"
|
||||
container.appendChild(link)
|
||||
|
||||
|
Reference in New Issue
Block a user