From b43c4f3cfb1b8eceff75eaba075e5a71f5812009 Mon Sep 17 00:00:00 2001 From: Anton Tranelis Date: Sun, 4 Feb 2024 12:01:16 +0100 Subject: [PATCH] tags url parameter --- src/Components/Map/Layer.tsx | 11 ++---- .../Subcomponents/Controls/SearchControl.tsx | 11 ++++-- .../Subcomponents/Controls/TagsControl.tsx | 2 +- .../ItemPopupComponents/HeaderView.tsx | 3 +- src/Components/Map/Tags.tsx | 21 ++++++++++- src/Components/Map/UtopiaMap.tsx | 34 +++++++++++------ src/Components/Map/hooks/useFilter.tsx | 37 ++++++++++++++++--- 7 files changed, 89 insertions(+), 30 deletions(-) diff --git a/src/Components/Map/Layer.tsx b/src/Components/Map/Layer.tsx index db3ca29d..5e424b4b 100644 --- a/src/Components/Map/Layer.tsx +++ b/src/Components/Map/Layer.tsx @@ -74,7 +74,8 @@ export const Layer = ({ popupopen: (e) => { const item = Object.entries(leafletRefs).find(r => r[1].popup == e.popup)?.[1].item; if (item?.layer?.name == name && window.location.pathname.split("/")[2] != item.id) { - window.history.pushState({}, "", `/${name}/${item.id}`) + let params = new URLSearchParams(window.location.search); + window.history.pushState({}, "", `/${name}/${item.id}`+ `${params.toString() !== "" ? `?${params}` : ""}`) let title = ""; if (item.name) title = item.name; else if (item.layer?.itemNameField) title = getValue(item, item.layer.itemNameField); @@ -115,10 +116,6 @@ export const Layer = ({ openPopup(); }, [leafletRefs, location]) - useEffect(() => { - console.log(`all tags loaded: ${allTagsLoaded}`); - }, [allTagsLoaded]) - useEffect(() => { if (tagsReady) { const processedTags = {}; @@ -143,7 +140,7 @@ export const Layer = ({ if (getValue(item, itemLongitudeField) && getValue(item, itemLatitudeField)) { - if (item[itemTextField]) item[itemTextField] = getValue(item, itemTextField); + if (getValue(item, itemTextField)) item[itemTextField] = getValue(item, itemTextField); else item[itemTextField] = ""; if (item?.tags) { item[itemTextField] = item[itemTextField] + '\n\n'; @@ -156,7 +153,7 @@ export const Layer = ({ } - if (allTagsLoaded && allItemsLoaded) { + if (allTagsLoaded && allItemsLoaded) { item[itemTextField].toLocaleLowerCase().match(hashTagRegex)?.map(tag => { if ((!tags.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) && !newTagsToAdd.find((t) => t.name.toLocaleLowerCase() === tag.slice(1).toLocaleLowerCase())) { const newTag = { id: crypto.randomUUID(), name: tag.slice(1).toLocaleLowerCase(), color: randomColor() }; diff --git a/src/Components/Map/Subcomponents/Controls/SearchControl.tsx b/src/Components/Map/Subcomponents/Controls/SearchControl.tsx index e4c1052e..89084a99 100644 --- a/src/Components/Map/Subcomponents/Controls/SearchControl.tsx +++ b/src/Components/Map/Subcomponents/Controls/SearchControl.tsx @@ -61,7 +61,9 @@ export const SearchControl = ({ clusterRef }) => { if (item.layer?.itemTextField) item.text = getValue(item, item.layer.itemTextField) return item.name?.toLowerCase().includes(value.toLowerCase()) || item.text?.toLowerCase().includes(value.toLowerCase()) })) - setTagsResults(tags.filter(tag => tag.name?.toLowerCase().includes(value.toLowerCase()))) + let phrase = value; + if(value.startsWith("#")) phrase = value.substring(1); + setTagsResults(tags.filter(tag => tag.name?.toLowerCase().includes(phrase.toLowerCase()))) }, 500, [value]); @@ -89,13 +91,14 @@ export const SearchControl = ({ clusterRef }) => { {value.length > 0 && } {hideSuggestions || Array.from(geoResults).length == 0 && itemsResults.length == 0 && tagsResults.length == 0 && !isGeoCoordinate(value)|| value.length == 0? "" : -
+
{tagsResults.length > 0 &&
{tagsResults.map(tag => (
{ addFilterTag(tag) - window.history.pushState({}, "", `/`) + let params = new URLSearchParams(window.location.search); + window.history.pushState({}, "", "/" + `${params? `?${params}` : ""}`); }}> #{capitalizeFirstLetter(tag.name)}
@@ -144,7 +147,7 @@ export const SearchControl = ({ clusterRef }) => {
{geo?.properties.name ? geo?.properties.name : value}
-
{geo?.properties?.city && `${capitalizeFirstLetter(geo?.properties?.city)}, `} {geo?.properties?.osm_value && geo?.properties?.osm_value !== "primary" && geo?.properties?.osm_value !== "path" && geo?.properties?.osm_value !== "secondary" && geo?.properties?.osm_value !== "residential" && geo?.properties?.osm_value !== "unclassified" && `${capitalizeFirstLetter(geo?.properties?.osm_value)}, `} {geo.properties.state && `${geo.properties.state}, `} {geo.properties.country && geo.properties.country}
+
{geo?.properties?.city && `${capitalizeFirstLetter(geo?.properties?.city)}, `} {geo?.properties?.osm_value && geo?.properties?.osm_value !== "yes" && geo?.properties?.osm_value !== "primary" && geo?.properties?.osm_value !== "path" && geo?.properties?.osm_value !== "secondary" && geo?.properties?.osm_value !== "residential" && geo?.properties?.osm_value !== "unclassified" && `${capitalizeFirstLetter(geo?.properties?.osm_value)}, `} {geo.properties.state && `${geo.properties.state}, `} {geo.properties.country && geo.properties.country}
diff --git a/src/Components/Map/Subcomponents/Controls/TagsControl.tsx b/src/Components/Map/Subcomponents/Controls/TagsControl.tsx index 7aa2823c..16973f19 100644 --- a/src/Components/Map/Subcomponents/Controls/TagsControl.tsx +++ b/src/Components/Map/Subcomponents/Controls/TagsControl.tsx @@ -12,7 +12,7 @@ export const TagsControl = () => { filterTags.map(tag =>
- +
#{capitalizeFirstLetter(tag.name)}
) diff --git a/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView.tsx b/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView.tsx index c34caaeb..e4d11549 100644 --- a/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView.tsx +++ b/src/Components/Map/Subcomponents/ItemPopupComponents/HeaderView.tsx @@ -53,7 +53,8 @@ export function HeaderView({ item, setItemFormPopup }: { } setLoading(false); map.closePopup(); - window.history.pushState({}, "", "/"); + let params = new URLSearchParams(window.location.search); + window.history.pushState({}, "", "/" + `${params? `?${params}` : ""}`); event.stopPropagation(); } diff --git a/src/Components/Map/Tags.tsx b/src/Components/Map/Tags.tsx index 22c47c08..5c24e141 100644 --- a/src/Components/Map/Tags.tsx +++ b/src/Components/Map/Tags.tsx @@ -1,7 +1,9 @@ import * as React from 'react' import { useEffect } from 'react'; import { ItemsApi, Tag } from '../../types'; -import { useSetTagData, useSetTagApi } from './hooks/useTags' +import { useSetTagData, useSetTagApi, useTags } from './hooks/useTags' +import { useLocation } from 'react-router-dom'; +import { useAddFilterTag } from './hooks/useFilter'; export function Tags({data, api} : {data?: Tag[], api?: ItemsApi}) { const setTagData = useSetTagData(); @@ -12,6 +14,23 @@ useEffect(() => { api && setTagApi(api); }, [api, data]) + +const location = useLocation(); +const addFilterTag = useAddFilterTag(); +const tags = useTags(); + + +useEffect(() => { + let params = new URLSearchParams(location.search); + let urlTags = params.get("tags"); + urlTags?.split(",").map(urlTag => { + const tag = tags.find(t => t.name.toLocaleLowerCase() === urlTag.toLocaleLowerCase()) + tag && addFilterTag(tag) + }); + +}, [location, tags]); + + return ( <> ) diff --git a/src/Components/Map/UtopiaMap.tsx b/src/Components/Map/UtopiaMap.tsx index fa2a92ea..dff494ec 100644 --- a/src/Components/Map/UtopiaMap.tsx +++ b/src/Components/Map/UtopiaMap.tsx @@ -6,19 +6,19 @@ import "./UtopiaMap.css" import { LatLng } from "leaflet"; import MarkerClusterGroup from 'react-leaflet-cluster' import AddButton from "./Subcomponents/AddButton"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import { ItemFormPopupProps } from "./Subcomponents/ItemFormPopup"; import { ItemsProvider } from "./hooks/useItems"; -import { TagsProvider } from "./hooks/useTags"; +import { TagsProvider, useAllTagsLoaded, useTags } from "./hooks/useTags"; import { LayersProvider } from "./hooks/useLayers"; -import { FilterProvider } from "./hooks/useFilter"; +import { FilterProvider, useAddFilterTag } from "./hooks/useFilter"; import { SearchControl } from "./Subcomponents/Controls/SearchControl"; import { PermissionsProvider } from "./hooks/usePermissions"; import { LeafletRefsProvider } from "./hooks/useLeafletRefs"; import { LayerControl } from "./Subcomponents/Controls/LayerControl"; import { QuestControl } from "./Subcomponents/Controls/QuestControl"; import { Control } from "./Subcomponents/Controls/Control"; -import { Outlet } from "react-router-dom"; +import { Outlet, useLocation } from "react-router-dom"; import { TagsControl } from "./Subcomponents/Controls/TagsControl"; @@ -40,25 +40,28 @@ function UtopiaMap({ children } : UtopiaMapProps) { - - let meta = document.getElementsByTagName('meta') - const [metaTags, setMetaTags] = useState>(meta); - function MapEventListener(props: MapEventListenerProps) { useMapEvents({ click: (e) => { - window.history.pushState({}, "", "/"); + let params = new URLSearchParams(window.location.search); + window.history.pushState({}, "", `/`+ `${params.toString() !== "" ? `?${params}` : ""}`) document.title = document.title.split("-")[0]; document.querySelector('meta[property="og:title"]')?.setAttribute("content", document.title); document.querySelector('meta[property="og:description"]')?.setAttribute("content", `${document.querySelector('meta[name="description"]')?.getAttribute("content")}`); - meta = metaTags; console.log(e.latlng.lat + ',' + e.latlng.lng); if (props.selectNewItemPosition != null) { props.setItemFormPopup({ layer: props.selectNewItemPosition, position: e.latlng }) props.setSelectNewItemPosition(null) } + }, + moveend: (e) => { + console.log(e); + + } + + }) return null } @@ -68,6 +71,15 @@ function UtopiaMap({ const clusterRef = React.useRef(); + const location = useLocation(); + + useEffect(() => { + let params = new URLSearchParams(location.search); + let urlPosition = params.get("position"); + + + }, [location]); + return ( <> @@ -79,7 +91,7 @@ function UtopiaMap({
- + diff --git a/src/Components/Map/hooks/useFilter.tsx b/src/Components/Map/hooks/useFilter.tsx index d62330a2..ac73bd86 100644 --- a/src/Components/Map/hooks/useFilter.tsx +++ b/src/Components/Map/hooks/useFilter.tsx @@ -2,10 +2,11 @@ import { useCallback, useReducer, createContext, useContext } from "react"; import * as React from "react"; import { LayerProps, Tag } from "../../../types"; import { useLayers } from "./useLayers"; +import { useLocation } from "react-router-dom"; type ActionType = | { type: "ADD_TAG"; tag: Tag } - | { type: "REMOVE_TAG"; id: string } + | { type: "REMOVE_TAG"; name: string } | { type: "RESET_TAGS" } | { type: "TOGGLE_LAYER"; layer: LayerProps } | { type: "ADD_LAYER"; layer: LayerProps } @@ -33,7 +34,7 @@ function useFilterManager(initialTags: Tag[]): { searchPhrase: string; visibleLayers: LayerProps[]; addFilterTag: (tag: Tag) => void; - removeFilterTag: (id: string) => void; + removeFilterTag: (name: string) => void; resetFilterTags: () => void; setSearchPhrase: (phrase: string) => void; addVisibleLayer: (layer: LayerProps) => void; @@ -53,7 +54,7 @@ function useFilterManager(initialTags: Tag[]): { ]; else return state; case "REMOVE_TAG": - return state.filter(({ id }) => id !== action.id); + return state.filter(({ name }) => name !== action.name); case "RESET_TAGS": return initialTags; default: @@ -89,6 +90,13 @@ function useFilterManager(initialTags: Tag[]): { const [searchPhrase, searchPhraseSet] = React.useState(""); const addFilterTag = (tag: Tag) => { + + let params = new URLSearchParams(window.location.search); + let urlTags = params.get("tags"); + if(!urlTags?.includes(tag.name)) + params.set("tags", `${urlTags ? urlTags : ""}${urlTags? ',' : ''}${tag.name}`) + window.history.pushState('','', "?" +params.toString()); + dispatchTags({ type: "ADD_TAG", tag, @@ -96,10 +104,29 @@ function useFilterManager(initialTags: Tag[]): { }; - const removeFilterTag = useCallback((id: string) => { + const removeFilterTag = useCallback((name: string) => { + + let params = new URLSearchParams(window.location.search); + let urlTags = params.get("tags"); + let newUrlTags = ""; + let tags = urlTags?.split(","); + if(tags?.length==0 && urlTags?.length && urlTags?.length > 0) tags[0]=urlTags; + tags?.map(urlTag => { + if(!(urlTag.toLocaleLowerCase() === name.toLocaleLowerCase())) + newUrlTags = newUrlTags + `${newUrlTags===""? urlTag : `,${urlTag}`}` + }); + if(newUrlTags !== "") { + params.set("tags", `${newUrlTags}`) + window.history.pushState('','', "?" +params.toString()); + } + else { + + window.history.pushState('','', window.location.pathname); + } + dispatchTags({ type: "REMOVE_TAG", - id, + name, }); }, []);