forked from MapComplete/MapComplete
Rework preferences handling, improve search
This commit is contained in:
parent
b45cfcaa18
commit
4085bbc1ac
19 changed files with 438 additions and 534 deletions
|
|
@ -45,9 +45,9 @@
|
|||
|
||||
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)
|
||||
let visitedHiddenThemes: Store<MinimalLayoutInformation[]> = UserRelatedState.initDiscoveredHiddenThemes(state.osmConnection)
|
||||
.map((knownIds) => hiddenThemes.filter((theme) =>
|
||||
knownIds.has(theme.id) || state.osmConnection.userDetails.data.name === "Pieter Vander Vennet"
|
||||
knownIds.indexOf(theme.id) >= 0 || state.osmConnection.userDetails.data.name === "Pieter Vander Vennet"
|
||||
))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5,18 +5,19 @@
|
|||
/**
|
||||
* A menu, opened by a dot
|
||||
*/
|
||||
export let dotColor = "var(--background-interactive)"
|
||||
export let placement: "left" | "right" | "top" | "bottom" = "left"
|
||||
|
||||
export let open = new UIEventSource(false)
|
||||
|
||||
function toggle() {
|
||||
open.set(!open.data)
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<div class="relative" style="z-index: 50">
|
||||
<div
|
||||
class="sidebar-unit absolute right-0 top-0 collapsable normal-background button-unstyled border-2 border-gray-300"
|
||||
class="sidebar-unit absolute right-0 top-0 collapsable normal-background button-unstyled"
|
||||
class:collapsed={!$open}>
|
||||
<slot />
|
||||
</div>
|
||||
|
|
@ -31,6 +32,7 @@
|
|||
:global(.dots-menu > path) {
|
||||
fill: var(--interactive-background);
|
||||
transition: fill 350ms linear;
|
||||
cursor: pointer;
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -41,18 +43,21 @@
|
|||
.collapsable {
|
||||
max-width: 100rem;
|
||||
max-height: 100rem;
|
||||
transition: max-width 500ms ease-in-out, border 400ms linear;
|
||||
transition: border 150ms linear, max-width 500ms linear, max-height 500ms linear;
|
||||
overflow: hidden;
|
||||
flex-wrap: nowrap;
|
||||
text-wrap: none;
|
||||
width: max-content;
|
||||
box-shadow: #ccc ;
|
||||
white-space: nowrap;
|
||||
border: 1px solid var(--button-background);
|
||||
}
|
||||
|
||||
.collapsed {
|
||||
max-width: 0;
|
||||
border: 2px solid #00000000
|
||||
max-height: 0;
|
||||
border: 2px solid #00000000;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -188,18 +188,4 @@ export default class MoreScreen {
|
|||
return `${linkPrefix}`
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives all the IDs of the hidden themes which were previously visited
|
||||
* @param osmConnection
|
||||
*/
|
||||
public static knownHiddenThemes(osmConnection: OsmConnection): Store<Set<string>> {
|
||||
const prefix = "mapcomplete-hidden-theme-"
|
||||
const userPreferences = osmConnection.preferencesHandler.preferences
|
||||
return userPreferences.map((preferences) =>
|
||||
new Set<string>(
|
||||
Object.keys(preferences)
|
||||
.filter((key) => key.startsWith(prefix))
|
||||
.map((key) => key.substring(prefix.length, key.length - "-enabled".length))
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
import { Store, UIEventSource } from "../../Logic/UIEventSource"
|
||||
import SimpleMetaTaggers from "../../Logic/SimpleMetaTagger"
|
||||
import LayerConfig from "../../Models/ThemeConfig/LayerConfig"
|
||||
import Searchbar from "../Base/Searchbar.svelte"
|
||||
import Translations from "../i18n/Translations"
|
||||
|
||||
export let tags: UIEventSource<Record<string, any>>
|
||||
export let tagKeys = tags.map((tgs) => (tgs === undefined ? [] : Object.keys(tgs)))
|
||||
|
|
@ -31,9 +33,11 @@
|
|||
|
||||
const metaKeys: string[] = [].concat(...SimpleMetaTaggers.metatags.map((k) => k.keys))
|
||||
let allCalculatedTags = new Set<string>([...calculatedTags, ...metaKeys])
|
||||
let search = new UIEventSource<string>("")
|
||||
</script>
|
||||
|
||||
<section>
|
||||
<Searchbar value={search} placeholder={Translations.T("Search a key")}></Searchbar>
|
||||
<table class="zebra-table break-all">
|
||||
<tr>
|
||||
<th>Key</th>
|
||||
|
|
@ -43,7 +47,7 @@
|
|||
<th colspan="2">Normal tags</th>
|
||||
</tr>
|
||||
{#each $tagKeys as key}
|
||||
{#if !allCalculatedTags.has(key)}
|
||||
{#if !allCalculatedTags.has(key) && ($search?.length === 0 || key.toLowerCase().indexOf($search.toLowerCase()) >= 0)}
|
||||
<tr>
|
||||
<td>{key}</td>
|
||||
<td style="width: 75%">
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
if (entry.feature?.properties?.id) {
|
||||
layer = state.layout.getMatchingLayer(entry.feature.properties)
|
||||
tags = state.featureProperties.getStore(entry.feature.properties.id)
|
||||
descriptionTr = layer.tagRenderings.find(tr => tr.labels.indexOf("description") >= 0)
|
||||
descriptionTr = layer?.tagRenderings?.find(tr => tr.labels.indexOf("description") >= 0)
|
||||
}
|
||||
|
||||
let dispatch = createEventDispatcher<{ select }>()
|
||||
|
|
@ -47,7 +47,7 @@
|
|||
if (entry.feature?.properties?.id) {
|
||||
state.selectedElement.set(entry.feature)
|
||||
}
|
||||
state.searchState.recentlySearched.addSelected(entry)
|
||||
state.userRelatedState.recentlyVisitedSearch.add(entry)
|
||||
dispatch("select")
|
||||
}
|
||||
</script>
|
||||
|
|
@ -81,11 +81,11 @@
|
|||
</div>
|
||||
<div class="flex flex-wrap gap-x-2">
|
||||
|
||||
{#if descriptionTr}
|
||||
{#if descriptionTr && tags}
|
||||
<TagRenderingAnswer defaultSize="subtle" noIcons={true} config={descriptionTr} {tags} {state}
|
||||
selectedElement={entry.feature} {layer} />
|
||||
{/if}
|
||||
{#if descriptionTr && entry.description}
|
||||
{#if descriptionTr && tags && entry.description}
|
||||
–
|
||||
{/if}
|
||||
{#if entry.description}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@
|
|||
|
||||
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))
|
||||
let recentlySeen: UIEventSource<GeocodeResult[]> = state.searchState.recentlySearched.seenThisSession
|
||||
let recentThemes = state.userRelatedState.recentlyVisitedThemes.mapD(thms => thms.filter(th => th !== state.layout.id).slice(0, 6))
|
||||
let recentlySeen: Store<GeocodeResult[]> = state.userRelatedState.recentlyVisitedSearch.value
|
||||
let recentThemes = state.userRelatedState.recentlyVisitedThemes.value.map(themes => themes.filter(th => th.id !== state.layout.id).slice(0, 6))
|
||||
let allowOtherThemes = state.featureSwitches.featureSwitchBackToThemeOverview
|
||||
let searchTerm = state.searchState.searchTerm
|
||||
let results = state.searchState.suggestions
|
||||
|
|
@ -97,7 +97,7 @@
|
|||
<Tr t={Translations.t.general.search.recents} />
|
||||
</h3>
|
||||
<DotMenu>
|
||||
<button on:click={() => {state.searchState.recentlySearched.seenThisSession.set([])}}>
|
||||
<button on:click={() => {state.userRelatedState.recentlyVisitedSearch.clear()}}>
|
||||
<TrashIcon />
|
||||
Delete search history
|
||||
</button>
|
||||
|
|
@ -121,7 +121,7 @@
|
|||
<Tr t={Translations.t.general.search.recentThemes} />
|
||||
</h3>
|
||||
<DotMenu>
|
||||
<button on:click={() => {state.userRelatedState.recentlyVisitedThemes.set([])}}>
|
||||
<button on:click={() => {state.userRelatedState.recentlyVisitedThemes.clear()}}>
|
||||
<TrashIcon />
|
||||
Delete earlier visited themes
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,7 @@
|
|||
import { Store, UIEventSource } from "../Logic/UIEventSource"
|
||||
import BaseUIElement from "./BaseUIElement"
|
||||
import LayoutConfig, { MinimalLayoutInformation } from "../Models/ThemeConfig/LayoutConfig"
|
||||
import {
|
||||
FeatureSource,
|
||||
IndexedFeatureSource,
|
||||
WritableFeatureSource
|
||||
} from "../Logic/FeatureSource/FeatureSource"
|
||||
import LayoutConfig from "../Models/ThemeConfig/LayoutConfig"
|
||||
import { FeatureSource, IndexedFeatureSource, WritableFeatureSource } from "../Logic/FeatureSource/FeatureSource"
|
||||
import { OsmConnection } from "../Logic/Osm/OsmConnection"
|
||||
import { Changes } from "../Logic/Osm/Changes"
|
||||
import { ExportableMap, MapProperties } from "../Models/MapProperties"
|
||||
|
|
@ -18,7 +14,6 @@ import LayerConfig from "../Models/ThemeConfig/LayerConfig"
|
|||
import FeatureSwitchState from "../Logic/State/FeatureSwitchState"
|
||||
import { MenuState } from "../Models/MenuState"
|
||||
import OsmObjectDownloader from "../Logic/Osm/OsmObjectDownloader"
|
||||
import { RasterLayerPolygon } from "../Models/RasterLayers"
|
||||
import { ImageUploadManager } from "../Logic/ImageProviders/ImageUploadManager"
|
||||
import { OsmTags } from "../Models/OsmFeature"
|
||||
import FavouritesFeatureSource from "../Logic/FeatureSource/Sources/FavouritesFeatureSource"
|
||||
|
|
@ -30,6 +25,8 @@ import { Map as MlMap } from "maplibre-gl"
|
|||
import ShowDataLayer from "./Map/ShowDataLayer"
|
||||
import { CombinedFetcher } from "../Logic/Web/NearbyImagesSearch"
|
||||
import SearchState from "../Logic/State/SearchState"
|
||||
import UserRelatedState, { OptionallySyncedHistory } from "../Logic/State/UserRelatedState"
|
||||
import GeocodeResult from "./Search/GeocodeResult.svelte"
|
||||
|
||||
/**
|
||||
* The state needed to render a special Visualisation.
|
||||
|
|
@ -80,15 +77,7 @@ export interface SpecialVisualizationState {
|
|||
readonly fullNodeDatabase?: FullNodeDatabaseSource
|
||||
|
||||
readonly perLayer: ReadonlyMap<string, GeoIndexedStoreForLayer>
|
||||
readonly userRelatedState: {
|
||||
readonly imageLicense: UIEventSource<string>
|
||||
readonly showTags: UIEventSource<"no" | undefined | "always" | "yes" | "full">
|
||||
readonly mangroveIdentity: MangroveIdentity
|
||||
readonly showAllQuestionsAtOnce: UIEventSource<boolean>
|
||||
readonly preferencesAsTags: UIEventSource<Record<string, string>>
|
||||
readonly language: UIEventSource<string>
|
||||
readonly recentlyVisitedThemes: Store<string[]>
|
||||
}
|
||||
readonly userRelatedState: UserRelatedState
|
||||
|
||||
readonly imageUploadManager: ImageUploadManager
|
||||
|
||||
|
|
|
|||
|
|
@ -2101,6 +2101,23 @@ export default class SpecialVisualizations {
|
|||
})
|
||||
},
|
||||
},
|
||||
{
|
||||
funcName:"clear_all",
|
||||
docs: "Clears all user preferences",
|
||||
needsUrls: [],
|
||||
args: [
|
||||
{
|
||||
name: "text",
|
||||
doc: "Text to show on the button"
|
||||
}
|
||||
],
|
||||
constr(state: SpecialVisualizationState, tagSource: UIEventSource<Record<string, string>>, argument: string[], feature: Feature, layer: LayerConfig): BaseUIElement {
|
||||
const text = argument[0]
|
||||
return new SubtleButton(undefined, text).onClick(() => {
|
||||
state.osmConnection.preferencesHandler.ClearPreferences()
|
||||
})
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
specialVisualizations.push(new AutoApplyButton(specialVisualizations))
|
||||
|
|
|
|||
|
|
@ -1,40 +1,3 @@
|
|||
<script lang="ts">
|
||||
import OHTable from "./InputElement/Helpers/OpeningHours/OHTable.svelte"
|
||||
import { UIEventSource } from "../Logic/UIEventSource"
|
||||
import type { OpeningHour } from "./OpeningHours/OpeningHours"
|
||||
export let value: UIEventSource<OpeningHour[]> = new UIEventSource<OpeningHour[]>([
|
||||
{
|
||||
weekday: 3,
|
||||
startMinutes: 0,
|
||||
endMinutes: 0,
|
||||
startHour: 12,
|
||||
endHour: 16
|
||||
},
|
||||
{
|
||||
weekday: 0,
|
||||
startMinutes: 0,
|
||||
endMinutes: 0,
|
||||
startHour: 0,
|
||||
endHour: 24
|
||||
},
|
||||
{
|
||||
weekday: 1,
|
||||
startMinutes: 0,
|
||||
endMinutes: 0,
|
||||
startHour: 1,
|
||||
endHour: 24
|
||||
},
|
||||
{
|
||||
weekday: 2,
|
||||
startMinutes: 0,
|
||||
endMinutes: 0,
|
||||
startHour: 12,
|
||||
endHour: 24
|
||||
}
|
||||
])
|
||||
|
||||
</script>
|
||||
|
||||
<main >
|
||||
<OHTable {value}/>
|
||||
</main>
|
||||
|
|
|
|||
|
|
@ -60,7 +60,6 @@
|
|||
let compass = Orientation.singleton.alpha
|
||||
let compassLoaded = Orientation.singleton.gotMeasurement
|
||||
let hash = Hash.hash
|
||||
let previewedImage = state.previewedImage
|
||||
let addNewFeatureMode = state.userRelatedState.addNewFeatureMode
|
||||
let gpsAvailable = state.geolocation.geolocationState.gpsAvailable
|
||||
let gpsButtonAriaLabel = state.geolocation.geolocationState.gpsStateExplanation
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue