import $ from 'jquery'
// @ts-ignore
import AutoComplete from '@tarekraafat/autocomplete.js/dist/autoComplete'
import { getTextAdData, fetchTextAdData } from './ad'
import { DateTime } from 'luxon'
import { appendTokenIcon } from './token_icon'
import { escapeHtml } from './utils'
import { commonPath } from './path_helper'
import xss from 'xss'
const placeHolder = 'Search by address, token symbol, name, transaction hash, or block number'
const dataSrc = async (query, id) => {
try {
// Loading placeholder text
const searchInput = document
.getElementById(id)
searchInput && searchInput.setAttribute('placeholder', 'Loading...')
// Fetch External Data Source
const source = await fetch(
`${commonPath}/token-autocomplete?q=${query}`
)
const data = await source.json()
// Post Loading placeholder text
searchInput && searchInput.setAttribute('placeholder', placeHolder)
// Returns Fetched data
return data
} catch (error) {
return error
}
}
const resultsListElement = (list, data) => {
const info = document.createElement('p')
const adv = `
:
-
`
info.innerHTML = adv
if (data.results.length > 0) {
info.innerHTML += `Displaying ${data.results.length} results`
} else if (data.query !== '###') {
info.innerHTML += `Found ${data.matches.length} matching results for `
const strong = document.createElement('strong')
strong.appendChild(document.createTextNode(data.query))
info.appendChild(strong)
}
list.prepend(info)
fetchTextAdData()
}
export const searchEngine = (query, record) => {
const queryLowerCase = query.toLowerCase()
if (record && (
(record.name && record.name.toLowerCase().includes(queryLowerCase)) ||
(record.symbol && record.symbol.toLowerCase().includes(queryLowerCase)) ||
(record.address_hash && record.address_hash.toLowerCase().includes(queryLowerCase)) ||
(record.tx_hash && record.tx_hash.toLowerCase().includes(queryLowerCase)) ||
(record.block_hash && record.block_hash.toLowerCase().includes(queryLowerCase))
)
) {
let searchResult = ''
searchResult += `
${record.address_hash || record.tx_hash || record.block_hash}
`
if (record.type === 'label') {
searchResult += `
${record.name}`
} else {
searchResult += '
'
if (record.name) {
searchResult += `${escapeHtml(record.name)}`
}
if (record.symbol) {
searchResult += ` (${escapeHtml(record.symbol)})`
}
if (record.holder_count) {
searchResult += ` ${record.holder_count} holder(s)`
}
if (record.inserted_at) {
searchResult += ` (${DateTime.fromISO(record.inserted_at).toLocaleString(DateTime.DATETIME_SHORT)})`
}
searchResult += '
'
}
searchResult += '
'
const re = new RegExp(query, 'ig')
searchResult = searchResult.replace(re, '$&')
return searchResult
}
}
const resultItemElement = async (item, data) => {
item.style = 'display: flex;'
item.innerHTML = `
${data.match}
${data.value.type}
`
const $tokenIconContainer = $(item).find(`#token-icon-${data.value.address_hash}`)
const $searchInput = $('#main-search-autocomplete')
const chainID = $searchInput.data('chain-id')
const displayTokenIcons = $searchInput.data('display-token-icons')
appendTokenIcon($tokenIconContainer, chainID, data.value.address_hash, displayTokenIcons, 15)
}
const config = (id) => {
return {
selector: `#${id}`,
data: {
src: (query) => dataSrc(query, id),
cache: false
},
placeHolder,
searchEngine: (query, record) => searchEngine(query, record),
threshold: 2,
resultsList: {
element: (list, data) => resultsListElement(list, data),
noResults: true,
maxResults: 100,
tabSelect: true
},
resultItem: {
element: (item, data) => resultItemElement(item, data),
highlight: 'autoComplete_highlight'
},
query: (input) => {
return xss(input)
},
events: {
input: {
focus: () => {
// @ts-ignore
if (autoCompleteJS && autoCompleteJS.input.value.length) autoCompleteJS.start()
}
}
}
}
}
const autoCompleteJS = document.querySelector('#main-search-autocomplete') && new AutoComplete(config('main-search-autocomplete'))
// eslint-disable-next-line
const autoCompleteJSMobile = document.querySelector('#main-search-autocomplete-mobile') && new AutoComplete(config('main-search-autocomplete-mobile'))
const selection = (event) => {
const selectionValue = event.detail.selection.value
if (selectionValue.type === 'contract' || selectionValue.type === 'address' || selectionValue.type === 'label') {
window.location.href = `${commonPath}/address/${selectionValue.address_hash}`
} else if (selectionValue.type === 'token') {
window.location.href = `${commonPath}/tokens/${selectionValue.address_hash}`
} else if (selectionValue.type === 'transaction') {
window.location.href = `${commonPath}/tx/${selectionValue.tx_hash}`
} else if (selectionValue.type === 'block') {
window.location.href = `${commonPath}/blocks/${selectionValue.block_hash}`
}
}
const openOnFocus = (event, type) => {
const query = event.target.value
if (query) {
if (type === 'desktop') {
// @ts-ignore
autoCompleteJS && autoCompleteJS.start(query)
} else if (type === 'mobile') {
// @ts-ignore
autoCompleteJSMobile && autoCompleteJSMobile.start(query)
}
} else {
getTextAdData()
.then(({ data: adData, inHouse: _inHouse }) => {
if (adData) {
if (type === 'desktop') {
// @ts-ignore
autoCompleteJS && autoCompleteJS.start('###')
} else if (type === 'mobile') {
// @ts-ignore
autoCompleteJSMobile && autoCompleteJSMobile.start('###')
}
}
})
}
}
const mainSearchAutocompleteObj = document.querySelector('#main-search-autocomplete')
const mainSearchAutocompleteMobileObj = document.querySelector('#main-search-autocomplete-mobile')
mainSearchAutocompleteObj && mainSearchAutocompleteObj.addEventListener('selection', function (event) {
selection(event)
})
mainSearchAutocompleteMobileObj && mainSearchAutocompleteMobileObj.addEventListener('selection', function (event) {
selection(event)
})
mainSearchAutocompleteObj && mainSearchAutocompleteObj.addEventListener('focus', function (event) {
openOnFocus(event, 'desktop')
})
mainSearchAutocompleteMobileObj && mainSearchAutocompleteMobileObj.addEventListener('focus', function (event) {
openOnFocus(event, 'mobile')
})