|
|
module.exports = class { onCreate(input) { this.state = { characters: [], channels: [], eventNames: [], filters: [], search: "", activeMap: { events: {}, characters: {}, channels: {}, }, } }
onInput(input) { this.update(input) }
onMount(input) { this.getEl("search").addEventListener("keydown", ev => { if (this.waiting) { return }
if (this.timeout != null) { clearTimeout(this.timeout) }
if (ev.key === "Enter") { this.emit("add", "search", ev.target.value) this.getEl("search").value = "" }
this.timeout = setTimeout(() => { this.timeout = null this.state.search = ev.target.value
this.update(this.input) }, 200) }) }
update(input) { if (input.filter) { this.updateActive(input) }
const search = this.state.search.toLocaleLowerCase()
this.state.characters = input.characters.filter(c => !this.state.activeMap.characters[c.id]).filter(c => this.matches(c.name, search)).sort((a,b) => compareFilters(a.name, b.name, search)) this.state.channels = input.channels.filter(c => !this.state.activeMap.channels[c.name]).filter(c => this.matches(c.name, search)).sort((a,b) => compareFilters(a.name, b.name, search)) this.state.eventNames = input.eventNames.filter(e => !this.state.activeMap.events[e]).filter(e => this.matches(e, search)).sort((a,b) => compareFilters(a, b, search)) }
updateActive({filter, characters, channels, eventNames}) { const filters = [] const activeMap = { events: {}, characters: {}, channels: {}, }
if (filter.search != null) { filters.push({ type: "search", key: "search", icon: "T", color: "color-text", text: filter.search, }) }
for (const character of (filter.characters || [])) { activeMap.characters[character] = true
filters.push({ type: "characters", key: character, icon: "C", color: "color-tag-character", id: character, text: (characters.find(c => c.id === character) || {name: "Unknown ("+character+")"}).name, }) }
for (const channel of (filter.channels || [])) { activeMap.channels[channel] = true
filters.push({ type: "channels", key: channel.replace(/'/g, "__"), icon: "#", color: "color-tag-location", id: channel, text: channel, }) }
for (const event of (filter.events || [])) { activeMap.events[event] = true
filters.push({ type: "events", key: event.replace(/['\s\.]/g, "__"), icon: "E", color: "color-tag-event", id: event, text: event, }) }
this.state.filters = filters this.state.activeMap = activeMap }
matches(str, search) { if (search == "") { return true }
if (search.length > str.length) { return false }
return str.toLowerCase().indexOf(search) !== -1 } }
/** * * @param {string} a * @param {string} b * @param {string} search */ function compareFilters(a, b, search) { if (search != "") { if (search.charAt(0) != "#" && a.charAt(0) == "#" && b.charAt(0) == "#") { search = '#' + search }
const aStarts = a.toLocaleLowerCase().startsWith(search) const bStarts = b.toLocaleLowerCase().startsWith(search) if (aStarts && !bStarts) { return -1 } else if (bStarts && !aStarts) { return 1 } }
return a.localeCompare(b) }
|