Search results: add menu, update searchers
This commit is contained in:
parent
9e0ae3321f
commit
ee2b3ce329
10 changed files with 88 additions and 41 deletions
|
@ -78,9 +78,6 @@ export class SummaryTileSource extends DynamicTileSource {
|
|||
isActive?: Store<boolean>
|
||||
}
|
||||
) {
|
||||
if(layers.length === 0){
|
||||
return
|
||||
}
|
||||
const layersSummed = layers.join("+")
|
||||
const zDiff = 2
|
||||
super(
|
||||
|
|
|
@ -61,6 +61,7 @@ export class RecentSearch {
|
|||
const [lon, lat] = GeoOperations.centerpointCoordinates(selected)
|
||||
const entry = <GeocodeResult>{
|
||||
feature: selected,
|
||||
display_name: selected.properties.name ?? selected.properties.alt_name ?? selected.properties.local_name,
|
||||
osm_id, osm_type,
|
||||
lon, lat,
|
||||
}
|
||||
|
|
|
@ -138,20 +138,24 @@ export default class SearchState {
|
|||
if (query === "") {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
|
||||
const geolocationState = this.state.geolocation.geolocationState
|
||||
const searcher = this.state.searchState.geosearch
|
||||
const bounds = this.state.mapProperties.bounds
|
||||
const bbox = this.state.mapProperties.bounds.data
|
||||
try {
|
||||
this.isSearching.set(true)
|
||||
geolocationState?.allowMoving.setData(true)
|
||||
geolocationState?.requestMoment.setData(undefined) // If the GPS is still searching for a fix, we say that we don't want tozoom to it anymore
|
||||
const result = await searcher.search(query, { bbox })
|
||||
if (result.length == 0) {
|
||||
this.feedback.set(Translations.t.general.search.nothing)
|
||||
return false
|
||||
let poi: SearchResult
|
||||
if(this.suggestions.data){
|
||||
poi = this.suggestions.data[0]
|
||||
}else{
|
||||
const results = GeocodingUtils.mergeSimilarResults([].concat(...await Promise.all(this.locationSearchers.map(ls => ls.search(query, { bbox: bounds.data })))))
|
||||
poi = results[0]
|
||||
}
|
||||
const poi = result[0]
|
||||
|
||||
if (poi.category === "theme") {
|
||||
const theme = <MinimalLayoutInformation>poi.payload
|
||||
const url = MoreScreen.createUrlFor(theme)
|
||||
|
|
|
@ -26,7 +26,6 @@ export default class Constants {
|
|||
"last_click",
|
||||
"favourite",
|
||||
"summary",
|
||||
"search"
|
||||
] as const
|
||||
/**
|
||||
* Special layers which are not included in a theme by default
|
||||
|
@ -39,7 +38,8 @@ export default class Constants {
|
|||
"import_candidate",
|
||||
"usersettings",
|
||||
"icons",
|
||||
"filters"
|
||||
"filters",
|
||||
"search"
|
||||
] as const
|
||||
/**
|
||||
* Layer IDs of layers which have special properties through built-in hooks
|
||||
|
|
|
@ -554,6 +554,10 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
this.previewedImage.setData(undefined)
|
||||
return
|
||||
}
|
||||
if(this.selectedElement.data){
|
||||
this.selectedElement.setData(undefined)
|
||||
return
|
||||
}
|
||||
if (this.searchState.showSearchDrawer.data){
|
||||
this.searchState.showSearchDrawer.set(false)
|
||||
return
|
||||
|
@ -561,7 +565,6 @@ export default class ThemeViewState implements SpecialVisualizationState {
|
|||
if (this.guistate.closeAll()){
|
||||
return
|
||||
}
|
||||
this.selectedElement.setData(undefined)
|
||||
Zoomcontrol.resetzoom()
|
||||
this.focusOnMap()
|
||||
})
|
||||
|
|
27
src/UI/Base/DotMenu.svelte
Normal file
27
src/UI/Base/DotMenu.svelte
Normal file
|
@ -0,0 +1,27 @@
|
|||
<script lang="ts">
|
||||
import DotsCircleHorizontal from "@rgossiaux/svelte-heroicons/solid/DotsCircleHorizontal"
|
||||
import { Dropdown } from "flowbite-svelte"
|
||||
import { TrashIcon } from "@babeard/svelte-heroicons/mini"
|
||||
import SidebarUnit from "./SidebarUnit.svelte"
|
||||
import { UIEventSource } from "../../Logic/UIEventSource"
|
||||
|
||||
/**
|
||||
* A menu, opened by a dot
|
||||
*/
|
||||
export let dotColor = "var(--background-interactive)"
|
||||
export let placement: "left" | "right" | "top" | "bottom" = "left"
|
||||
|
||||
export let isOpen : UIEventSource<boolean> = new UIEventSource<boolean>(false)
|
||||
let _isOpen = isOpen.data
|
||||
$: {
|
||||
console.log("is open?", _isOpen)
|
||||
isOpen.set(_isOpen)
|
||||
}
|
||||
</script>
|
||||
|
||||
<DotsCircleHorizontal class="w-6 h-6 dots-menu-themes transition-colors" color={$isOpen ? "black": "var(--interactive-background)"} />
|
||||
<Dropdown placement="left" bind:open={_isOpen} triggeredBy=".dots-menu-themes" containerClass="p-1 border border-2 border-gray button-unstyled">
|
||||
<SidebarUnit>
|
||||
<slot />
|
||||
</SidebarUnit>
|
||||
</Dropdown>
|
|
@ -18,7 +18,7 @@
|
|||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
:global(.sidebar-button svg, .sidebar-button img) {
|
||||
:global(.sidebar-button svg, .sidebar-button img, .sidebar-unit > button img, .sidebar-unit > button svg) {
|
||||
width: 1.5rem;
|
||||
height: 1.5rem;
|
||||
margin-right: 0.5rem;
|
||||
|
@ -32,7 +32,7 @@
|
|||
}
|
||||
|
||||
|
||||
:global(.sidebar-button, .sidebar-unit > a) {
|
||||
:global(.sidebar-button, .sidebar-unit > a, .sidebar-unit > button) {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 0.25rem !important;
|
||||
|
@ -42,12 +42,12 @@
|
|||
text-align: start;
|
||||
}
|
||||
|
||||
:global(.sidebar-button > svg , .sidebar-button > img, .sidebar-unit > a img, .sidebar-unit > a svg) {
|
||||
:global(.sidebar-button > svg , .sidebar-button > img, .sidebar-unit > a img, .sidebar-unit > a svg, .sidebar-unit > button svg, .sidebar-unit > button img) {
|
||||
margin-right: 0.5rem;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
:global(.sidebar-button:hover, .sidebar-unit > a:hover) {
|
||||
:global(.sidebar-button:hover, .sidebar-unit > a:hover, .sidebar-unit > button:hover) {
|
||||
background: var(--low-interaction-background) !important;
|
||||
}
|
||||
|
||||
|
|
|
@ -158,11 +158,11 @@
|
|||
|
||||
<Page {onlyLink} shown={pg.about_theme}>
|
||||
<svelte:fragment slot="link">
|
||||
<Marker icons={layout.icon} />
|
||||
<Marker size="h-6 w-6 mr-2" icons={layout.icon} />
|
||||
<Tr t={t.showIntroduction} />
|
||||
</svelte:fragment>
|
||||
<svelte:fragment slot="header">
|
||||
<Marker size="h-6 w-6 mr-2" icons={layout.icon} />
|
||||
<Marker size="h-8 w-8 mr-3" icons={layout.icon} />
|
||||
<Tr t={layout.title} />
|
||||
</svelte:fragment>
|
||||
<ThemeIntroPanel {state} />
|
||||
|
|
|
@ -15,6 +15,10 @@
|
|||
import ThemeResult from "./ThemeResult.svelte"
|
||||
import SidebarUnit from "../Base/SidebarUnit.svelte"
|
||||
import { TrashIcon } from "@babeard/svelte-heroicons/mini"
|
||||
import { Dropdown, DropdownItem } from "flowbite-svelte"
|
||||
import DotsCircleHorizontal from "@rgossiaux/svelte-heroicons/solid/DotsCircleHorizontal"
|
||||
import DotMenu from "../Base/DotMenu.svelte"
|
||||
import { CogIcon } from "@rgossiaux/svelte-heroicons/solid"
|
||||
|
||||
export let state: ThemeViewState
|
||||
let activeFilters: Store<ActiveFilter[]> = state.layerState.activeFilters.map(fs => fs.filter(f => Constants.priviliged_layers.indexOf(<any>f.layer.id) < 0))
|
||||
|
@ -90,7 +94,7 @@
|
|||
<h3 class="m-2">
|
||||
<Tr t={Translations.t.general.search.recents} />
|
||||
</h3>
|
||||
{#each $recentlySeen as entry}
|
||||
{#each $recentlySeen as entry (entry)}
|
||||
<SearchResultSvelte {entry} {state} on:select />
|
||||
{/each}
|
||||
<button class="as-link flex self-end" on:click={() => {recentlySeen.set([])}}>
|
||||
|
@ -102,19 +106,29 @@
|
|||
|
||||
{#if $searchTerm.length === 0 && $recentThemes?.length > 0 && $allowOtherThemes}
|
||||
<SidebarUnit>
|
||||
<div class="flex w-full justify-between">
|
||||
|
||||
<h3 class="m-2">
|
||||
<Tr t={Translations.t.general.search.recentThemes} />
|
||||
</h3>
|
||||
<DotMenu>
|
||||
<button on:click={() => {state.userRelatedState.recentlyVisitedThemes.set([])}}>
|
||||
<TrashIcon />
|
||||
Delete earlier visited themes
|
||||
</button>
|
||||
<button>
|
||||
<CogIcon/>
|
||||
Edit sync settings
|
||||
</button>
|
||||
</DotMenu>
|
||||
</div>
|
||||
{#each $recentThemes as themeId (themeId)}
|
||||
<SearchResultSvelte
|
||||
entry={{payload: MoreScreen.officialThemesById.get(themeId), osm_id: themeId, category: "theme"}}
|
||||
{state}
|
||||
on:select />
|
||||
{/each}
|
||||
<button class="as-link flex self-end" on:click={() => {state.userRelatedState.recentlyVisitedThemes.set([])}}>
|
||||
<TrashIcon class="w-4 h-4"/>
|
||||
Delete history
|
||||
</button>
|
||||
|
||||
</SidebarUnit>
|
||||
{/if}
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
export let entry: MinimalLayoutInformation
|
||||
let otherTheme = entry
|
||||
</script>
|
||||
|
||||
<a href={MoreScreen.createUrlFor(otherTheme, false)}
|
||||
{#if entry}
|
||||
<a href={MoreScreen.createUrlFor(otherTheme)}
|
||||
class="flex items-center p-2 w-full gap-y-2 rounded-xl searchresult">
|
||||
|
||||
<Icon icon={otherTheme.icon} clss="w-6 h-6 m-1" />
|
||||
|
@ -20,3 +20,4 @@
|
|||
<!--<Tr t={new Translation(otherTheme.shortDescription)} /> -->
|
||||
</div>
|
||||
</a>
|
||||
{/if}
|
||||
|
|
Loading…
Reference in a new issue