2017-10-17 09:27:15 +00:00
|
|
|
import { AnimeNotifier } from "../AnimeNotifier"
|
|
|
|
|
2018-03-17 19:41:18 +00:00
|
|
|
// Search page reference
|
|
|
|
var emptySearchHTML = ""
|
|
|
|
var searchPage: HTMLElement
|
2018-03-17 23:35:38 +00:00
|
|
|
var searchPageTitle: HTMLElement
|
2018-03-17 19:41:18 +00:00
|
|
|
var correctResponseRendered = {
|
|
|
|
"anime": false,
|
|
|
|
"character": false,
|
|
|
|
"forum": false,
|
|
|
|
"soundtrack": false,
|
2018-03-17 21:09:17 +00:00
|
|
|
"user": false,
|
|
|
|
"company": false
|
2018-03-17 19:41:18 +00:00
|
|
|
}
|
|
|
|
|
2018-03-17 21:20:26 +00:00
|
|
|
// Save old term to compare
|
|
|
|
var oldTerm = ""
|
|
|
|
|
2018-03-17 19:41:18 +00:00
|
|
|
// Containers for all the search results
|
|
|
|
var animeSearchResults: HTMLElement
|
|
|
|
var characterSearchResults: HTMLElement
|
|
|
|
var forumSearchResults: HTMLElement
|
|
|
|
var soundtrackSearchResults: HTMLElement
|
|
|
|
var userSearchResults: HTMLElement
|
2018-03-17 21:09:17 +00:00
|
|
|
var companySearchResults: HTMLElement
|
2018-03-17 19:41:18 +00:00
|
|
|
|
2017-10-17 09:27:15 +00:00
|
|
|
// Search
|
2018-03-17 19:41:18 +00:00
|
|
|
export async function search(arn: AnimeNotifier, search: HTMLInputElement, e: KeyboardEvent) {
|
2017-10-17 09:27:15 +00:00
|
|
|
if(e.ctrlKey || e.altKey) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-03-17 21:20:26 +00:00
|
|
|
// Check if the search term really changed
|
2018-03-17 19:41:18 +00:00
|
|
|
let term = search.value.trim()
|
2018-03-17 21:20:26 +00:00
|
|
|
|
|
|
|
if(term === oldTerm) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
oldTerm = term
|
|
|
|
|
|
|
|
// Determine if we're already seeing the search page
|
2018-03-17 19:41:18 +00:00
|
|
|
let searchPageActivated = (searchPage === arn.app.content.children[0])
|
2017-10-17 09:27:15 +00:00
|
|
|
|
2018-03-17 19:41:18 +00:00
|
|
|
// Reset
|
|
|
|
correctResponseRendered.anime = false
|
|
|
|
correctResponseRendered.character = false
|
|
|
|
correctResponseRendered.forum = false
|
|
|
|
correctResponseRendered.soundtrack = false
|
|
|
|
correctResponseRendered.user = false
|
|
|
|
|
|
|
|
// Set browser URL
|
|
|
|
let url = "/search/" + term
|
2018-03-17 23:35:38 +00:00
|
|
|
document.title = "Search: " + term
|
|
|
|
history.pushState(url, document.title, url)
|
2018-03-17 19:41:18 +00:00
|
|
|
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")
|
2018-03-17 21:09:17 +00:00
|
|
|
companySearchResults = document.getElementById("company-search-results")
|
2018-03-17 23:35:38 +00:00
|
|
|
searchPageTitle = document.getElementsByTagName("h1")[0]
|
2018-03-17 19:41:18 +00:00
|
|
|
}
|
|
|
|
|
2018-03-17 23:35:38 +00:00
|
|
|
searchPageTitle.innerText = document.title
|
|
|
|
|
2018-03-17 19:41:18 +00:00
|
|
|
if(!term || term.length < 1) {
|
|
|
|
await arn.innerHTML(searchPage, emptySearchHTML)
|
|
|
|
arn.app.emit("DOMContentLoaded")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2018-03-17 19:53:18 +00:00
|
|
|
const fetchOptions: RequestInit = {
|
|
|
|
credentials: "same-origin"
|
|
|
|
}
|
|
|
|
|
2018-03-17 19:41:18 +00:00
|
|
|
// Start searching
|
2018-03-17 19:53:18 +00:00
|
|
|
fetch("/_/anime-search/" + term, fetchOptions)
|
2018-03-17 19:41:18 +00:00
|
|
|
.then(showResponseInElement(arn, url, "anime", animeSearchResults))
|
|
|
|
.catch(console.error)
|
|
|
|
|
2018-03-17 19:53:18 +00:00
|
|
|
fetch("/_/character-search/" + term, fetchOptions)
|
2018-03-17 19:41:18 +00:00
|
|
|
.then(showResponseInElement(arn, url, "character", characterSearchResults))
|
|
|
|
.catch(console.error)
|
|
|
|
|
2018-03-17 19:53:18 +00:00
|
|
|
fetch("/_/forum-search/" + term, fetchOptions)
|
2018-03-17 19:41:18 +00:00
|
|
|
.then(showResponseInElement(arn, url, "forum", forumSearchResults))
|
|
|
|
.catch(console.error)
|
|
|
|
|
2018-03-17 19:53:18 +00:00
|
|
|
fetch("/_/soundtrack-search/" + term, fetchOptions)
|
2018-03-17 19:41:18 +00:00
|
|
|
.then(showResponseInElement(arn, url, "soundtrack", soundtrackSearchResults))
|
|
|
|
.catch(console.error)
|
|
|
|
|
2018-03-17 19:53:18 +00:00
|
|
|
fetch("/_/user-search/" + term, fetchOptions)
|
2018-03-17 19:41:18 +00:00
|
|
|
.then(showResponseInElement(arn, url, "user", userSearchResults))
|
|
|
|
.catch(console.error)
|
2018-03-17 21:09:17 +00:00
|
|
|
|
|
|
|
fetch("/_/company-search/" + term, fetchOptions)
|
|
|
|
.then(showResponseInElement(arn, url, "company", companySearchResults))
|
|
|
|
.catch(console.error)
|
2018-03-17 19:41:18 +00:00
|
|
|
} catch(err) {
|
|
|
|
console.error(err)
|
|
|
|
} finally {
|
|
|
|
arn.loading(false)
|
2017-10-17 09:27:15 +00:00
|
|
|
}
|
2018-03-17 19:41:18 +00:00
|
|
|
}
|
2017-10-17 09:27:15 +00:00
|
|
|
|
2018-03-17 19:41:18 +00:00
|
|
|
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")
|
|
|
|
}
|
2017-10-19 19:43:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Search database
|
|
|
|
export function searchDB(arn: AnimeNotifier, input: HTMLInputElement, e: KeyboardEvent) {
|
|
|
|
if(e.ctrlKey || e.altKey) {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
let dataType = (arn.app.find("data-type") as HTMLInputElement).value || "+"
|
|
|
|
let field = (arn.app.find("field") as HTMLInputElement).value || "+"
|
|
|
|
let fieldValue = (arn.app.find("field-value") as HTMLInputElement).value || "+"
|
|
|
|
let records = arn.app.find("records")
|
|
|
|
|
|
|
|
arn.loading(true)
|
|
|
|
|
|
|
|
fetch(`/api/select/${dataType}/where/${field}/is/${fieldValue}`)
|
|
|
|
.then(response => {
|
|
|
|
if(response.status !== 200) {
|
|
|
|
throw response
|
|
|
|
}
|
|
|
|
|
|
|
|
return response
|
|
|
|
})
|
|
|
|
.then(response => response.json())
|
|
|
|
.then(data => {
|
|
|
|
records.innerHTML = ""
|
|
|
|
let count = 0
|
|
|
|
|
|
|
|
if(data.results.length === 0) {
|
|
|
|
records.innerText = "No results."
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
for(let record of data.results) {
|
|
|
|
count++
|
|
|
|
|
|
|
|
let container = document.createElement("div")
|
|
|
|
container.classList.add("record")
|
|
|
|
|
|
|
|
let id = document.createElement("div")
|
|
|
|
id.innerText = record.id
|
|
|
|
id.classList.add("record-id")
|
|
|
|
container.appendChild(id)
|
|
|
|
|
|
|
|
let link = document.createElement("a")
|
|
|
|
link.classList.add("record-view")
|
|
|
|
link.innerText = "Open " + dataType.toLowerCase()
|
|
|
|
|
|
|
|
if(dataType === "User") {
|
|
|
|
link.href = "/+" + record.nick
|
|
|
|
} else {
|
|
|
|
link.href = "/" + dataType.toLowerCase() + "/" + record.id
|
|
|
|
}
|
2018-03-17 19:41:18 +00:00
|
|
|
|
2017-10-19 19:43:42 +00:00
|
|
|
link.target = "_blank"
|
|
|
|
container.appendChild(link)
|
|
|
|
|
|
|
|
let apiLink = document.createElement("a")
|
|
|
|
apiLink.classList.add("record-view-api")
|
|
|
|
apiLink.innerText = "JSON data"
|
|
|
|
apiLink.href = "/api/" + dataType.toLowerCase() + "/" + record.id
|
|
|
|
apiLink.target = "_blank"
|
|
|
|
container.appendChild(apiLink)
|
|
|
|
|
|
|
|
let recordCount = document.createElement("div")
|
|
|
|
recordCount.innerText = count + "/" + data.results.length
|
|
|
|
recordCount.classList.add("record-count")
|
|
|
|
container.appendChild(recordCount)
|
|
|
|
|
|
|
|
records.appendChild(container)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.catch(response => {
|
|
|
|
response.text().then(text => {
|
|
|
|
arn.statusMessage.showError(text)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
.then(() => arn.loading(false))
|
2017-10-17 09:27:15 +00:00
|
|
|
}
|