Search: refactoring searching for themes, refactor allThemesGui, incidentally fix #1679

This commit is contained in:
Pieter Vander Vennet 2024-09-05 02:25:03 +02:00
parent 9b8c300e77
commit d90b6d82d0
18 changed files with 421 additions and 334 deletions

View file

@ -11,16 +11,11 @@
import LoginToggle from "./Base/LoginToggle.svelte"
import Pencil from "../assets/svg/Pencil.svelte"
import Constants from "../Models/Constants"
import { Store, UIEventSource } from "../Logic/UIEventSource"
import { placeholder } from "../Utils/placeholder"
import { SearchIcon } from "@rgossiaux/svelte-heroicons/solid"
import { Store, Stores, UIEventSource } from "../Logic/UIEventSource"
import ThemesList from "./BigComponents/ThemesList.svelte"
import { LayoutInformation } from "../Models/ThemeConfig/LayoutConfig"
import * as themeOverview from "../assets/generated/theme_overview.json"
import UnofficialThemeList from "./BigComponents/UnofficialThemeList.svelte"
import { MinimalLayoutInformation } from "../Models/ThemeConfig/LayoutConfig"
import Eye from "../assets/svg/Eye.svelte"
import LoginButton from "./Base/LoginButton.svelte"
import ChevronDoubleRight from "@babeard/svelte-heroicons/mini/ChevronDoubleRight"
import Mastodon from "../assets/svg/Mastodon.svelte"
import Liberapay from "../assets/svg/Liberapay.svelte"
import Bug from "../assets/svg/Bug.svelte"
@ -28,6 +23,7 @@
import { Utils } from "../Utils"
import { ArrowTrendingUp } from "@babeard/svelte-heroicons/solid/ArrowTrendingUp"
import Searchbar from "./Base/Searchbar.svelte"
import ChevronDoubleRight from "@babeard/svelte-heroicons/mini/ChevronDoubleRight"
const featureSwitches = new OsmConnectionFeatureSwitches()
const osmConnection = new OsmConnection({
@ -40,27 +36,71 @@
})
const state = new UserRelatedState(osmConnection)
const t = Translations.t.index
const tu = Translations.t.general
const tr = Translations.t.general.morescreen
let userLanguages = osmConnection.userDetails.map((ud) => ud.languages)
let themeSearchText: UIEventSource<string | undefined> = new UIEventSource<string>("")
let search: UIEventSource<string | undefined> = new UIEventSource<string>("")
let searchStable = search.stabilized(100)
const officialThemes: MinimalLayoutInformation[] = MoreScreen.officialThemes.themes.filter(th => th.hideFromOverview === false)
const hiddenThemes: MinimalLayoutInformation[] = MoreScreen.officialThemes.themes.filter(th => th.hideFromOverview === true)
let visitedHiddenThemes: Store<MinimalLayoutInformation[]> = MoreScreen.knownHiddenThemes(state.osmConnection)
.map((knownIds) => hiddenThemes.filter((theme) =>
knownIds.has(theme.id) || state.osmConnection.userDetails.data.name === "Pieter Vander Vennet"
))
const customThemes: Store<MinimalLayoutInformation[]> = Stores.ListStabilized<string>(state.installedUserThemes)
.mapD(stableIds => stableIds.map(id => state.getUnofficialTheme(id)))
function filtered(themes: MinimalLayoutInformation[]): Store<MinimalLayoutInformation[]> {
return searchStable.map(search => {
if (!search) {
return themes
}
const scores = MoreScreen.sortedByLowest(search, themes)
const strict = scores.filter(sc => sc.lowest < 2)
if (strict.length > 0) {
return strict.map(sc => sc.theme)
}
return scores.filter(sc => sc.lowest < 4).slice(0, 6).map(sc => sc.theme)
})
}
let officialSearched = filtered(officialThemes)
let hiddenSearched = visitedHiddenThemes.bindD(visited => filtered(visited))
let customSearched = customThemes.bindD(customThemes => filtered(customThemes))
let searchIsFocussed = new UIEventSource(false)
document.addEventListener("keydown", function(event) {
if (event.ctrlKey && event.code === "KeyF") {
document.getElementById("theme-search")?.focus()
searchIsFocussed.set(true)
event.preventDefault()
}
})
let visitedHiddenThemes: Store<LayoutInformation[]>
const hiddenThemes: LayoutInformation[] =
(themeOverview["default"] ?? themeOverview)?.filter((layout) => layout.hideFromOverview) ?? []
{
visitedHiddenThemes = MoreScreen.knownHiddenThemes(state.osmConnection)
.map((knownIds) => hiddenThemes.filter((theme) =>
knownIds.has(theme.id) || state.osmConnection.userDetails.data.name === "Pieter Vander Vennet"
))
function applySearch() {
const didRedirect = MoreScreen.applySearch(search.data)
console.log("Did redirect?", didRedirect)
if (didRedirect) {
// Just for style and readability; won't _actually_ reach this
return
}
const candidate = officialSearched.data[0] ?? hiddenSearched.data[0] ?? customSearched.data[0]
if (!candidate) {
return
}
window.location.href = MoreScreen.createUrlFor(candidate)
}
</script>
<main>
@ -92,20 +132,19 @@
</div>
</div>
<Searchbar value={themeSearchText} placeholder={tr.searchForATheme} on:search={() => MoreScreen.applySearch(themeSearchText.data)}/>
<Searchbar value={search} placeholder={tr.searchForATheme} on:search={() => applySearch()} isFocused={searchIsFocussed} />
<ThemesList search={themeSearchText} {state} themes={MoreScreen.officialThemes} />
<ThemesList {search} {state} themes={$officialSearched} />
<LoginToggle {state}>
<LoginButton clss="primary" {osmConnection} slot="not-logged-in">
<Tr t={t.logIn} />
</LoginButton>
<ThemesList
hideThemes={false}
isCustom={false}
search={themeSearchText}
{search}
{state}
themes={$visitedHiddenThemes}
themes={$hiddenSearched}
hasSelection={$officialSearched.length === 0}
>
<svelte:fragment slot="title">
<h3>
@ -122,7 +161,19 @@
</svelte:fragment>
</ThemesList>
<UnofficialThemeList search={themeSearchText} {state} />
{#if $customThemes.length > 0}
<ThemesList {search} {state} themes={$customSearched}
hasSelection={$officialSearched.length === 0 && $hiddenSearched.length === 0}
>
<svelte:fragment slot="title">
<h3>
<Tr t={tu.customThemeTitle} />
</h3>
<Tr t={tu.customThemeIntro} />
</svelte:fragment>
</ThemesList>
{/if}
</LoginToggle>
<a