Merge master

This commit is contained in:
Pieter Vander Vennet 2025-04-08 14:52:32 +02:00
commit 9ab53188ec
5 changed files with 46 additions and 13 deletions

View file

@ -13,7 +13,12 @@
"ca": "Les tombes (i les tombes) indiquen on va ser enterrada una persona. En aquest mapa, es poden gravar i es pot fer un enllaç a la Viquipèdia" "ca": "Les tombes (i les tombes) indiquen on va ser enterrada una persona. En aquest mapa, es poden gravar i es pot fer un enllaç a la Viquipèdia"
}, },
"source": { "source": {
"osmTags": "historic=tomb" "osmTags": {
"or": [
"historic=tomb",
"cemetery=grave"
]
}
}, },
"minzoom": 15, "minzoom": 15,
"title": { "title": {
@ -44,16 +49,15 @@
"presets": [ "presets": [
{ {
"title": { "title": {
"en": "a tombstone", "en": "a grave",
"de": "ein Grabstein", "nl": "een grafsteen",
"es": "una lápida", "de": "ein Grabstein"
"ca": "una làpida"
}, },
"tags": [ "tags": [
"historic=tomb" "cemetery=grave"
], ],
"description": { "description": {
"en": "A tombstone is a physical object which indicates that one or more persons are buried here. It generally has the name, birth date and death date of the person or persons as inscription.", "en": "A grave is a physical object which indicates that one or more persons are buried here. It generally has the name, birth date and death date of the person or persons as inscription.",
"de": "Ein Grabstein ist ein physischer Gegenstand, der anzeigt, dass eine oder mehrere Personen hier begraben sind. Er trägt in der Regel den Namen, das Geburts- und das Sterbedatum der Person oder Personen als Inschrift.", "de": "Ein Grabstein ist ein physischer Gegenstand, der anzeigt, dass eine oder mehrere Personen hier begraben sind. Er trägt in der Regel den Namen, das Geburts- und das Sterbedatum der Person oder Personen als Inschrift.",
"uk": "Надгробок - це фізичний об'єкт, який вказує на те, що тут похована одна або кілька осіб. Як правило, на ньому викарбувано ім'я, дату народження та дату смерті особи чи осіб.", "uk": "Надгробок - це фізичний об'єкт, який вказує на те, що тут похована одна або кілька осіб. Як правило, на ньому викарбувано ім'я, дату народження та дату смерті особи чи осіб.",
"es": "Una lápida es un objeto físico que indica que una o más personas están enterradas aquí. Generalmente tiene el nombre, la fecha de nacimiento y la fecha de defunción de la persona o personas como inscripción.", "es": "Una lápida es un objeto físico que indica que una o más personas están enterradas aquí. Generalmente tiene el nombre, la fecha de nacimiento y la fecha de defunción de la persona o personas como inscripción.",

View file

@ -222,7 +222,7 @@
} }
], ],
"tagRenderings": [ "tagRenderings": [
"images", "images_no_blur",
{ {
"id": "plantnet", "id": "plantnet",
"render": "{plantnet_detection()}" "render": "{plantnet_detection()}"

View file

@ -70,7 +70,17 @@ export default class SearchState {
const themeSearch = ThemeSearchIndex.fromState(state) const themeSearch = ThemeSearchIndex.fromState(state)
this.themeSuggestions = this.searchTerm.mapD( this.themeSuggestions = this.searchTerm.mapD(
(query) => themeSearch.data.search(query, 3), (query) => {
const results = themeSearch.data.search(query, 3)
const deduped: MinimalThemeInformation[] = []
for (const result of results) {
if (deduped.some(th => th.id === result.id)) {
continue
}
deduped.push(result)
}
return deduped
},
[themeSearch] [themeSearch]
) )

View file

@ -14,6 +14,16 @@
export let state: { osmConnection: OsmConnection } export let state: { osmConnection: OsmConnection }
export let onlyIcons: boolean = false export let onlyIcons: boolean = false
export let hasSelection: boolean = true export let hasSelection: boolean = true
let themesFiltered: MinimalThemeInformation[] = []
for (const theme of themes) {
if (!theme) {
continue
}
if (themesFiltered.some(th => th.id === theme.id)) {
continue
}
themesFiltered.push(theme)
}
</script> </script>
<section class="w-full"> <section class="w-full">
@ -23,7 +33,7 @@
? "flex flex-wrap items-center justify-center gap-x-2" ? "flex flex-wrap items-center justify-center gap-x-2"
: "theme-list my-2 gap-4 md:grid md:grid-flow-row md:grid-cols-2 lg:grid-cols-3"} : "theme-list my-2 gap-4 md:grid md:grid-flow-row md:grid-cols-2 lg:grid-cols-3"}
> >
{#each Utils.NoNull(themes) as theme (theme.id)} {#each Utils.NoNull(themesFiltered) as theme (theme.id)}
<ThemeButton {theme} {state} iconOnly={onlyIcons}> <ThemeButton {theme} {state} iconOnly={onlyIcons}>
{#if $search && hasSelection && themes?.[0] === theme} {#if $search && hasSelection && themes?.[0] === theme}
<span class="thanks hidden-on-mobile" aria-hidden="true"> <span class="thanks hidden-on-mobile" aria-hidden="true">

View file

@ -11,12 +11,21 @@
import { TrashIcon } from "@babeard/svelte-heroicons/mini" import { TrashIcon } from "@babeard/svelte-heroicons/mini"
import { CogIcon } from "@rgossiaux/svelte-heroicons/solid" import { CogIcon } from "@rgossiaux/svelte-heroicons/solid"
import Tr from "../Base/Tr.svelte" import Tr from "../Base/Tr.svelte"
import { Utils } from "../../Utils.ts" import { MinimalThemeInformation } from "../../Models/ThemeConfig/ThemeConfig"
export let state: SpecialVisualizationState export let state: SpecialVisualizationState
let searchTerm = state.searchState.searchTerm let searchTerm = state.searchState.searchTerm
let recentThemes = state.userRelatedState.recentlyVisitedThemes.value.map((themes) => let recentThemes = state.userRelatedState.recentlyVisitedThemes.value.map((themes) => {
Utils.Dedup(themes.filter((th) => th !== state.theme.id).slice(0, 6)) const recent = themes.filter((th) => th !== state.theme.id).slice(0, 6)
const deduped: MinimalThemeInformation[] = []
for (const theme of recent) {
if (deduped.some(th => th.id === theme.id)) {
continue
}
deduped.push(theme)
}
return deduped
}
) )
let themeResults = state.searchState.themeSuggestions let themeResults = state.searchState.themeSuggestions