diff --git a/src/frontend/hooks/server/presets.ts b/src/frontend/hooks/server/presets.ts index a2cd8097f..29d3e7efd 100644 --- a/src/frontend/hooks/server/presets.ts +++ b/src/frontend/hooks/server/presets.ts @@ -2,10 +2,12 @@ import { useSuspenseQuery, useMutation, useQueryClient, + useQuery, } from '@tanstack/react-query'; import {useProject} from './projects'; import {PresetValue} from '@mapeo/schema'; +import {IconSize} from '../../sharedTypes'; export function usePresetsQuery() { const project = useProject(); @@ -33,3 +35,23 @@ export function usePresetsMutation() { }, }); } + +export function useGetPresetIcon(size: IconSize, name?: string) { + const project = useProject(); + + return useQuery({ + queryKey: ['presetIcon', name], + enabled: !!name, + queryFn: async () => { + const currentPreset = await project.preset + .getMany() + .then(res => res.find(p => p.name === name)); + + return await project.$icons.getIconUrl(currentPreset?.iconId!, { + mimeType: 'image/png', + size: size, + pixelDensity: 3, + }); + }, + }); +} diff --git a/src/frontend/screens/Observation/PresetHeader.tsx b/src/frontend/screens/Observation/PresetHeader.tsx index c6f0bc08f..868aae5c0 100644 --- a/src/frontend/screens/Observation/PresetHeader.tsx +++ b/src/frontend/screens/Observation/PresetHeader.tsx @@ -1,13 +1,14 @@ +import React from 'react'; import {View, Text, StyleSheet} from 'react-native'; import {BLACK} from '../../lib/styles'; import {FormattedPresetName} from '../../sharedComponents/FormattedData'; -import {CategoryCircleIcon} from '../../sharedComponents/icons/CategoryIcon'; +import {PresetCircleIcon} from '../../sharedComponents/icons/PresetIcon'; import {Preset} from '@mapeo/schema'; export const PresetHeader = ({preset}: {preset: Preset}) => { return ( - + diff --git a/src/frontend/screens/ObservationEdit/PresetView.tsx b/src/frontend/screens/ObservationEdit/PresetView.tsx index 1e3bb00c0..0bcde8f62 100644 --- a/src/frontend/screens/ObservationEdit/PresetView.tsx +++ b/src/frontend/screens/ObservationEdit/PresetView.tsx @@ -3,7 +3,7 @@ import {defineMessages, useIntl} from 'react-intl'; import {View, Text, StyleSheet} from 'react-native'; import {BLACK, LIGHT_BLUE} from '../../lib/styles'; import {TextButton} from '../../sharedComponents/TextButton'; -import {CategoryCircleIcon} from '../../sharedComponents/icons/CategoryIcon'; +import {PresetCircleIcon} from '../../sharedComponents/icons/PresetIcon'; import {useNavigationFromRoot} from '../../hooks/useNavigationWithTypes'; import {useDraftObservation} from '../../hooks/useDraftObservation'; @@ -32,7 +32,7 @@ export const PresetView = () => { return ( - + {name} - + ) : ( - + )} diff --git a/src/frontend/screens/PresetChooser.tsx b/src/frontend/screens/PresetChooser.tsx index 45df24655..a90848e8e 100644 --- a/src/frontend/screens/PresetChooser.tsx +++ b/src/frontend/screens/PresetChooser.tsx @@ -10,7 +10,7 @@ import { import {defineMessages, FormattedMessage} from 'react-intl'; import {useDraftObservation} from '../hooks/useDraftObservation'; -import {CategoryCircleIcon} from '../sharedComponents/icons/CategoryIcon'; +import {PresetCircleIcon} from '../sharedComponents/icons/PresetIcon'; import {WHITE} from '../lib/styles'; import {NativeNavigationComponent} from '../sharedTypes/navigation'; import {CustomHeaderLeftClose} from '../sharedComponents/CustomHeaderLeftClose'; @@ -118,7 +118,7 @@ const Item = React.memo( underlayColor="#000033" testID={`${item.docId}CategoryButton`}> - + ( - ({size = 'medium', iconId}) => { - const [error, setError] = React.useState(false); - const iconSize = iconSizes[size] || 35; - // Fallback to a default icon if we can't load the icon from mapeo-server - // if (error || !iconId) { - // return ; - // } - return ( - setError(true)} - /> - ); - }, -); - -export const CategoryCircleIcon = ({ - color, - iconId, - size = 'medium', -}: CategoryCircleIconProps) => { - // const [{ presets }] = React.useContext(ConfigContext); - - // If the preset defines a "color" field for *any* point-based category - // we want to render a thicker border, even if not all categories have a color defined - // const presetsUseColors = Array.from(presets.values()).some( - // p => p.geometry.includes("point") && !!p.color - // ); - - return ( - - - - ); -}; diff --git a/src/frontend/sharedComponents/icons/PresetIcon.tsx b/src/frontend/sharedComponents/icons/PresetIcon.tsx new file mode 100644 index 000000000..493a9dfd3 --- /dev/null +++ b/src/frontend/sharedComponents/icons/PresetIcon.tsx @@ -0,0 +1,53 @@ +import React, {memo} from 'react'; +import {Image} from 'react-native'; + +import {Circle} from './Circle'; +import {IconSize} from '../../sharedTypes'; +import {UIActivityIndicator} from 'react-native-indicators'; +import {useGetPresetIcon} from '../../hooks/server/presets'; +import MaterialIcon from 'react-native-vector-icons/MaterialIcons'; + +interface PresetIconProps { + size?: IconSize; + name?: string; +} + +const iconSizes = { + small: 22, + medium: 35, + large: 50, +}; + +const radii = { + small: 15, + medium: 25, + large: 35, +}; + +export const PresetIcon = memo(({size = 'medium', name}) => { + const iconSize = iconSizes[size] || 35; + const {data, isLoading} = useGetPresetIcon(size, name); + const [error, setError] = React.useState(false); + + if (isLoading) return ; + + // Fallback to a default icon if we can't load the icon from mapeo-server + if (error || !name) return ; + + return ( + setError(true)} + /> + ); +}); + +export const PresetCircleIcon = ({name, size = 'medium'}: PresetIconProps) => { + return ( + + + + ); +};