mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2025-12-13 07:46:10 +00:00
refactoring hooks and api
This commit is contained in:
parent
b0e611c9c5
commit
c92b2be9fc
File diff suppressed because it is too large
Load Diff
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 92 KiB |
@ -18,5 +18,5 @@ export default {
|
||||
}),
|
||||
typescript()
|
||||
],
|
||||
external: ['react', 'react-dom', 'leaflet', 'react-leaflet', 'react-toastify' , 'react-toastify/dist/ReactToastify.css', 'tw-elements' ,'react-router-dom', 'react-leaflet-cluster', '@tanstack/react-query', 'leaflet/dist/leaflet.css', '@heroicons/react/20/solid']
|
||||
external: ['react', 'react-dom', 'leaflet', 'react-leaflet', 'react-toastify' , 'react-toastify/dist/ReactToastify.css', 'tw-elements' ,'react-router-dom', 'react-leaflet-cluster', '@tanstack/react-query', 'tributejs', 'prop-types', 'leaflet/dist/leaflet.css', '@heroicons/react/20/solid']
|
||||
}
|
||||
@ -1,84 +1,47 @@
|
||||
import * as React from 'react'
|
||||
import { Marker } from 'react-leaflet'
|
||||
import { Item, Tag, LayerProps } from '../../types'
|
||||
import { Item, LayerProps } from '../../types'
|
||||
import MarkerIconFactory from '../../Utils/MarkerIconFactory'
|
||||
import { ItemViewPopup } from './Subcomponents/ItemViewPopup'
|
||||
import { useTags } from './hooks/useTags'
|
||||
import { useAddItem, useItems, useResetItems } from './hooks/useItems'
|
||||
import { useItems, useResetItems, useSetItemsApi, useSetItemsData } from './hooks/useItems'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useAddLayer } from './hooks/useLayers'
|
||||
import { ItemFormPopupProps, ItemFormPopup } from './Subcomponents/ItemFormPopup'
|
||||
import { toast } from 'react-toastify'
|
||||
import { hashTagRegex } from '../../Utils/HeighlightTags'
|
||||
import { useFilterTags } from './hooks/useFilter'
|
||||
|
||||
|
||||
export const Layer = (props: LayerProps) => {
|
||||
|
||||
const [itemFormPopup, setItemFormPopup] = useState<ItemFormPopupProps | null>(null);
|
||||
|
||||
const tags = useTags();
|
||||
const filterTags = useFilterTags();
|
||||
|
||||
const items = useItems();
|
||||
const addItem = useAddItem()
|
||||
const addLayer = useAddLayer();
|
||||
const setItemsApi = useSetItemsApi();
|
||||
const setItemsData = useSetItemsData();
|
||||
|
||||
const resetItems = useResetItems();
|
||||
|
||||
const getItemTags = (item: Item) : Tag[] => {
|
||||
const itemTagStrings = item.text.toLocaleLowerCase().match(hashTagRegex);
|
||||
const itemTags: Tag[] = [];
|
||||
itemTagStrings?.map(tag => {
|
||||
if (tags.find(t => t.id === tag.slice(1))) { itemTags.push(tags.find(t => t.id === tag.slice(1))!) }
|
||||
})
|
||||
return itemTags;
|
||||
};
|
||||
|
||||
const loadItems = async () => {
|
||||
props.data?.map(item => {
|
||||
if (item.position) {
|
||||
item.layer = props;
|
||||
addItem(item);
|
||||
}
|
||||
})
|
||||
|
||||
if (props.api) {
|
||||
addLayer(props);
|
||||
}
|
||||
|
||||
if(props.api) {
|
||||
const result = await toast.promise(
|
||||
props.api!.getItems(),
|
||||
{
|
||||
pending: `loading ${props.name} ...`,
|
||||
success: `${props.name} loaded` ,
|
||||
error: `error while loading ${props.name}`
|
||||
}
|
||||
);
|
||||
if (result) {
|
||||
result.map(item => {
|
||||
if (item.position) {
|
||||
addItem(({ layer: props, api: props.api, ...item }));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
resetItems(props);
|
||||
loadItems();
|
||||
props.data && setItemsData(props);
|
||||
props.api && setItemsApi(props);
|
||||
}, [props.data, props.api])
|
||||
|
||||
return (
|
||||
<>
|
||||
{items &&
|
||||
items.filter(item => item.layer?.name === props.name)?.map((place: Item) => {
|
||||
const tags = getItemTags(place);
|
||||
items.filter(item => item.layer?.name === props.name)?.filter(item => item)?.map((place: Item) => {
|
||||
const tags = place.tags;
|
||||
if(place.name === "docutopia")
|
||||
console.log(tags);
|
||||
|
||||
let color1 = "#666";
|
||||
let color2 = "RGBA(35, 31, 32, 0.2)";
|
||||
if (tags[0]) {
|
||||
if (tags && tags[0]) {
|
||||
color1 = tags[0].color;
|
||||
}
|
||||
if (tags[1]) {
|
||||
if (tags && tags[1]) {
|
||||
color2 = tags[1].color;
|
||||
}
|
||||
return (
|
||||
@ -106,12 +69,12 @@ export const Layer = (props: LayerProps) => {
|
||||
(props.children && React.Children.toArray(props.children).some(child => React.isValidElement(child) && child.props.__TYPE === "ItemForm") ?
|
||||
React.Children.toArray(props.children).map((child) =>
|
||||
React.isValidElement(child) && child.props.__TYPE === "ItemForm" ?
|
||||
<ItemFormPopup key={props.setItemFormPopup?.name} position={props.itemFormPopup!.position} layer={props.itemFormPopup!.layer} setItemFormPopup={setItemFormPopup} item={props.itemFormPopup!.item} api={props.api} >{child}</ItemFormPopup>
|
||||
<ItemFormPopup key={props.setItemFormPopup?.name} position={props.itemFormPopup!.position} layer={props.itemFormPopup!.layer} setItemFormPopup={setItemFormPopup} item={props.itemFormPopup!.item} >{child}</ItemFormPopup>
|
||||
: ""
|
||||
)
|
||||
:
|
||||
<>
|
||||
<ItemFormPopup position={props.itemFormPopup!.position} layer={props.itemFormPopup!.layer} setItemFormPopup={setItemFormPopup} item={props.itemFormPopup!.item} api={props.api} />
|
||||
<ItemFormPopup position={props.itemFormPopup!.position} layer={props.itemFormPopup!.layer} setItemFormPopup={setItemFormPopup} item={props.itemFormPopup!.item} />
|
||||
</>)
|
||||
}
|
||||
</>
|
||||
|
||||
@ -14,7 +14,6 @@ export interface ItemFormPopupProps {
|
||||
position: LatLng,
|
||||
layer: LayerProps,
|
||||
item?: Item,
|
||||
api?: ItemsApi<any>,
|
||||
children?: React.ReactNode,
|
||||
setItemFormPopup: React.Dispatch<React.SetStateAction<any>>
|
||||
}
|
||||
@ -47,22 +46,13 @@ export function ItemFormPopup(props: ItemFormPopupProps) {
|
||||
addTag({id: tag.slice(1), color: randomColor()})
|
||||
});
|
||||
|
||||
|
||||
if (props.item) {
|
||||
formItem['id'] = props.item.id;
|
||||
await props.api?.updateItem!(formItem);
|
||||
formItem['api'] = props.api;
|
||||
formItem['layer'] = props.layer;
|
||||
await updateItem(formItem);
|
||||
await updateItem({...props.item, ...formItem});
|
||||
setSpinner(false);
|
||||
map.closePopup();
|
||||
}
|
||||
else {
|
||||
formItem['id'] = crypto.randomUUID();
|
||||
await props.api?.createItem!(formItem);
|
||||
formItem['api'] = props.api;
|
||||
formItem['layer'] = props.layer;
|
||||
await addItem(formItem);
|
||||
await addItem({...formItem, id: crypto.randomUUID(), layer: props.layer});
|
||||
setSpinner(false);
|
||||
map.closePopup();
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ export function HeaderView({ item, setItemFormPopup }: {
|
||||
|
||||
const removeItemFromMap = (event: React.MouseEvent<HTMLElement>) => {
|
||||
setLoading(true);
|
||||
item.api?.deleteItem!(item.id)
|
||||
item.layer.api?.deleteItem!(item.id)
|
||||
.then(() => removeItem(item))
|
||||
.then(() => map.closePopup())
|
||||
.then(()=>setLoading(false))
|
||||
@ -41,7 +41,7 @@ export function HeaderView({ item, setItemFormPopup }: {
|
||||
<b className="tw-text-xl tw-font-bold">{item.name}</b>
|
||||
</div>
|
||||
<div className='tw-col-span-1'>
|
||||
{item.api &&
|
||||
{item.layer.api &&
|
||||
<div className="tw-dropdown tw-dropdown-bottom">
|
||||
<label tabIndex={0} className="tw-btn tw-m-1 tw-bg-white hover:tw-bg-white tw-text-gray-500 hover:tw-text-gray-700 tw-leading-3 tw-border-none tw-min-h-0 tw-h-4">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="tw-h-5 tw-w-5" viewBox="0 0 20 20" fill="currentColor">
|
||||
@ -49,7 +49,7 @@ export function HeaderView({ item, setItemFormPopup }: {
|
||||
</svg>
|
||||
</label>
|
||||
<ul tabIndex={0} className="tw-dropdown-content tw-menu tw-p-2 tw-shadow tw-bg-base-100 tw-rounded-box">
|
||||
{item.api.updateItem && <li>
|
||||
{item.layer.api.updateItem && <li>
|
||||
<a className='tw-bg-white hover:tw-bg-gray-300 !tw-text-blue-800 hover:tw-text-gray-700' onClick={openEditPopup}>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" className="tw-h-5 tw-w-5" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z" />
|
||||
@ -57,7 +57,7 @@ export function HeaderView({ item, setItemFormPopup }: {
|
||||
</a>
|
||||
</li>}
|
||||
|
||||
{item.api.deleteItem && <li>
|
||||
{item.layer.api.deleteItem && <li>
|
||||
<a className='tw-bg-white hover:tw-bg-gray-300 !tw-text-red-800 hover:tw-text-red-950' onClick={removeItemFromMap}>
|
||||
{loading ? <span className="tw-loading tw-loading-spinner tw-loading-sm"></span>
|
||||
:
|
||||
|
||||
84
src/Components/Map/hooks/useFilter.tsx
Normal file
84
src/Components/Map/hooks/useFilter.tsx
Normal file
@ -0,0 +1,84 @@
|
||||
import { useCallback, useReducer, createContext, useContext } from "react";
|
||||
import * as React from "react";
|
||||
import {Tag} from "../../../types";
|
||||
|
||||
type ActionType =
|
||||
| { type: "ADD"; tag: Tag }
|
||||
| { type: "REMOVE"; id: string };
|
||||
|
||||
type UseTagManagerResult = ReturnType<typeof useTagsManager>;
|
||||
|
||||
const TagContext = createContext<UseTagManagerResult>({
|
||||
filterTags: [],
|
||||
addFilterTag: () => { },
|
||||
removeFilterTag: () => { },
|
||||
|
||||
});
|
||||
|
||||
function useTagsManager(initialTags: Tag[]): {
|
||||
filterTags: Tag[];
|
||||
addFilterTag: (tag: Tag) => void;
|
||||
removeFilterTag: (id: string) => void;
|
||||
} {
|
||||
const [filterTags, dispatch] = useReducer((state: Tag[], action: ActionType) => {
|
||||
switch (action.type) {
|
||||
case "ADD":
|
||||
const exist = state.find((tag) =>
|
||||
tag.id === action.tag.id ? true : false
|
||||
);
|
||||
if (!exist) return [
|
||||
...state,
|
||||
action.tag,
|
||||
];
|
||||
else return state;
|
||||
|
||||
case "REMOVE":
|
||||
return state.filter(({ id }) => id !== action.id);
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
}, initialTags);
|
||||
|
||||
|
||||
|
||||
const addFilterTag = (tag: Tag) => {
|
||||
dispatch({
|
||||
type: "ADD",
|
||||
tag,
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
const removeFilterTag = useCallback((id: string) => {
|
||||
dispatch({
|
||||
type: "REMOVE",
|
||||
id,
|
||||
});
|
||||
}, []);
|
||||
|
||||
|
||||
return { filterTags, addFilterTag, removeFilterTag };
|
||||
}
|
||||
|
||||
export const TagsProvider: React.FunctionComponent<{
|
||||
initialTags: Tag[], children?: React.ReactNode
|
||||
}> = ({ initialTags, children }) => (
|
||||
<TagContext.Provider value={useTagsManager(initialTags)}>
|
||||
{children}
|
||||
</TagContext.Provider>
|
||||
);
|
||||
|
||||
export const useFilterTags = (): Tag[] => {
|
||||
const { filterTags } = useContext(TagContext);
|
||||
return filterTags;
|
||||
};
|
||||
|
||||
export const useAddFilterTag = (): UseTagManagerResult["addFilterTag"] => {
|
||||
const { addFilterTag } = useContext(TagContext);
|
||||
return addFilterTag;
|
||||
};
|
||||
|
||||
export const useRemoveFilterTag = (): UseTagManagerResult["removeFilterTag"] => {
|
||||
const { removeFilterTag } = useContext(TagContext);
|
||||
return removeFilterTag;
|
||||
};
|
||||
@ -1,69 +1,124 @@
|
||||
import { useCallback, useReducer, createContext, useContext } from "react";
|
||||
import { useCallback, useReducer, createContext, useContext, useEffect } from "react";
|
||||
import * as React from "react";
|
||||
import { Item, LayerProps } from "../../../types";
|
||||
import { Item, ItemsApi, LayerProps, Tag } from "../../../types";
|
||||
import { toast } from "react-toastify";
|
||||
import { useAddLayer } from "./useLayers";
|
||||
import { useTags } from "./useTags";
|
||||
import { hashTagRegex } from "../../../Utils/HeighlightTags";
|
||||
|
||||
|
||||
type ActionType =
|
||||
| { type: "ADD"; item: Item }
|
||||
| { type: "UPDATE"; item: Item }
|
||||
| { type: "REMOVE"; item: Item }
|
||||
| { type: "RESET"; layer: LayerProps };
|
||||
| { type: "ADD"; item: Item }
|
||||
| { type: "UPDATE"; item: Item }
|
||||
| { type: "REMOVE"; item: Item }
|
||||
| { type: "RESET"; layer: LayerProps }
|
||||
| { type: "ADD_TAGS" };
|
||||
|
||||
|
||||
type UseItemManagerResult = ReturnType<typeof useItemsManager>;
|
||||
|
||||
const ItemContext = createContext<UseItemManagerResult>({
|
||||
items: [],
|
||||
addItem: () => {},
|
||||
updateItem: () => {},
|
||||
removeItem: () => {},
|
||||
resetItems: () => {}
|
||||
items: [],
|
||||
addItem: () => { },
|
||||
updateItem: () => { },
|
||||
removeItem: () => { },
|
||||
resetItems: () => { },
|
||||
setItemsApi: () => { },
|
||||
setItemsData: () => { },
|
||||
});
|
||||
|
||||
function useItemsManager (initialItems: Item[]): {
|
||||
function useItemsManager(initialItems: Item[]): {
|
||||
items: Item[];
|
||||
addItem: (item: Item) => void;
|
||||
updateItem: (item: Item) => void;
|
||||
removeItem: (item: Item) => void;
|
||||
resetItems: (layer: LayerProps) => void;
|
||||
setItemsApi: (layer: LayerProps) => void;
|
||||
setItemsData: (layer: LayerProps) => void;
|
||||
} {
|
||||
|
||||
const addLayer = useAddLayer();
|
||||
const tags = useTags();
|
||||
|
||||
const [items, dispatch] = useReducer((state: Item[], action: ActionType) => {
|
||||
switch (action.type) {
|
||||
case "ADD":
|
||||
case "ADD":
|
||||
const exist = state.find((item) =>
|
||||
item.id === action.item.id ? true : false
|
||||
);
|
||||
if (!exist) return [
|
||||
...state,
|
||||
action.item,
|
||||
];
|
||||
else return state;
|
||||
case "UPDATE":
|
||||
return state.map((item) => {
|
||||
if (item.id === action.item.id) {
|
||||
return action.item
|
||||
}
|
||||
return item
|
||||
});
|
||||
case "REMOVE":
|
||||
return state.filter(item => item !== action.item);
|
||||
case "RESET":
|
||||
return state.filter(item => item.layer.name !== action.layer.name);
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
item.id === action.item.id ? true : false
|
||||
);
|
||||
if (!exist) return [
|
||||
...state,
|
||||
action.item,
|
||||
];
|
||||
else return state;
|
||||
case "UPDATE":
|
||||
return state.map((item) => {
|
||||
if (item.id === action.item.id) {
|
||||
return action.item
|
||||
}
|
||||
return item
|
||||
});
|
||||
case "REMOVE":
|
||||
return state.filter(item => item !== action.item);
|
||||
case "RESET":
|
||||
return state.filter(item => item.layer.name !== action.layer.name);
|
||||
case "ADD_TAGS":
|
||||
return state.map(item => {
|
||||
const itemTagStrings = item.text.toLocaleLowerCase().match(hashTagRegex);
|
||||
const itemTags: Tag[] = [];
|
||||
itemTagStrings?.map(tag => {
|
||||
if (tags.find(t => t.id === tag.slice(1))) { itemTags.push(tags.find(t => t.id === tag.slice(1))!) }
|
||||
})
|
||||
return { ...item, tags: itemTags }
|
||||
})
|
||||
default:
|
||||
throw new Error();
|
||||
}
|
||||
}, initialItems);
|
||||
|
||||
const addItem = useCallback((item: Item) => {
|
||||
|
||||
const setItemsApi = useCallback(async (layer: LayerProps) => {
|
||||
layer.api?.createItem && addLayer(layer);
|
||||
const result = await toast.promise(
|
||||
layer.api!.getItems(),
|
||||
{
|
||||
pending: `loading ${layer.name} ...`,
|
||||
success: `${layer.name} loaded`,
|
||||
error: `error while loading ${layer.name}`
|
||||
}
|
||||
);
|
||||
if (result) {
|
||||
result.map(item => {
|
||||
dispatch({ type: "ADD", item: { ...item, layer: layer } });
|
||||
})
|
||||
}
|
||||
dispatch({ type: "ADD_TAGS" })
|
||||
}, [])
|
||||
|
||||
const setItemsData = useCallback((layer: LayerProps) => {
|
||||
layer.data?.map(item => {
|
||||
dispatch({ type: "ADD", item: { ...item, layer: layer } })
|
||||
})
|
||||
dispatch({ type: "ADD_TAGS" })
|
||||
}, []);
|
||||
|
||||
|
||||
const addItem = useCallback(async (item: Item) => {
|
||||
await item.layer.api?.createItem!(item);
|
||||
dispatch({
|
||||
type: "ADD",
|
||||
item,
|
||||
});
|
||||
dispatch({ type: "ADD_TAGS" })
|
||||
}, []);
|
||||
|
||||
const updateItem = useCallback((item: Item) => {
|
||||
const updateItem = useCallback(async (item: Item) => {
|
||||
await item.layer.api?.updateItem!(item);
|
||||
dispatch({
|
||||
type: "UPDATE",
|
||||
item,
|
||||
});
|
||||
dispatch({ type: "ADD_TAGS" })
|
||||
}, []);
|
||||
|
||||
const removeItem = useCallback((item: Item) => {
|
||||
@ -80,11 +135,16 @@ function useItemsManager (initialItems: Item[]): {
|
||||
});
|
||||
}, []);
|
||||
|
||||
return { items, updateItem, addItem, removeItem, resetItems };
|
||||
useEffect(() => {
|
||||
dispatch({ type: "ADD_TAGS" })
|
||||
}, [tags])
|
||||
|
||||
|
||||
return { items, updateItem, addItem, removeItem, resetItems, setItemsApi, setItemsData };
|
||||
}
|
||||
|
||||
export const ItemsProvider: React.FunctionComponent<{
|
||||
initialItems: Item[], children?: React.ReactNode
|
||||
initialItems: Item[], children?: React.ReactNode
|
||||
}> = ({ initialItems, children }) => (
|
||||
<ItemContext.Provider value={useItemsManager(initialItems)}>
|
||||
{children}
|
||||
@ -109,9 +169,19 @@ export const useUpdateItem = (): UseItemManagerResult["updateItem"] => {
|
||||
export const useRemoveItem = (): UseItemManagerResult["removeItem"] => {
|
||||
const { removeItem } = useContext(ItemContext);
|
||||
return removeItem;
|
||||
};
|
||||
};
|
||||
|
||||
export const useResetItems = (): UseItemManagerResult["resetItems"] => {
|
||||
const { resetItems } = useContext(ItemContext);
|
||||
return resetItems;
|
||||
};
|
||||
|
||||
export const useSetItemsApi = (): UseItemManagerResult["setItemsApi"] => {
|
||||
const { setItemsApi } = useContext(ItemContext);
|
||||
return setItemsApi;
|
||||
};
|
||||
|
||||
export const useSetItemsData = (): UseItemManagerResult["setItemsData"] => {
|
||||
const { setItemsData } = useContext(ItemContext);
|
||||
return setItemsData;
|
||||
};
|
||||
@ -1,10 +1,9 @@
|
||||
import { useCallback, useReducer, createContext, useContext } from "react";
|
||||
import * as React from "react";
|
||||
import { Item, LayerProps } from "../../../types";
|
||||
import { LayerProps } from "../../../types";
|
||||
|
||||
type ActionType =
|
||||
| { type: "ADD LAYER"; layer: LayerProps }
|
||||
| { type: "ADD ITEM"; item: Item; layer: LayerProps };
|
||||
|
||||
type UseItemManagerResult = ReturnType<typeof useLayerManager>;
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import { useCallback, useReducer, createContext, useContext } from "react";
|
||||
import * as React from "react";
|
||||
import { ItemsApi, Tag } from "../../../types";
|
||||
import { toast } from "react-toastify";
|
||||
|
||||
type ActionType =
|
||||
| { type: "ADD"; tag: Tag }
|
||||
@ -43,7 +42,7 @@ function useTagsManager(initialTags: Tag[]): {
|
||||
}
|
||||
}, initialTags);
|
||||
|
||||
const [api, setApi] = React.useState<ItemsApi<Tag> | undefined>(undefined)
|
||||
const [api, setApi] = React.useState<ItemsApi<Tag>>({} as ItemsApi<Tag>)
|
||||
|
||||
const setTagApi = useCallback(async (api: ItemsApi<Tag>) => {
|
||||
setApi(api);
|
||||
|
||||
@ -1,30 +1,18 @@
|
||||
/**
|
||||
export const randomColor = (brightness) => {
|
||||
function randomChannel(brightness){
|
||||
var r = 255-brightness;
|
||||
var n = 0|((Math.random() * r) + brightness);
|
||||
var s = n.toString(16);
|
||||
return (s.length==1) ? '0'+s : s;
|
||||
}
|
||||
return '#' + randomChannel(brightness) + randomChannel(brightness) + randomChannel(brightness);
|
||||
}
|
||||
*/
|
||||
|
||||
export const randomColor = () => {
|
||||
return hsvToRgb((Math.random()+golden_ratio_conjugate)%1,0.8, 0.7)
|
||||
return hsvToHex((Math.random() + golden_ratio_conjugate) % 1, 0.8, 0.7)
|
||||
}
|
||||
|
||||
const golden_ratio_conjugate = 0.618033988749895;
|
||||
|
||||
function hsvToRgb(h, s, v){
|
||||
function hsvToHex(h, s, v) {
|
||||
var r, g, b;
|
||||
var i = (Math.floor(h * 6));
|
||||
var i = (Math.floor(h * 6));
|
||||
var f = h * 6 - i;
|
||||
var p = v * (1 - s);
|
||||
var q = v * (1 - f * s);
|
||||
var t = v * (1 - (1 - f) * s);
|
||||
|
||||
switch(i % 6){
|
||||
switch (i % 6) {
|
||||
case 0: r = v, g = t, b = p; break;
|
||||
case 1: r = q, g = v, b = p; break;
|
||||
case 2: r = p, g = v, b = t; break;
|
||||
@ -33,11 +21,11 @@ const golden_ratio_conjugate = 0.618033988749895;
|
||||
case 5: r = v, g = p, b = q; break;
|
||||
}
|
||||
|
||||
return rgbToHex(Math.round(r*255), Math.round(g*255), Math.round(b*255))
|
||||
return rgbToHex(Math.round(r * 255), Math.round(g * 255), Math.round(b * 255))
|
||||
}
|
||||
|
||||
|
||||
const rgbToHex = (r, g, b) => '#' + [r, g, b].map(x => {
|
||||
const hex = x.toString(16)
|
||||
return hex.length === 1 ? '0' + hex : hex
|
||||
}).join('')
|
||||
}).join('')
|
||||
@ -20,7 +20,6 @@ export interface LayerProps {
|
||||
markerIcon: string,
|
||||
markerShape: string,
|
||||
markerDefaultColor: string,
|
||||
tags?: Tag[],
|
||||
api?: ItemsApi<any>,
|
||||
setItemFormPopup?: React.Dispatch<React.SetStateAction<ItemFormPopupProps | null>>,
|
||||
itemFormPopup?: ItemFormPopupProps | null
|
||||
@ -35,8 +34,8 @@ export class Item {
|
||||
date_updated?: string | null;
|
||||
start?: string;
|
||||
end?: string;
|
||||
tags?: number[];
|
||||
api?: ItemsApi<any>;
|
||||
tags?: Tag[];
|
||||
[key: string]: any;
|
||||
constructor(id:string|number,name:string,text:string,position:Geometry, layer?: LayerProps, api?: ItemsApi<any>){
|
||||
this.id = id;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user