Feature: add favourite

This commit is contained in:
Pieter Vander Vennet 2023-11-22 19:39:19 +01:00
parent a32ab16a5e
commit f9827dd6ae
68 changed files with 1641 additions and 885 deletions

View file

@ -23,6 +23,7 @@ export default class Constants {
"gps_track",
"range",
"last_click",
"favourite",
] as const
/**
* Special layers which are not included in a theme by default
@ -131,6 +132,8 @@ export default class Constants {
"clock",
"invalid",
"close",
"heart",
"heart_outline",
] as const
public static readonly defaultPinIcons: string[] = <any>Constants._defaultPinIcons

View file

@ -26,7 +26,7 @@ import predifined_filters from "../../../../assets/layers/filters/filters.json"
import { TagConfigJson } from "../Json/TagConfigJson"
import PointRenderingConfigJson, { IconConfigJson } from "../Json/PointRenderingConfigJson"
import ValidationUtils from "./ValidationUtils"
import { RenderingSpecification, SpecialVisualization } from "../../../UI/SpecialVisualization"
import { RenderingSpecification } from "../../../UI/SpecialVisualization"
import { QuestionableTagRenderingConfigJson } from "../Json/QuestionableTagRenderingConfigJson"
import { ConfigMeta } from "../../../UI/Studio/configMeta"
import LineRenderingConfigJson from "../Json/LineRenderingConfigJson"
@ -639,6 +639,13 @@ export class AddEditingElements extends DesugaringStep<LayerConfigJson> {
json.tagRenderings.push(this._desugaring.tagRenderings.get("last_edit"))
}
if (!usedSpecialFunctions.has("favourite_status")) {
json.tagRenderings.push({
id: "favourite_status",
render: { "*": "{favourite_status()}" },
})
}
if (!usedSpecialFunctions.has("all_tags")) {
const trc: QuestionableTagRenderingConfigJson = {
id: "all-tags",
@ -1193,6 +1200,31 @@ class ExpandMarkerRenderings extends DesugaringStep<IconConfigJson> {
}
}
class AddFavouriteBadges extends DesugaringStep<LayerConfigJson> {
constructor() {
super(
"Adds the favourite heart to the title and the rendering badges",
[],
"AddFavouriteBadges"
)
}
convert(json: LayerConfigJson, context: ConversionContext): LayerConfigJson {
if (json.id === "favourite") {
return json
}
const pr = json.pointRendering?.[0]
if (pr) {
pr.iconBadges ??= []
if (!pr.iconBadges.some((ti) => ti.if === "_favourite=yes")) {
pr.iconBadges.push({ if: "_favourite=yes", then: "circle:white;heart:red" })
}
}
return json
}
}
export class AddRatingBadge extends DesugaringStep<LayerConfigJson> {
constructor() {
super(
@ -1206,6 +1238,10 @@ export class AddRatingBadge extends DesugaringStep<LayerConfigJson> {
if (!json.tagRenderings) {
return json
}
if (json.titleIcons.some((ti) => ti === "icons.rating" || ti["id"] === "rating")) {
// already added
return json
}
const specialVis: Exclude<RenderingSpecification, string>[] = <
Exclude<RenderingSpecification, string>[]
@ -1247,6 +1283,7 @@ export class PrepareLayer extends Fuse<LayerConfigJson> {
),
new SetDefault("titleIcons", ["icons.defaults"]),
new AddRatingBadge(),
new AddFavouriteBadges(),
new On(
"titleIcons",
(layer) =>

View file

@ -968,7 +968,7 @@ export class ValidateTagRenderings extends Fuse<TagRenderingConfigJson> {
"Various validation on tagRenderingConfigs",
new DetectShadowedMappings(layerConfig),
new DetectConflictingAddExtraTags(),
new DetectNonErasedKeysInMappings(),
// new DetectNonErasedKeysInMappings(),
new DetectMappingsWithImages(doesImageExist),
new On("render", new ValidatePossibleLinks()),
new On("question", new ValidatePossibleLinks()),

View file

@ -305,6 +305,9 @@ export default class LayoutConfig implements LayoutInformation {
}
for (const layer of this.layers) {
if (!layer.source) {
if (layer.isShown?.matchesProperties(tags)) {
return layer
}
continue
}
if (layer.source.osmTags.matchesProperties(tags)) {

View file

@ -58,6 +58,7 @@ import { PreferredRasterLayerSelector } from "../Logic/Actors/PreferredRasterLay
import { ImageUploadManager } from "../Logic/ImageProviders/ImageUploadManager"
import { Imgur } from "../Logic/ImageProviders/Imgur"
import NearbyFeatureSource from "../Logic/FeatureSource/Sources/NearbyFeatureSource"
import FavouritesFeatureSource from "../Logic/FeatureSource/Sources/FavouritesFeatureSource"
/**
*
@ -96,10 +97,11 @@ export default class ThemeViewState implements SpecialVisualizationState {
readonly indexedFeatures: IndexedFeatureSource & LayoutSource
readonly currentView: FeatureSource<Feature<Polygon>>
readonly featuresInView: FeatureSource
readonly favourites: FavouritesFeatureSource
/**
* Contains a few (<10) >features that are near the center of the map.
*/
readonly closestFeatures: FeatureSource
readonly closestFeatures: NearbyFeatureSource
readonly newFeatures: WritableFeatureSource
readonly layerState: LayerState
readonly perLayer: ReadonlyMap<string, GeoIndexedStoreForLayer>
@ -220,8 +222,6 @@ export default class ThemeViewState implements SpecialVisualizationState {
this.fullNodeDatabase
)
this.indexedFeatures = layoutSource
let currentViewIndex = 0
const empty = []
this.currentView = new StaticFeatureSource(
@ -242,13 +242,19 @@ export default class ThemeViewState implements SpecialVisualizationState {
this.featuresInView = new BBoxFeatureSource(layoutSource, this.mapProperties.bounds)
this.dataIsLoading = layoutSource.isLoading
this.indexedFeatures = layoutSource
this.featureProperties = new FeaturePropertiesStore(layoutSource)
this.favourites = new FavouritesFeatureSource(
this.osmConnection,
this.featureProperties,
layoutSource,
layout
)
const indexedElements = this.indexedFeatures
this.featureProperties = new FeaturePropertiesStore(indexedElements)
this.changes = new Changes(
{
dryRun: this.featureSwitches.featureSwitchIsTesting,
allElements: indexedElements,
allElements: layoutSource,
featurePropertiesStore: this.featureProperties,
osmConnection: this.osmConnection,
historicalUserLocations: this.geolocation.historicalUserLocations,
@ -258,7 +264,7 @@ export default class ThemeViewState implements SpecialVisualizationState {
this.historicalUserLocations = this.geolocation.historicalUserLocations
this.newFeatures = new NewGeometryFromChangesFeatureSource(
this.changes,
indexedElements,
layoutSource,
this.featureProperties
)
layoutSource.addSource(this.newFeatures)
@ -627,7 +633,10 @@ export default class ThemeViewState implements SpecialVisualizationState {
)
),
current_view: this.currentView,
favourite: this.favourites,
}
this.closestFeatures.registerSource(specialLayers.favourite, "favourite")
if (this.layout?.lockLocation) {
const bbox = new BBox(this.layout.lockLocation)
this.mapProperties.maxbounds.setData(bbox)
@ -663,12 +672,16 @@ export default class ThemeViewState implements SpecialVisualizationState {
rangeIsDisplayed?.syncWith(this.featureSwitches.featureSwitchIsTesting, true)
}
// enumarate all 'normal' layers and match them with the appropriate 'special' layer - if applicable
this.layerState.filteredLayers.forEach((flayer) => {
const id = flayer.layerDef.id
const features: FeatureSource = specialLayers[id]
if (features === undefined) {
return
}
if (id === "favourite") {
console.log("Matching special layer", id, flayer)
}
this.featureProperties.trackFeatureSource(features)
new ShowDataLayer(this.map, {