Properly render theme icon when using a studio layer as theme

This commit is contained in:
Pieter Vander Vennet 2024-06-19 01:56:19 +02:00
parent 5ead6c6e37
commit d38a6c7505
6 changed files with 50 additions and 27 deletions

View file

@ -162,18 +162,26 @@ export default class DetermineLayout {
return dict return dict
} }
private static getSharedTagRenderingOrder(): string[] {
return questions.tagRenderings.map(tr => tr.id)
}
private static prepCustomTheme(json: any, sourceUrl?: string, forceId?: string): LayoutConfig { private static prepCustomTheme(json: any, sourceUrl?: string, forceId?: string): LayoutConfig {
if (json.layers === undefined && json.tagRenderings !== undefined) { if (json.layers === undefined && json.tagRenderings !== undefined) {
// We got fed a layer instead of a theme // We got fed a layer instead of a theme
const layerConfig = <LayerConfigJson>json const layerConfig = <LayerConfigJson>json
const iconTr: string | TagRenderingConfigJson = const icon = Utils.NoNull(layerConfig.pointRendering.flatMap(
<any>( pr => pr.marker
layerConfig.pointRendering ).map(iconSpec => {
.map((mr) => mr?.marker?.find((icon) => icon.icon !== undefined)?.icon) const icon = new TagRenderingConfig(<TagRenderingConfigJson>iconSpec.icon).render.txt
.find((i) => i !== undefined) if(iconSpec.color === undefined || icon.startsWith("http:") || icon.startsWith("https:")){
) ?? "bug" return icon
const icon = new TagRenderingConfig(iconTr)?.render?.txt ?? "./assets/svg/bug.svg" }
const color = new TagRenderingConfig(<TagRenderingConfigJson>iconSpec.color).render.txt
return icon+":"+color
})).join(";")
json = { json = {
id: json.id, id: json.id,
description: json.description, description: json.description,
@ -193,6 +201,7 @@ export default class DetermineLayout {
} }
const convertState: DesugaringContext = { const convertState: DesugaringContext = {
tagRenderings: DetermineLayout.getSharedTagRenderings(), tagRenderings: DetermineLayout.getSharedTagRenderings(),
tagRenderingOrder: DetermineLayout.getSharedTagRenderingOrder(),
sharedLayers: knownLayersDict, sharedLayers: knownLayersDict,
publicLayers: new Set<string>(), publicLayers: new Set<string>(),
} }
@ -211,7 +220,7 @@ export default class DetermineLayout {
} }
{ {
new ValidateThemeAndLayers( new ValidateThemeAndLayers(
new DoesImageExist(new Set<string>(), (_) => true), new DoesImageExist(new Set<string>(), () => true),
"", "",
false false
).convertStrict(json) ).convertStrict(json)

View file

@ -183,7 +183,10 @@ export interface TagRenderingConfigJson {
* ifunset: Do not show an extra icon next to the render value * ifunset: Do not show an extra icon next to the render value
* *
* An icon supporting this mapping; typically shown pretty small. * An icon supporting this mapping; typically shown pretty small.
* This can be used to show a 'phone'-icon next to the phone number * This can be used to show a e.g. 'phone'-icon next to the phone number
*
* This supports patterns, you can e.g. have `close:red;some/other/icon.svg`
*
* inline: <img src='{icon}' class="w-8 h-8" /> {icon} * inline: <img src='{icon}' class="w-8 h-8" /> {icon}
* Type: icon * Type: icon
*/ */

View file

@ -8,6 +8,7 @@
import Tr from "../Base/Tr.svelte" import Tr from "../Base/Tr.svelte"
import Translations from "../i18n/Translations" import Translations from "../i18n/Translations"
import { LocalStorageSource } from "../../Logic/Web/LocalStorageSource" import { LocalStorageSource } from "../../Logic/Web/LocalStorageSource"
import Marker from "../Map/Marker.svelte"
export let theme: LayoutInformation export let theme: LayoutInformation
export let isCustom: boolean = false export let isCustom: boolean = false
@ -86,7 +87,8 @@
{#if theme.id !== personal.id || $unlockedPersonal} {#if theme.id !== personal.id || $unlockedPersonal}
<a class={"flex w-full items-center text-ellipsis rounded my-2"} href={$href}> <a class={"flex w-full items-center text-ellipsis rounded my-2"} href={$href}>
<img src={theme.icon} class="m-1 block h-11 w-11 sm:mr-2" alt="" /> <Marker icons={theme.icon} size="m-1 block h-11 w-11 sm:mr-2"/>
<span class="flex flex-col overflow-hidden text-ellipsis font-bold text-xl"> <span class="flex flex-col overflow-hidden text-ellipsis font-bold text-xl">
<Tr cls="underline" t={title} /> <Tr cls="underline" t={title} />
<Tr cls="subtle text-base" t={description}/> <Tr cls="subtle text-base" t={description}/>

View file

@ -5,11 +5,30 @@
/** /**
* Renders a 'marker', which consists of multiple 'icons' * Renders a 'marker', which consists of multiple 'icons'
*/ */
export let icons: { icon: string; color: string }[] export let icons: string | { icon: string; color: string }[]
if(typeof icons === "string") {
icons = icons.split(";").map(subspec => {
if(subspec.startsWith("http://") || subspec.startsWith("https://")){
return {
icon: subspec, color: "black"
}
}
const [icon, color] = subspec.split(":")
return {
icon, color: color ?? "black"
}
})
}
/** /**
* Class which is applied onto the individual icons * Class which is applied onto the individual icons
*/ */
export let clss = "" export let clss = ""
/**
* Class applied onto the entire element
*/
export let size = "w-full h-full" export let size = "w-full h-full"
</script> </script>

View file

@ -31,20 +31,13 @@
| "large-height" | "large-height"
| string | string
} }
function iconToMarker(spec: string) {
return spec.split(";").map(subspec => {
const [icon, color] = subspec.split(":")
return {
icon, color: color ?? "black"
}
})
}
</script> </script>
{#if mapping.icon !== undefined} {#if mapping.icon !== undefined}
<div class="inline-flex items-center"> <div class="inline-flex items-center">
<Marker <Marker
icons={iconToMarker(mapping.icon)} icons={mapping.icon}
size={twJoin(`mapping-icon-${mapping.iconClass ?? "small"}-height mapping-icon-${mapping.iconClass ?? "small"}-width`, "mr-2", "shrink-0 mx-2")} size={twJoin(`mapping-icon-${mapping.iconClass ?? "small"}-height mapping-icon-${mapping.iconClass ?? "small"}-width`, "mr-2", "shrink-0 mx-2")}
clss={`mapping-icon-${mapping.iconClass ?? "small"}`} clss={`mapping-icon-${mapping.iconClass ?? "small"}`}
/> />

View file

@ -78,6 +78,7 @@
import Share from "@babeard/svelte-heroicons/solid/Share" import Share from "@babeard/svelte-heroicons/solid/Share"
import ChevronRight from "@babeard/svelte-heroicons/solid/ChevronRight" import ChevronRight from "@babeard/svelte-heroicons/solid/ChevronRight"
import DocumentChartBar from "@babeard/svelte-heroicons/outline/DocumentChartBar" import DocumentChartBar from "@babeard/svelte-heroicons/outline/DocumentChartBar"
import Marker from "./Map/Marker.svelte"
export let state: ThemeViewState export let state: ThemeViewState
let layout = state.layout let layout = state.layout
@ -254,12 +255,7 @@
htmlElem={openMapButton} htmlElem={openMapButton}
> >
<div class="m-0.5 mx-1 flex cursor-pointer items-center max-[480px]:w-full sm:mx-1 md:mx-2"> <div class="m-0.5 mx-1 flex cursor-pointer items-center max-[480px]:w-full sm:mx-1 md:mx-2">
<img <Marker icons={layout.icon} size="h-4 w-4 md:h-8 md:w-8 mr-0.5 sm:mr-1 md:mr-2" ></Marker>
role="presentation"
alt=""
class="mr-0.5 block h-4 w-4 sm:mr-1 md:mr-2 md:h-8 md:w-8"
src={layout.icon}
/>
<b class="mr-1"> <b class="mr-1">
<Tr t={layout.title} /> <Tr t={layout.title} />
</b> </b>
@ -489,7 +485,8 @@
</div> </div>
<div class="flex" slot="title0"> <div class="flex" slot="title0">
<img class="block h-4 w-4" src={layout.icon} /> <Marker icons={layout.icon} size="h-4 w-4"/>
<Tr t={layout.title} /> <Tr t={layout.title} />
</div> </div>