diff --git a/src/Components/Map/Layer.tsx b/src/Components/Map/Layer.tsx index 4775a752..cd6ed6b4 100644 --- a/src/Components/Map/Layer.tsx +++ b/src/Components/Map/Layer.tsx @@ -3,7 +3,7 @@ import { Marker, Tooltip, useMap, useMapEvents } from 'react-leaflet' import { Item, LayerProps, Tag } from '../../types' import MarkerIconFactory from '../../Utils/MarkerIconFactory' import { ItemViewPopup } from './Subcomponents/ItemViewPopup' -import { useItems, useSetItemsApi, useSetItemsData } from './hooks/useItems' +import { useAllItemsLoaded, useItems, useSetItemsApi, useSetItemsData } from './hooks/useItems' import { useEffect, useState } from 'react' import { ItemFormPopup } from './Subcomponents/ItemFormPopup' import { useFilterTags, useIsLayerVisible } from './hooks/useFilter' @@ -52,6 +52,8 @@ export const Layer = ({ let location = useLocation(); const allTagsLoaded = useAllTagsLoaded(); + const allItemsLoaded = useAllItemsLoaded(); + const tags = useTags(); const addTag = useAddTag(); const [newTagsToAdd, setNewTagsToAdd] = useState([]); @@ -114,17 +116,17 @@ export const Layer = ({ }, [leafletRefs, location]) useEffect(() => { + console.log(`all tags loaded: ${allTagsLoaded}`); }, [allTagsLoaded]) - + useEffect(() => { - if(tagsReady){ + if (tagsReady) { + const processedTags = {}; newTagsToAdd.map(newtag => { - addTag(newtag); - setNewTagsToAdd(current => - current.filter(tag => { - return tag.name !== newtag.name; - }), - ) + if (!processedTags[newtag.name]) { + processedTags[newtag.name] = true; + addTag(newtag); + } }) } }, [tagsReady]) @@ -137,32 +139,36 @@ export const Layer = ({ filter(item => filterTags.length == 0 ? item : filterTags.every(tag => getItemTags(item).some(filterTag => filterTag.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())))?. filter(item => item.layer && isLayerVisible(item.layer)). - map((item: Item) => { + map((item: Item) => { if (getValue(item, itemLongitudeField) && getValue(item, itemLatitudeField)) { - if(item[itemTextField]) item[itemTextField] = getValue(item, itemTextField); + + + if (item[itemTextField]) item[itemTextField] = getValue(item, itemTextField); else item[itemTextField] = ""; if (item?.tags) { item[itemTextField] = item[itemTextField] + '\n\n'; item.tags.map(tag => { - if(!item[itemTextField].includes(`#${tag}`)) - return (item[itemTextField] = item[itemTextField] + `#${tag} `) + if (!item[itemTextField].includes(`#${tag}`)) + return (item[itemTextField] = item[itemTextField] + `#${tag} `) return item[itemTextField] - + }); } - if(allTagsLoaded) { - 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()}; - setNewTagsToAdd(current => [...current, newTag]); + + + 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 = { name: tag.slice(1).toLocaleLowerCase(), color: randomColor() }; + setNewTagsToAdd(current => [...current, newTag]); } }); !tagsReady && setTagsReady(true); - } + } const itemTtags = getItemTags(item); - + const latitude = itemLatitudeField && item ? getValue(item, itemLatitudeField) : undefined; const longitude = itemLongitudeField && item ? getValue(item, itemLongitudeField) : undefined; diff --git a/src/Components/Map/Subcomponents/Controls/TagsControl.tsx b/src/Components/Map/Subcomponents/Controls/TagsControl.tsx index 5f51d35a..7aa2823c 100644 --- a/src/Components/Map/Subcomponents/Controls/TagsControl.tsx +++ b/src/Components/Map/Subcomponents/Controls/TagsControl.tsx @@ -12,13 +12,11 @@ export const TagsControl = () => { filterTags.map(tag =>
- +
#{capitalizeFirstLetter(tag.name)}
) } - - ) } diff --git a/src/Components/Map/hooks/useItems.tsx b/src/Components/Map/hooks/useItems.tsx index 9ad87c16..7ff0f81c 100644 --- a/src/Components/Map/hooks/useItems.tsx +++ b/src/Components/Map/hooks/useItems.tsx @@ -1,4 +1,4 @@ -import { useCallback, useReducer, createContext, useContext, useEffect } from "react"; +import { useCallback, useReducer, createContext, useContext, useEffect, useState } from "react"; import * as React from "react"; import { Item, ItemsApi, LayerProps, Tag } from "../../../types"; import { toast } from "react-toastify"; @@ -23,6 +23,7 @@ const ItemContext = createContext({ resetItems: () => { }, setItemsApi: () => { }, setItemsData: () => { }, + allItemsLoaded: false }); function useItemsManager(initialItems: Item[]): { @@ -33,10 +34,17 @@ function useItemsManager(initialItems: Item[]): { resetItems: (layer: LayerProps) => void; setItemsApi: (layer: LayerProps) => void; setItemsData: (layer: LayerProps) => void; + allItemsLoaded: boolean; + } { const addLayer = useAddLayer(); + const [itemsCount, setItemsCount] = useState(0); + const [allItemsLoaded, setallItemsLoaded] = useState(false); + + + const [items, dispatch] = useReducer((state: Item[], action: ActionType) => { switch (action.type) { case "ADD": @@ -83,6 +91,7 @@ function useItemsManager(initialItems: Item[]): { result.map(item => { dispatch({ type: "ADD", item: { ...item, layer: layer } }); }) + setallItemsLoaded(true); } }, []) @@ -123,7 +132,7 @@ function useItemsManager(initialItems: Item[]): { - return { items, updateItem, addItem, removeItem, resetItems, setItemsApi, setItemsData }; + return { items, updateItem, addItem, removeItem, resetItems, setItemsApi, setItemsData, allItemsLoaded }; } export const ItemsProvider: React.FunctionComponent<{ @@ -167,4 +176,9 @@ export const useSetItemsApi = (): UseItemManagerResult["setItemsApi"] => { export const useSetItemsData = (): UseItemManagerResult["setItemsData"] => { const { setItemsData } = useContext(ItemContext); return setItemsData; -}; \ No newline at end of file +}; + +export const useAllItemsLoaded = (): UseItemManagerResult["allItemsLoaded"] => { + const { allItemsLoaded } = useContext(ItemContext); + return allItemsLoaded; +} \ No newline at end of file diff --git a/src/Components/Map/hooks/useTags.tsx b/src/Components/Map/hooks/useTags.tsx index f9c607c8..f542a368 100644 --- a/src/Components/Map/hooks/useTags.tsx +++ b/src/Components/Map/hooks/useTags.tsx @@ -29,17 +29,22 @@ function useTagsManager(initialTags: Tag[]): { } { const [allTagsLoaded, setallTagsLoaded] = useState(false); + const [tagCount, setTagCount] = useState(0); const [tags, dispatch] = useReducer((state: Tag[], action: ActionType) => { switch (action.type) { case "ADD": const exist = state.find((tag) => - tag.id === action.tag.id ? true : false + tag.name.toLocaleLowerCase() === action.tag.name.toLocaleLowerCase() ? true : false ); - if (!exist) return [ - ...state, - { ...action.tag} - ]; + if (!exist) { + const newState = [ + ...state, + { ...action.tag} + ]; + if(tagCount == newState.length) setallTagsLoaded(true); + return newState; + } else return state; default: throw new Error(); @@ -48,16 +53,20 @@ function useTagsManager(initialTags: Tag[]): { const [api, setApi] = React.useState>({} as ItemsApi) + const setTagApi = useCallback(async (api: ItemsApi) => { setApi(api); const result = await api.getItems(); + setTagCount(result.length); + if(tagCount == 0) setallTagsLoaded(true); if (result) { result.map(tag => { tag.name = tag.name.toLocaleLowerCase(); - dispatch({ type: "ADD", tag }) + dispatch({ type: "ADD", tag }); }) - setallTagsLoaded(true); } + + }, []) const setTagData = useCallback((data: Tag[]) => { @@ -67,14 +76,15 @@ function useTagsManager(initialTags: Tag[]): { }) }, []); - const addTag = (tag: Tag) => { - dispatch({ - type: "ADD", - tag, - }); - if (!tags.some((t) => t.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())) { - api?.createItem && api.createItem(tag); - } + const addTag = (tag: Tag) => { + dispatch({ + type: "ADD", + tag, + }); + if (!tags.some((t) => t.name.toLocaleLowerCase() === tag.name.toLocaleLowerCase())) { + api?.createItem && api.createItem(tag); + } + }; diff --git a/src/types.ts b/src/types.ts index 7447d1a3..1dab967c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -69,7 +69,7 @@ export class Geometry { export interface Tag { color: string; - id: string; + id?: string; name: string; }