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