diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c0dd911fb..c9e184215 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -318,8 +318,8 @@ importers: specifier: ^5.2.0 version: 5.3.3(react@17.0.2) zustand: - specifier: ^3.4.1 - version: 3.7.2(react@17.0.2) + specifier: ^4.4.6 + version: 4.4.6(@types/react@18.0.17)(react@17.0.2) devDependencies: '@vitejs/plugin-react': specifier: ^4.1.1 @@ -11277,6 +11277,14 @@ packages: prepend-http: 2.0.0 dev: true + /use-sync-external-store@1.2.0(react@17.0.2): + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 17.0.2 + dev: false + /use@3.1.1: resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} engines: {node: '>=0.10.0'} @@ -11807,16 +11815,24 @@ packages: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} dev: false - /zustand@3.7.2(react@17.0.2): - resolution: {integrity: sha512-PIJDIZKtokhof+9+60cpockVOq05sJzHCriyvaLBmEJixseQ1a5Kdov6fWZfWOu5SK9c+FhH1jU0tntLxRJYMA==} + /zustand@4.4.6(@types/react@18.0.17)(react@17.0.2): + resolution: {integrity: sha512-Rb16eW55gqL4W2XZpJh0fnrATxYEG3Apl2gfHTyDSE965x/zxslTikpNch0JgNjJA9zK6gEFW8Fl6d1rTZaqgg==} engines: {node: '>=12.7.0'} peerDependencies: + '@types/react': '>=16.8' + immer: '>=9.0' react: '>=16.8' peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true react: optional: true dependencies: + '@types/react': 18.0.17 react: 17.0.2 + use-sync-external-store: 1.2.0(react@17.0.2) dev: false /zwitch@1.0.5: diff --git a/sites/avivator/package.json b/sites/avivator/package.json index c6c252668..3ce1e07c6 100644 --- a/sites/avivator/package.json +++ b/sites/avivator/package.json @@ -18,7 +18,7 @@ "react-dom": "^16.8.0 || ^17.0.0", "react-dropzone": "^11.2.3", "react-router-dom": "^5.2.0", - "zustand": "^3.4.1" + "zustand": "^4.4.6" }, "devDependencies": { "@vitejs/plugin-react": "^4.1.1", diff --git a/sites/avivator/src/Avivator.jsx b/sites/avivator/src/Avivator.jsx index d0ec462c1..3f8b21d09 100644 --- a/sites/avivator/src/Avivator.jsx +++ b/sites/avivator/src/Avivator.jsx @@ -1,6 +1,6 @@ import React, { useEffect } from 'react'; -import { useViewerStore } from './state'; +import { useViewerStore, useViewerStoreApi } from './state'; import { useImage } from './hooks'; import SnackBars from './components/Snackbars'; import Viewer from './components/Viewer'; @@ -22,9 +22,10 @@ export default function Avivator(props) { const isViewerLoading = useViewerStore(store => store.isViewerLoading); const source = useViewerStore(store => store.source); const useLinkedView = useViewerStore(store => store.useLinkedView); + const viewerStore = useViewerStoreApi(); useEffect(() => { - useViewerStore.setState({ + viewerStore.setState({ source: initSource, isNoImageUrlSnackbarOn: isDemoImage }); diff --git a/sites/avivator/src/components/Controller/Controller.jsx b/sites/avivator/src/components/Controller/Controller.jsx index 075f70771..5ae9a72fb 100644 --- a/sites/avivator/src/components/Controller/Controller.jsx +++ b/sites/avivator/src/components/Controller/Controller.jsx @@ -4,7 +4,7 @@ import Grid from '@material-ui/core/Grid'; import Tabs from '@material-ui/core/Tabs'; import Tab from '@material-ui/core/Tab'; import Divider from '@material-ui/core/Divider'; -import shallow from 'zustand/shallow'; +import { shallow } from 'zustand/shallow'; import ChannelController from './components/ChannelController'; import Menu from './components/Menu'; @@ -25,7 +25,8 @@ import { useViewerStore, useImageSettingsStore, useLoader, - useMetadata + useMetadata, + useImageSettingsStoreApi } from '../../state'; import { guessRgb, useWindowSize, getSingleSelectionStats } from '../../utils'; import { GLOBAL_SLIDER_DIMENSION_FIELDS } from '../../constants'; @@ -108,6 +109,7 @@ const Controller = () => { const globalControlLabels = labels.filter(label => GLOBAL_SLIDER_DIMENSION_FIELDS.includes(label) ); + const imageSettingsStore = useImageSettingsStoreApi(); const channelControllers = ids.map((id, i) => { const onSelectionChange = e => { const selection = { @@ -132,9 +134,9 @@ const Controller = () => { newProps.colors = Channels[c].Color.slice(0, -1); } setPropertiesForChannel(i, newProps); - useImageSettingsStore.setState({ + imageSettingsStore.setState({ onViewportLoad: () => { - useImageSettingsStore.setState({ onViewportLoad: () => {} }); + imageSettingsStore.setState({ onViewportLoad: () => {} }); setIsChannelLoading(i, false); } }); diff --git a/sites/avivator/src/components/Controller/components/AddChannel.jsx b/sites/avivator/src/components/Controller/components/AddChannel.jsx index 3c667f4f6..390b04c4d 100644 --- a/sites/avivator/src/components/Controller/components/AddChannel.jsx +++ b/sites/avivator/src/components/Controller/components/AddChannel.jsx @@ -1,13 +1,13 @@ import React, { useCallback } from 'react'; import Button from '@material-ui/core/Button'; import AddIcon from '@material-ui/icons/Add'; -import shallow from 'zustand/shallow'; +import { shallow } from 'zustand/shallow'; import { MAX_CHANNELS, COLOR_PALLETE } from '../../../constants'; import { useChannelsStore, useViewerStore, - useImageSettingsStore, + useImageSettingsStoreApi, useLoader, useMetadata } from '../../../state'; @@ -41,6 +41,7 @@ const AddChannel = () => { const loader = useLoader(); const metadata = useMetadata(); const { labels } = loader[0]; + const imageSettingsStore = useImageSettingsStoreApi(); const handleChannelAdd = useCallback(() => { let selection = Object.fromEntries(labels.map(l => [l, 0])); selection = { ...selection, ...globalSelection }; @@ -55,9 +56,9 @@ const AddChannel = () => { contrastLimits, channelsVisible: true }); - useImageSettingsStore.setState({ + imageSettingsStore.setState({ onViewportLoad: () => { - useImageSettingsStore.setState({ onViewportLoad: () => {} }); + imageSettingsStore.setState({ onViewportLoad: () => {} }); setIsChannelLoading(numSelectionsBeforeAdd, false); } }); @@ -85,6 +86,7 @@ const AddChannel = () => { selections, setIsChannelLoading, setPropertiesForChannel, + imageSettingsStore, metadata ]); return ( diff --git a/sites/avivator/src/components/Controller/components/CameraOptions.jsx b/sites/avivator/src/components/Controller/components/CameraOptions.jsx index 781afefc9..e22c303cf 100644 --- a/sites/avivator/src/components/Controller/components/CameraOptions.jsx +++ b/sites/avivator/src/components/Controller/components/CameraOptions.jsx @@ -4,13 +4,14 @@ import Button from '@material-ui/core/Button'; import Grid from '@material-ui/core/Grid'; import Typography from '@material-ui/core/Typography'; import { makeStyles, createStyles } from '@material-ui/core/styles'; -import shallow from 'zustand/shallow'; +import { shallow } from 'zustand/shallow'; import { getDefaultInitialViewState } from '@hms-dbmi/viv'; import { useImageSettingsStore, useViewerStore, - useLoader + useLoader, + useViewerStoreApi } from '../../../state'; import { useWindowSize } from '../../../utils'; @@ -53,11 +54,12 @@ const CameraOptions = () => { ); + const viewerStore = useViewerStoreApi(); const reCenterButton = (