@aics/vole-app 3.5.0 → 3.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/es/aics-image-viewer/components/App/index.js +10 -0
- package/es/aics-image-viewer/components/ChannelsWidget.js +3 -1
- package/es/aics-image-viewer/components/ChannelsWidgetRow.js +29 -16
- package/es/aics-image-viewer/components/ControlPanel/CopySettingsButton.js +177 -147
- package/es/aics-image-viewer/components/ControlPanel/index.js +4 -1
- package/es/aics-image-viewer/components/Toolbar/styles.css +0 -10
- package/es/aics-image-viewer/components/ViewerCanvasWrapper/index.js +2 -1
- package/es/aics-image-viewer/components/dimension_sliders/AxisClipSliders.js +21 -8
- package/es/aics-image-viewer/components/dimension_sliders/RotationSliders.js +5 -7
- package/es/aics-image-viewer/components/dimension_sliders/SliderRows.js +8 -6
- package/es/aics-image-viewer/components/shared/ControlPanelRow/index.js +4 -2
- package/es/aics-image-viewer/components/shared/ControlPanelRow/styles.css +4 -3
- package/es/aics-image-viewer/components/useVolume.js +58 -24
- package/es/aics-image-viewer/shared/constants.js +24 -0
- package/es/aics-image-viewer/shared/utils/parseSnapshot.js +28 -2
- package/es/aics-image-viewer/shared/utils/parseUrl.js +41 -139
- package/es/aics-image-viewer/shared/utils/test/camera.test.js +1 -1
- package/es/aics-image-viewer/shared/utils/test/parseUrl.test.js +20 -20
- package/es/aics-image-viewer/shared/utils/test/storage.test.js +2 -2
- package/es/aics-image-viewer/shared/utils/test/viewerChannelSettings.test.js +1 -1
- package/es/aics-image-viewer/state/test/deserialize.test.js +1 -1
- package/es/aics-image-viewer/state/test/reset.test.js +1 -1
- package/es/aics-image-viewer/state/test/serialize.test.js +1 -0
- package/package.json +26 -44
- package/type-declarations/aics-image-viewer/components/ChannelsWidget.d.ts +3 -0
- package/type-declarations/aics-image-viewer/components/ChannelsWidgetRow.d.ts +3 -0
- package/type-declarations/aics-image-viewer/components/ControlPanel/CopySettingsButton.d.ts +2 -0
- package/type-declarations/aics-image-viewer/components/ViewerCanvasWrapper/index.d.ts +1 -0
- package/type-declarations/aics-image-viewer/components/dimension_sliders/AxisClipSliders.d.ts +1 -0
- package/type-declarations/aics-image-viewer/components/dimension_sliders/SliderRows.d.ts +1 -2
- package/type-declarations/aics-image-viewer/components/shared/ControlPanelRow/index.d.ts +1 -0
- package/type-declarations/aics-image-viewer/components/useVolume.d.ts +3 -0
- package/type-declarations/aics-image-viewer/shared/constants.d.ts +1 -0
- package/type-declarations/aics-image-viewer/shared/utils/parseSnapshot.d.ts +2 -0
- package/type-declarations/aics-image-viewer/shared/utils/parseUrl.d.ts +1 -8
- package/es/Globals.d.js +0 -0
- package/es/aics-image-viewer/shared/utils/firebase/index.js +0 -109
- package/type-declarations/aics-image-viewer/shared/utils/firebase/index.d.ts +0 -69
|
@@ -25,13 +25,25 @@ export var AxisClipSliders = function AxisClipSliders(props) {
|
|
|
25
25
|
changeViewerSetting("region", _defineProperty({}, axis, [start, end]));
|
|
26
26
|
};
|
|
27
27
|
var updateSlice = function updateSlice(axis, slice) {
|
|
28
|
+
var isScrubbing = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
|
|
28
29
|
pauseOnInput(axis);
|
|
30
|
+
if (isScrubbing) {
|
|
31
|
+
props.setScrubbingAxis(axis);
|
|
32
|
+
}
|
|
29
33
|
props.changeViewerSetting("slice", _defineProperty({}, axis, slice / props.numSlices[axis]));
|
|
30
34
|
};
|
|
31
35
|
var updateTime = function updateTime(time) {
|
|
36
|
+
var isScrubbing = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
32
37
|
pauseOnInput("t");
|
|
38
|
+
if (isScrubbing) {
|
|
39
|
+
props.setScrubbingAxis("t");
|
|
40
|
+
}
|
|
33
41
|
props.changeViewerSetting("time", time);
|
|
34
42
|
};
|
|
43
|
+
var endScrub = function endScrub() {
|
|
44
|
+
props.setScrubbingAxis(null);
|
|
45
|
+
props.playControls.endHold();
|
|
46
|
+
};
|
|
35
47
|
|
|
36
48
|
// Pause when view mode or volume size has changed
|
|
37
49
|
useEffect(function () {
|
|
@@ -54,20 +66,20 @@ export var AxisClipSliders = function AxisClipSliders(props) {
|
|
|
54
66
|
label: axis.toUpperCase(),
|
|
55
67
|
val: Math.round(props.slices[axis] * numSlices),
|
|
56
68
|
max: numSlices,
|
|
69
|
+
onSlide: function onSlide(val) {
|
|
70
|
+
return updateSlice(axis, val, true);
|
|
71
|
+
},
|
|
57
72
|
onChange: function onChange(val) {
|
|
58
73
|
return updateSlice(axis, val);
|
|
59
74
|
},
|
|
60
75
|
onStart: function onStart() {
|
|
61
76
|
return props.playControls.startHold(axis);
|
|
62
77
|
},
|
|
63
|
-
onEnd:
|
|
64
|
-
return props.playControls.endHold();
|
|
65
|
-
},
|
|
78
|
+
onEnd: endScrub,
|
|
66
79
|
playing: props.playingAxis === axis,
|
|
67
80
|
onTogglePlayback: function onTogglePlayback(willPlay) {
|
|
68
81
|
return handlePlayPause(axis, willPlay);
|
|
69
|
-
}
|
|
70
|
-
updateWhileSliding: numSlices === numSlicesLoaded
|
|
82
|
+
}
|
|
71
83
|
}));
|
|
72
84
|
};
|
|
73
85
|
var create3dAxisSlider = function create3dAxisSlider(axis) {
|
|
@@ -119,15 +131,16 @@ export var AxisClipSliders = function AxisClipSliders(props) {
|
|
|
119
131
|
onTogglePlayback: function onTogglePlayback(willPlay) {
|
|
120
132
|
return handlePlayPause("t", willPlay);
|
|
121
133
|
},
|
|
134
|
+
onSlide: function onSlide(time) {
|
|
135
|
+
return updateTime(time, true);
|
|
136
|
+
},
|
|
122
137
|
onChange: function onChange(time) {
|
|
123
138
|
return updateTime(time);
|
|
124
139
|
},
|
|
125
140
|
onStart: function onStart() {
|
|
126
141
|
return props.playControls.startHold("t");
|
|
127
142
|
},
|
|
128
|
-
onEnd:
|
|
129
|
-
return props.playControls.endHold();
|
|
130
|
-
}
|
|
143
|
+
onEnd: endScrub
|
|
131
144
|
})))), props.numScenes > 1 && /*#__PURE__*/React.createElement("span", {
|
|
132
145
|
className: "slider-group"
|
|
133
146
|
}, /*#__PURE__*/React.createElement("span", {
|
|
@@ -100,21 +100,19 @@ export var RotationSliders = function RotationSliders(_ref) {
|
|
|
100
100
|
|
|
101
101
|
// Set up event listeners on mount.
|
|
102
102
|
useEffect(function () {
|
|
103
|
-
|
|
104
|
-
// At time of writing, `setOnRenderCallback` appears not to be used anywhere else in either this package or
|
|
105
|
-
// vole-core, but that could change at any time.
|
|
106
|
-
// Ideally `View3d` would have an `addEventListener`/`removeEventListener` model.
|
|
107
|
-
view3d.setOnRenderCallback(function () {
|
|
103
|
+
var renderListener = function renderListener() {
|
|
108
104
|
if (!hasControlRef.current) {
|
|
109
105
|
setRotation(getRotationAngles(view3d.getCameraState()));
|
|
110
106
|
}
|
|
111
|
-
}
|
|
107
|
+
};
|
|
108
|
+
view3d.addEventListener("render", renderListener);
|
|
112
109
|
var clickListener = function clickListener() {
|
|
113
110
|
return hasControlRef.current = false;
|
|
114
111
|
};
|
|
115
112
|
view3d.getDOMElement().addEventListener("mousedown", clickListener);
|
|
116
113
|
return function () {
|
|
117
|
-
|
|
114
|
+
view3d.removeEventListener("render", renderListener);
|
|
115
|
+
view3d.getDOMElement().removeEventListener("mousedown", clickListener);
|
|
118
116
|
};
|
|
119
117
|
}, [view3d]);
|
|
120
118
|
var createRotateSlider = function createRotateSlider(axis) {
|
|
@@ -116,6 +116,7 @@ export var IndexSliderRow = function IndexSliderRow(props) {
|
|
|
116
116
|
/** Wrapper around `SliderRow` that adds a play button and accounts for the case where not all of an axis is loaded. */
|
|
117
117
|
export var PlaySliderRow = function PlaySliderRow(props) {
|
|
118
118
|
var onChange = props.onChange,
|
|
119
|
+
onSlide = props.onSlide,
|
|
119
120
|
onStart = props.onStart,
|
|
120
121
|
onEnd = props.onEnd;
|
|
121
122
|
// In partially-loaded axes, stores the displayed value of the slider while the user is sliding it
|
|
@@ -131,9 +132,10 @@ export var PlaySliderRow = function PlaySliderRow(props) {
|
|
|
131
132
|
var wrappedOnChange = useCallback(function (val) {
|
|
132
133
|
return onChange === null || onChange === void 0 ? void 0 : onChange(val);
|
|
133
134
|
}, [onChange]);
|
|
134
|
-
var
|
|
135
|
-
|
|
136
|
-
|
|
135
|
+
var wrappedOnSlide = useCallback(function (val) {
|
|
136
|
+
setValReadout(val);
|
|
137
|
+
onSlide === null || onSlide === void 0 || onSlide(val);
|
|
138
|
+
}, [onSlide]);
|
|
137
139
|
var wrappedOnStart = useCallback(function () {
|
|
138
140
|
setValReadout(props.val);
|
|
139
141
|
setSliderHeld(true);
|
|
@@ -146,10 +148,10 @@ export var PlaySliderRow = function PlaySliderRow(props) {
|
|
|
146
148
|
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(IndexSliderRow, {
|
|
147
149
|
label: props.label,
|
|
148
150
|
val: props.val,
|
|
149
|
-
valReadout:
|
|
151
|
+
valReadout: !sliderHeld ? undefined : valReadout,
|
|
150
152
|
max: props.max,
|
|
151
|
-
onSlide:
|
|
152
|
-
onChange:
|
|
153
|
+
onSlide: wrappedOnSlide,
|
|
154
|
+
onChange: wrappedOnChange,
|
|
153
155
|
onStart: wrappedOnStart,
|
|
154
156
|
onEnd: wrappedOnEnd
|
|
155
157
|
}), props.max > 1 && /*#__PURE__*/React.createElement(Tooltip, {
|
|
@@ -31,7 +31,7 @@ var ControlPanelRow = function ControlPanelRow(inputProps) {
|
|
|
31
31
|
var style = {
|
|
32
32
|
"--control-panel-row-vertical-margin": props.verticalMargin + "px"
|
|
33
33
|
};
|
|
34
|
-
var createTitle = props.title !== undefined || props.showColorPicker;
|
|
34
|
+
var createTitle = props.title !== undefined || props.icon !== undefined || props.showColorPicker;
|
|
35
35
|
var baseClass = "control-panel-row".concat(props.highlight ? " control-panel-row-highlight" : "");
|
|
36
36
|
var className = props.className ? "".concat(baseClass, " ").concat(props.className) : baseClass;
|
|
37
37
|
return /*#__PURE__*/React.createElement("div", {
|
|
@@ -40,7 +40,9 @@ var ControlPanelRow = function ControlPanelRow(inputProps) {
|
|
|
40
40
|
onClick: props.onClick
|
|
41
41
|
}, createTitle && /*#__PURE__*/React.createElement("div", {
|
|
42
42
|
className: "control-panel-row-title"
|
|
43
|
-
}, props.
|
|
43
|
+
}, props.icon && /*#__PURE__*/React.createElement("div", {
|
|
44
|
+
className: "control-panel-row-icon"
|
|
45
|
+
}, props.icon), props.showColorPicker && /*#__PURE__*/React.createElement(ColorPicker, _extends({
|
|
44
46
|
disableAlpha: true,
|
|
45
47
|
width: 18
|
|
46
48
|
}, colorPickerProps)), props.title && /*#__PURE__*/React.createElement("h4", null, props.title)), props.children);
|
|
@@ -16,8 +16,10 @@
|
|
|
16
16
|
flex-grow:1;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
.control-panel-col .control-panel-row .control-panel-row-title .color-picker
|
|
20
|
-
|
|
19
|
+
.control-panel-col .control-panel-row .control-panel-row-title .color-picker,
|
|
20
|
+
.control-panel-col .control-panel-row .control-panel-row-title .control-panel-row-icon{
|
|
21
|
+
margin-right:10px;
|
|
22
|
+
font-size:12px;
|
|
21
23
|
}
|
|
22
24
|
|
|
23
25
|
.control-panel-col .control-panel-row .control-panel-row-title h4{
|
|
@@ -58,7 +60,6 @@
|
|
|
58
60
|
width:100%;
|
|
59
61
|
border-bottom:1px solid var(--color-controlpanel-border);
|
|
60
62
|
}
|
|
61
|
-
|
|
62
63
|
.control-panel-col .ant-collapse-item:not(:last-child) .control-panel-row:last-child::after{
|
|
63
64
|
border-bottom:none;
|
|
64
65
|
}
|
|
@@ -39,7 +39,7 @@ export var ImageLoadStatus = /*#__PURE__*/function (ImageLoadStatus) {
|
|
|
39
39
|
return ImageLoadStatus;
|
|
40
40
|
}({});
|
|
41
41
|
var LoadType = /*#__PURE__*/function (LoadType) {
|
|
42
|
-
LoadType[LoadType["
|
|
42
|
+
LoadType[LoadType["RELOAD"] = 0] = "RELOAD";
|
|
43
43
|
LoadType[LoadType["SCENE"] = 1] = "SCENE";
|
|
44
44
|
return LoadType;
|
|
45
45
|
}(LoadType || {}); // Used by `channelVersions` (see below)
|
|
@@ -84,6 +84,7 @@ var useVolume = function useVolume(scenePaths, options) {
|
|
|
84
84
|
var onChannelLoadedRef = useEffectEventRef(options === null || options === void 0 ? void 0 : options.onChannelLoaded);
|
|
85
85
|
var onChangeSceneRef = useEffectEventRef(options === null || options === void 0 ? void 0 : options.onChangeScene);
|
|
86
86
|
var onCreateImageRef = useEffectEventRef(options === null || options === void 0 ? void 0 : options.onCreateImage);
|
|
87
|
+
var onScrubRef = useEffectEventRef(options === null || options === void 0 ? void 0 : options.onScrub);
|
|
87
88
|
var maskChannelName = options === null || options === void 0 ? void 0 : options.maskChannelName;
|
|
88
89
|
|
|
89
90
|
// set up our big objects: the image, its loading infrastructure, and controls for playback
|
|
@@ -104,6 +105,10 @@ var useVolume = function useVolume(scenePaths, options) {
|
|
|
104
105
|
_useState4 = _slicedToArray(_useState3, 2),
|
|
105
106
|
playingAxis = _useState4[0],
|
|
106
107
|
setPlayingAxis = _useState4[1];
|
|
108
|
+
var _useState5 = useState(null),
|
|
109
|
+
_useState6 = _slicedToArray(_useState5, 2),
|
|
110
|
+
scrubbingAxis = _useState6[0],
|
|
111
|
+
setScrubbingAxis = _useState6[1];
|
|
107
112
|
useEffect(function () {
|
|
108
113
|
playControls.onPlayingAxisChanged = function (axis) {
|
|
109
114
|
var isPlaying = axis !== null;
|
|
@@ -113,36 +118,24 @@ var useVolume = function useVolume(scenePaths, options) {
|
|
|
113
118
|
sceneLoader.updateFetchOptions({
|
|
114
119
|
onlyPriorityDirections: isPlaying
|
|
115
120
|
});
|
|
116
|
-
// sync multichannel loading so we don't show loaded channels one at a time
|
|
117
|
-
sceneLoader.syncMultichannelLoading(isPlaying);
|
|
118
|
-
if (image) {
|
|
119
|
-
// If we're playing and entire axis is not in memory (T always, Z likely), downlevel to speed things up
|
|
120
|
-
var _image$imageInfo = image.imageInfo,
|
|
121
|
-
volumeSize = _image$imageInfo.volumeSize,
|
|
122
|
-
subregionSize = _image$imageInfo.subregionSize;
|
|
123
|
-
var shouldDownlevel = isPlaying && (axis === "t" || volumeSize[axis] !== subregionSize[axis]);
|
|
124
|
-
image.updateRequiredData({
|
|
125
|
-
scaleLevelBias: shouldDownlevel ? 1 : 0
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
121
|
};
|
|
129
122
|
}, [sceneLoader, playControls, image]);
|
|
130
123
|
|
|
131
124
|
// track which channels have been loaded
|
|
132
|
-
var
|
|
133
|
-
|
|
134
|
-
channelVersions =
|
|
135
|
-
_setChannelVersions =
|
|
125
|
+
var _useState7 = useState([]),
|
|
126
|
+
_useState8 = _slicedToArray(_useState7, 2),
|
|
127
|
+
channelVersions = _useState8[0],
|
|
128
|
+
_setChannelVersions = _useState8[1];
|
|
136
129
|
var _useRefWithSetter = useRefWithSetter(_setChannelVersions, channelVersions),
|
|
137
130
|
_useRefWithSetter2 = _slicedToArray(_useRefWithSetter, 2),
|
|
138
131
|
channelVersionsRef = _useRefWithSetter2[0],
|
|
139
132
|
setChannelVersions = _useRefWithSetter2[1];
|
|
140
133
|
|
|
141
134
|
// Some extra items for tracking load status
|
|
142
|
-
var
|
|
143
|
-
|
|
144
|
-
loadThrewError =
|
|
145
|
-
setLoadThrewError =
|
|
135
|
+
var _useState9 = useState(false),
|
|
136
|
+
_useState0 = _slicedToArray(_useState9, 2),
|
|
137
|
+
loadThrewError = _useState0[0],
|
|
138
|
+
setLoadThrewError = _useState0[1];
|
|
146
139
|
var inInitialLoadRef = useRef(true);
|
|
147
140
|
|
|
148
141
|
// derive whether the image is loaded from whether any and/or all channels are loaded
|
|
@@ -178,11 +171,41 @@ var useVolume = function useVolume(scenePaths, options) {
|
|
|
178
171
|
);
|
|
179
172
|
}));
|
|
180
173
|
}, [channelVersionsRef, setChannelVersions]);
|
|
174
|
+
useEffect(function () {
|
|
175
|
+
if (!image) return;
|
|
176
|
+
var onLoadStart = function onLoadStart() {
|
|
177
|
+
return setIsLoading(LoadType.RELOAD);
|
|
178
|
+
};
|
|
179
|
+
image.addEventListener("loadStart", onLoadStart);
|
|
180
|
+
return function () {
|
|
181
|
+
return image.removeEventListener("loadStart", onLoadStart);
|
|
182
|
+
};
|
|
183
|
+
}, [image, setIsLoading]);
|
|
181
184
|
var onError = useCallback(function (e) {
|
|
182
185
|
setLoadThrewError(true);
|
|
183
186
|
onErrorRef(e);
|
|
184
187
|
throw e;
|
|
185
188
|
}, [onErrorRef]);
|
|
189
|
+
var scaleLevelBias = useMemo(function () {
|
|
190
|
+
if (!image) return 0;
|
|
191
|
+
|
|
192
|
+
// If we're playing/scrubbing and entire axis is not in memory, downlevel to speed things up
|
|
193
|
+
var _image$imageInfo = image.imageInfo,
|
|
194
|
+
volumeSize = _image$imageInfo.volumeSize,
|
|
195
|
+
subregionSize = _image$imageInfo.subregionSize,
|
|
196
|
+
numMultiscaleLevels = _image$imageInfo.numMultiscaleLevels;
|
|
197
|
+
var axis = scrubbingAxis !== null && scrubbingAxis !== void 0 ? scrubbingAxis : playingAxis;
|
|
198
|
+
if (axis && (axis === "t" || volumeSize[axis] !== subregionSize[axis])) {
|
|
199
|
+
var isPlayback = scrubbingAxis !== null;
|
|
200
|
+
return isPlayback ? numMultiscaleLevels : 1;
|
|
201
|
+
}
|
|
202
|
+
return 0;
|
|
203
|
+
}, [image, playingAxis, scrubbingAxis]);
|
|
204
|
+
useEffect(function () {
|
|
205
|
+
image === null || image === void 0 || image.updateRequiredData({
|
|
206
|
+
scaleLevelBias: scaleLevelBias
|
|
207
|
+
})["catch"](onError);
|
|
208
|
+
}, [scaleLevelBias, image, onError]);
|
|
186
209
|
|
|
187
210
|
// channelGroupedByType groups channel indexes by their category.
|
|
188
211
|
// It depends on `viewerChannelSettings` and the channel names in the current image.
|
|
@@ -310,9 +333,8 @@ var useVolume = function useVolume(scenePaths, options) {
|
|
|
310
333
|
var setTime = useCallback(function (view3d, time) {
|
|
311
334
|
if (image && !inInitialLoadRef.current) {
|
|
312
335
|
view3d.setTime(image, time)["catch"](onError);
|
|
313
|
-
setIsLoading(LoadType.TIME);
|
|
314
336
|
}
|
|
315
|
-
}, [image, onError,
|
|
337
|
+
}, [image, onError, inInitialLoadRef]);
|
|
316
338
|
var setScene = useCallback(function (scene) {
|
|
317
339
|
if (image && !inInitialLoadRef.current) {
|
|
318
340
|
var onCreateScene = function onCreateScene(volume, sceneIndex, loadSpec) {
|
|
@@ -335,6 +357,17 @@ var useVolume = function useVolume(scenePaths, options) {
|
|
|
335
357
|
setIsLoading(LoadType.SCENE);
|
|
336
358
|
}
|
|
337
359
|
}, [image, sceneLoader, onError, setIsLoading, setChannelStateForNewImage, channelVersionsRef, setChannelVersions, onChangeSceneRef]);
|
|
360
|
+
useEffect(function () {
|
|
361
|
+
if (image && !inInitialLoadRef.current) {
|
|
362
|
+
// When playing, wait for all channels to load before displaying
|
|
363
|
+
// When scrubbing, show channels as they arrive, for speed
|
|
364
|
+
sceneLoader.syncMultichannelLoading(scrubbingAxis === null && playingAxis !== null);
|
|
365
|
+
}
|
|
366
|
+
}, [image, scrubbingAxis, playingAxis, sceneLoader]);
|
|
367
|
+
useEffect(function () {
|
|
368
|
+
if (!image) return;
|
|
369
|
+
onScrubRef(scrubbingAxis !== null, image);
|
|
370
|
+
}, [onScrubRef, scrubbingAxis, image]);
|
|
338
371
|
return useMemo(function () {
|
|
339
372
|
return {
|
|
340
373
|
image: image,
|
|
@@ -342,10 +375,11 @@ var useVolume = function useVolume(scenePaths, options) {
|
|
|
342
375
|
imageLoadStatus: imageLoadStatus,
|
|
343
376
|
setTime: setTime,
|
|
344
377
|
setScene: setScene,
|
|
378
|
+
setScrubbingAxis: setScrubbingAxis,
|
|
345
379
|
playControls: playControls,
|
|
346
380
|
playingAxis: playingAxis,
|
|
347
381
|
channelGroupedByType: channelGroupedByType
|
|
348
382
|
};
|
|
349
|
-
}, [image, channelVersions, imageLoadStatus, setTime, setScene, playControls, playingAxis, channelGroupedByType]);
|
|
383
|
+
}, [image, channelVersions, imageLoadStatus, setTime, setScene, setScrubbingAxis, playControls, playingAxis, channelGroupedByType]);
|
|
350
384
|
};
|
|
351
385
|
export default useVolume;
|
|
@@ -4,6 +4,30 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
|
|
|
4
4
|
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
5
5
|
import { PrefetchDirection } from "@aics/vole-core";
|
|
6
6
|
import { ImageType, RenderMode, ViewMode } from "../state/types";
|
|
7
|
+
/**
|
|
8
|
+
* Gets the current vole-app version safely across the different app and library
|
|
9
|
+
* build environments.
|
|
10
|
+
*/
|
|
11
|
+
function getBuildVersion() {
|
|
12
|
+
// Defined as global constants when built by Vite as an app
|
|
13
|
+
if (typeof VITE_VOLEAPP_VERSION === "string" && VITE_VOLEAPP_VERSION.length > 0) {
|
|
14
|
+
return VITE_VOLEAPP_VERSION;
|
|
15
|
+
}
|
|
16
|
+
// Injected at build time when built by Babel as a library
|
|
17
|
+
try {
|
|
18
|
+
return "3.6.0";
|
|
19
|
+
} catch (_unused) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
var buildVersion = getBuildVersion();
|
|
24
|
+
if (buildVersion === undefined) {
|
|
25
|
+
console.error("Failed to determine VOLEAPP_VERSION; a default fallback will be used instead. This is likely due to a build environment misconfiguration.");
|
|
26
|
+
}
|
|
27
|
+
// 3.5.0 is the first version where app versions are serialized to channel
|
|
28
|
+
// state, and is used as the fallback.
|
|
29
|
+
export var VOLEAPP_VERSION = buildVersion !== null && buildVersion !== void 0 ? buildVersion : "3.5.0";
|
|
30
|
+
|
|
7
31
|
// Add all exported constants here to prevent circular dependencies
|
|
8
32
|
export var
|
|
9
33
|
// Control panel will automatically close if viewport is less than this width
|
|
@@ -14,6 +14,7 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" ==
|
|
|
14
14
|
import { snapshotToChannelState, snapshotToViewerChannelSetting } from "../../state/deserialize";
|
|
15
15
|
import { channelStateToSnapshot } from "../../state/serialize";
|
|
16
16
|
import { cloneChannelState } from "../../state/util";
|
|
17
|
+
import { VOLEAPP_VERSION } from "../constants";
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* A message sent from an external application after this app was opened,
|
|
@@ -89,6 +90,30 @@ export var channelStatesToSnapshot = function channelStatesToSnapshot(channelSta
|
|
|
89
90
|
};
|
|
90
91
|
};
|
|
91
92
|
|
|
93
|
+
/** Converts a single `ChannelState` to a compact JSON representation that can be stringified into the clipboard. */
|
|
94
|
+
export var singleChannelStateToSnapshot = function singleChannelStateToSnapshot(channelState, excludeKeys) {
|
|
95
|
+
var setting = cloneChannelState(channelState);
|
|
96
|
+
if (excludeKeys !== undefined) {
|
|
97
|
+
var _iterator3 = _createForOfIteratorHelper(excludeKeys),
|
|
98
|
+
_step3;
|
|
99
|
+
try {
|
|
100
|
+
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
|
|
101
|
+
var key = _step3.value;
|
|
102
|
+
delete setting[key];
|
|
103
|
+
}
|
|
104
|
+
} catch (err) {
|
|
105
|
+
_iterator3.e(err);
|
|
106
|
+
} finally {
|
|
107
|
+
_iterator3.f();
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
var channels = _defineProperty({}, setting.name, channelStateToSnapshot(setting, false));
|
|
111
|
+
return {
|
|
112
|
+
version: VOLEAPP_VERSION,
|
|
113
|
+
channels: channels
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
|
|
92
117
|
/** Converts a compacted set of `ChannelState`s from the clipboard into a record of channel names and their states. */
|
|
93
118
|
export var snapshotToChannelStates = function snapshotToChannelStates(serialized) {
|
|
94
119
|
var result = {};
|
|
@@ -142,12 +167,13 @@ export function viewerMessageToParams(message, propUrl) {
|
|
|
142
167
|
// get metadata
|
|
143
168
|
var meta = message.meta;
|
|
144
169
|
var metadata = meta && scenes.map(function (scene) {
|
|
145
|
-
if (Array.isArray(scene)) {
|
|
170
|
+
if (Array.isArray(scene) && scene.length > 1) {
|
|
146
171
|
// can't handle multi-source scenes (yet)
|
|
147
172
|
console.warn("Can't apply metadata to multi-source scene", scene);
|
|
148
173
|
return undefined;
|
|
149
174
|
}
|
|
150
|
-
|
|
175
|
+
var sceneString = Array.isArray(scene) ? scene[0] : scene;
|
|
176
|
+
return meta[sceneString];
|
|
151
177
|
});
|
|
152
178
|
return {
|
|
153
179
|
imageUrl: imageUrl,
|