diff --git a/UI/BigComponents/MoreScreen.ts b/UI/BigComponents/MoreScreen.ts index 63887079d4..7ae449437e 100644 --- a/UI/BigComponents/MoreScreen.ts +++ b/UI/BigComponents/MoreScreen.ts @@ -1,17 +1,17 @@ import Svg from "../../Svg" import Combine from "../Base/Combine" -import { SubtleButton } from "../Base/SubtleButton" +import {SubtleButton} from "../Base/SubtleButton" import Translations from "../i18n/Translations" import BaseUIElement from "../BaseUIElement" -import LayoutConfig, { LayoutInformation } from "../../Models/ThemeConfig/LayoutConfig" -import { ImmutableStore, Store, UIEventSource } from "../../Logic/UIEventSource" +import LayoutConfig, {LayoutInformation} from "../../Models/ThemeConfig/LayoutConfig" +import {ImmutableStore, Store, UIEventSource} from "../../Logic/UIEventSource" import Loc from "../../Models/Loc" import UserRelatedState from "../../Logic/State/UserRelatedState" -import { Utils } from "../../Utils" +import {Utils} from "../../Utils" import Title from "../Base/Title" import themeOverview from "../../assets/generated/theme_overview.json" -import { Translation } from "../i18n/Translation" -import { TextField } from "../Input/TextField" +import {Translation} from "../i18n/Translation" +import {TextField} from "../Input/TextField" import Locale from "../i18n/Locale" import SvelteUIElement from "../Base/SvelteUIElement" import ThemesList from "./ThemesList.svelte" @@ -37,7 +37,7 @@ export default class MoreScreen extends Combine { searchTerm = searchTerm.toLowerCase() if (searchTerm === "personal") { window.location.href = MoreScreen.createUrlFor( - { id: "personal" }, + {id: "personal"}, false, state ).data @@ -59,13 +59,13 @@ export default class MoreScreen extends Combine { (th) => th.hideFromOverview == false && th.id !== "personal" && - MoreScreen.MatchesLayoutFunc(th)(searchTerm) + MoreScreen.MatchesLayout(th, searchTerm) ) if (publicTheme !== undefined) { window.location.href = MoreScreen.createUrlFor(publicTheme, false, state).data } const hiddenTheme = MoreScreen.officialThemes.find( - (th) => th.id !== "personal" && MoreScreen.MatchesLayoutFunc(th)(searchTerm) + (th) => th.id !== "personal" && MoreScreen.MatchesLayout(th, searchTerm) ) if (hiddenTheme !== undefined) { window.location.href = MoreScreen.createUrlFor(hiddenTheme, false, state).data @@ -109,6 +109,85 @@ export default class MoreScreen extends Combine { ]) } + /** + * Creates a button linking to the given theme + * @private + */ + public static createLinkButton( + state: { + locationControl?: UIEventSource + layoutToUse?: LayoutConfig + }, + layout: { + id: string + icon: string + title: any + shortDescription: any + definition?: any + mustHaveLanguage?: boolean + }, + isCustom: boolean = false + ): BaseUIElement { + const url = MoreScreen.createUrlFor(layout, isCustom, state) + let content = new Combine([ + new Translation( + layout.title, + !isCustom && !layout.mustHaveLanguage ? "themes:" + layout.id + ".title" : undefined + ), + new Translation(layout.shortDescription)?.SetClass("subtle") ?? "", + ]).SetClass("overflow-hidden flex flex-col") + + if (state.layoutToUse === undefined) { + // Currently on the index screen: we style the buttons equally large + content = new Combine([content]).SetClass("flex flex-col justify-center h-24") + } + + return new SubtleButton(layout.icon, content, {url, newTab: false}) + } + + public static CreateProffessionalSerivesButton() { + const t = Translations.t.professional.indexPage + return new Combine([ + new Title(t.hook, 4), + t.hookMore, + new SubtleButton(undefined, t.button, {url: "./professional.html"}), + ]).SetClass("flex flex-col border border-gray-300 p-2 rounded-lg") + } + + public static MatchesLayout(layout: { + id: string + title: any + shortDescription: any + keywords?: any[] + }, search: string): boolean { + if(search === undefined){ + return true + } + search = search.toLocaleLowerCase() + if (search.length > 3 && layout.id.toLowerCase().indexOf(search) >= 0) { + return true + } + if(layout.id === "personal"){ + return false + } + const entitiesToSearch = [ + layout.shortDescription, + layout.title, + ...(layout.keywords ?? []), + ] + for (const entity of entitiesToSearch) { + if (entity === undefined) { + continue + } + const term = entity["*"] ?? entity[Locale.language.data] + if (term?.toLowerCase()?.indexOf(search) >= 0) { + return true + } + } + + return false + } + private static createUrlFor( layout: { id: string; definition?: string }, isCustom: boolean, @@ -164,79 +243,4 @@ export default class MoreScreen extends Combine { }) ?? new ImmutableStore(`${linkPrefix}`) ) } - - /** - * Creates a button linking to the given theme - * @private - */ - public static createLinkButton( - state: { - locationControl?: UIEventSource - layoutToUse?: LayoutConfig - }, - layout: { - id: string - icon: string - title: any - shortDescription: any - definition?: any - mustHaveLanguage?: boolean - }, - isCustom: boolean = false - ): BaseUIElement { - const url = MoreScreen.createUrlFor(layout, isCustom, state) - let content = new Combine([ - new Translation( - layout.title, - !isCustom && !layout.mustHaveLanguage ? "themes:" + layout.id + ".title" : undefined - ), - new Translation(layout.shortDescription)?.SetClass("subtle") ?? "", - ]).SetClass("overflow-hidden flex flex-col") - - if (state.layoutToUse === undefined) { - // Currently on the index screen: we style the buttons equally large - content = new Combine([content]).SetClass("flex flex-col justify-center h-24") - } - - return new SubtleButton(layout.icon, content, { url, newTab: false }) - } - - public static CreateProffessionalSerivesButton() { - const t = Translations.t.professional.indexPage - return new Combine([ - new Title(t.hook, 4), - t.hookMore, - new SubtleButton(undefined, t.button, { url: "./professional.html" }), - ]).SetClass("flex flex-col border border-gray-300 p-2 rounded-lg") - } - - private static MatchesLayoutFunc(layout: { - id: string - title: any - shortDescription: any - keywords?: any[] - }): (search: string) => boolean { - return (search: string) => { - search = search.toLocaleLowerCase() - if (layout.id.toLowerCase().indexOf(search) >= 0) { - return true - } - const entitiesToSearch = [ - layout.shortDescription, - layout.title, - ...(layout.keywords ?? []), - ] - for (const entity of entitiesToSearch) { - if (entity === undefined) { - continue - } - const term = entity["*"] ?? entity[Locale.language.data] - if (term?.toLowerCase()?.indexOf(search) >= 0) { - return true - } - } - - return false - } - } } diff --git a/UI/BigComponents/ThemesList.svelte b/UI/BigComponents/ThemesList.svelte index 3f4bc51a58..f4e3abb7c5 100644 --- a/UI/BigComponents/ThemesList.svelte +++ b/UI/BigComponents/ThemesList.svelte @@ -9,6 +9,7 @@ import ProfessionalServicesButton from "./ProfessionalServicesButton.svelte" import ThemeButton from "./ThemeButton.svelte" import { LayoutInformation } from "../../Models/ThemeConfig/LayoutConfig" + import MoreScreen from "./MoreScreen"; export let search: UIEventSource export let themes: LayoutInformation[] @@ -18,26 +19,7 @@ export let hideThemes: boolean = true // Filter theme based on search value - $: filteredThemes = themes.filter((theme) => { - if ($search === undefined || $search === "") return true - - const srch = $search.toLocaleLowerCase() - if (theme.id.toLowerCase().indexOf(srch) >= 0) { - return true - } - const entitiesToSearch = [theme.shortDescription, theme.title, ...(theme.keywords ?? [])] - for (const entity of entitiesToSearch) { - if (entity === undefined) { - continue - } - const term = entity["*"] ?? entity[Locale.language.data] - if (term?.toLowerCase()?.indexOf(search) >= 0) { - return true - } - } - - return false - }) + $: filteredThemes = themes.filter((theme) => MoreScreen.MatchesLayout(theme, $search))