@aics/vole-app 3.4.4 → 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 +15 -5
- 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/ColorPicker/index.js +9 -1
- package/es/aics-image-viewer/components/ControlPanel/CopySettingsButton.js +445 -0
- package/es/aics-image-viewer/components/ControlPanel/index.js +16 -5
- package/es/aics-image-viewer/components/ControlPanel/styles.css +29 -2
- package/es/aics-image-viewer/components/StyleProvider/index.js +17 -2
- package/es/aics-image-viewer/components/Toolbar/ViewModeRadioButtons.js +1 -1
- package/es/aics-image-viewer/components/Toolbar/index.js +1 -1
- package/es/aics-image-viewer/components/Toolbar/styles.css +0 -10
- package/es/aics-image-viewer/components/{CellViewerCanvasWrapper → ViewerCanvasWrapper}/index.js +3 -2
- package/es/aics-image-viewer/components/dimension_sliders/AxisClipSliders.js +21 -8
- package/es/aics-image-viewer/components/dimension_sliders/RotationSliders.js +6 -8
- package/es/aics-image-viewer/components/dimension_sliders/SliderRows.js +8 -6
- package/es/aics-image-viewer/components/shared/ContextualAlert.js +101 -0
- 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 +59 -25
- package/es/aics-image-viewer/shared/constants.js +25 -1
- package/es/aics-image-viewer/shared/types.js +1 -1
- package/es/aics-image-viewer/shared/utils/controlPointsToLut.js +4 -0
- package/es/aics-image-viewer/shared/utils/parseSnapshot.js +205 -0
- package/es/aics-image-viewer/shared/utils/{urlParsing.js → parseUrl.js} +55 -191
- package/es/aics-image-viewer/shared/utils/permissions.js +46 -0
- package/es/aics-image-viewer/shared/utils/test/camera.test.js +1 -2
- package/es/aics-image-viewer/shared/utils/test/{urlParsing.test.js → parseUrl.test.js} +28 -25
- 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/deserialize.js +443 -331
- package/es/aics-image-viewer/state/reset.js +1 -1
- package/es/aics-image-viewer/state/serialize.js +168 -78
- package/es/aics-image-viewer/state/subscribers.js +1 -1
- package/es/aics-image-viewer/state/test/deserialize.test.js +63 -77
- package/es/aics-image-viewer/state/test/reset.test.js +2 -2
- package/es/aics-image-viewer/state/test/serialize.test.js +42 -43
- package/es/aics-image-viewer/state/test/test_data.js +119 -1
- package/es/aics-image-viewer/state/types.js +157 -245
- package/es/aics-image-viewer/state/util.js +39 -1
- package/es/index.js +4 -2
- package/package.json +26 -44
- package/type-declarations/aics-image-viewer/components/App/types.d.ts +3 -3
- 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 +11 -0
- package/type-declarations/aics-image-viewer/components/Toolbar/ViewModeRadioButtons.d.ts +1 -1
- package/type-declarations/aics-image-viewer/components/{CellViewerCanvasWrapper → ViewerCanvasWrapper}/index.d.ts +4 -3
- package/type-declarations/aics-image-viewer/components/dimension_sliders/AxisClipSliders.d.ts +7 -6
- package/type-declarations/aics-image-viewer/components/dimension_sliders/SliderRows.d.ts +1 -2
- package/type-declarations/aics-image-viewer/components/shared/ContextualAlert.d.ts +29 -0
- 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 +2 -2
- package/type-declarations/aics-image-viewer/shared/types.d.ts +2 -2
- package/type-declarations/aics-image-viewer/shared/utils/controlPointsToLut.d.ts +1 -1
- package/type-declarations/aics-image-viewer/shared/utils/parseSnapshot.d.ts +49 -0
- package/type-declarations/aics-image-viewer/shared/utils/{urlParsing.d.ts → parseUrl.d.ts} +3 -24
- package/type-declarations/aics-image-viewer/shared/utils/permissions.d.ts +7 -0
- package/type-declarations/aics-image-viewer/shared/utils/viewerChannelSettings.d.ts +1 -1
- package/type-declarations/aics-image-viewer/state/deserialize.d.ts +70 -35
- package/type-declarations/aics-image-viewer/state/reset.d.ts +1 -1
- package/type-declarations/aics-image-viewer/state/serialize.d.ts +44 -10
- package/type-declarations/aics-image-viewer/state/types.d.ts +265 -159
- package/type-declarations/aics-image-viewer/state/util.d.ts +3 -1
- package/type-declarations/index.d.ts +5 -3
- package/es/Globals.d.js +0 -0
- package/es/aics-image-viewer/shared/enums.js +0 -18
- package/es/aics-image-viewer/shared/utils/firebase/index.js +0 -109
- package/type-declarations/aics-image-viewer/shared/enums.d.ts +0 -15
- package/type-declarations/aics-image-viewer/shared/utils/firebase/index.d.ts +0 -69
- package/type-declarations/aics-image-viewer/shared/utils/math.d.ts +0 -1
- /package/es/aics-image-viewer/components/{CellViewerCanvasWrapper → ViewerCanvasWrapper}/styles.css +0 -0
|
@@ -25,12 +25,12 @@ import { LoadSpec, VolumeLoaderContext } from "@aics/vole-core";
|
|
|
25
25
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
26
26
|
import { Box3, Vector3 } from "three";
|
|
27
27
|
import { AXIS_TO_LOADER_PRIORITY, CACHE_MAX_SIZE, getDefaultViewerChannelSettings, QUEUE_MAX_LOW_PRIORITY_SIZE, QUEUE_MAX_SIZE } from "../shared/constants";
|
|
28
|
-
import { ViewMode } from "../shared/enums";
|
|
29
28
|
import { useConstructor, useRefWithSetter } from "../shared/utils/hooks";
|
|
30
29
|
import PlayControls from "../shared/utils/playControls";
|
|
31
30
|
import SceneStore from "../shared/utils/sceneStore";
|
|
32
31
|
import { makeChannelIndexGrouping } from "../shared/utils/viewerChannelSettings";
|
|
33
32
|
import { select, useViewerState } from "../state/store";
|
|
33
|
+
import { ViewMode } from "../state/types";
|
|
34
34
|
export var ImageLoadStatus = /*#__PURE__*/function (ImageLoadStatus) {
|
|
35
35
|
ImageLoadStatus[ImageLoadStatus["REQUESTED"] = 0] = "REQUESTED";
|
|
36
36
|
ImageLoadStatus[ImageLoadStatus["LOADING"] = 1] = "LOADING";
|
|
@@ -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;
|
|
@@ -3,7 +3,31 @@ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object
|
|
|
3
3
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
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
|
-
import { ImageType, RenderMode, ViewMode } from "
|
|
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
|
|
@@ -2,5 +2,5 @@ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" ==
|
|
|
2
2
|
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
3
3
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
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
|
-
import { ViewMode } from "
|
|
5
|
+
import { ViewMode } from "../state/types";
|
|
6
6
|
export var activeAxisMap = _defineProperty(_defineProperty(_defineProperty(_defineProperty({}, ViewMode.yz, "x"), ViewMode.xz, "y"), ViewMode.xy, "z"), ViewMode.threeD, null);
|
|
@@ -40,6 +40,10 @@ export function getDefaultLut(histogram) {
|
|
|
40
40
|
* Parses a single LUT value from a string, where the value is either a number, a percentile, or a median multiplier.
|
|
41
41
|
*/
|
|
42
42
|
function parseLutValue(value, histogram) {
|
|
43
|
+
if (typeof value === "number") {
|
|
44
|
+
return value;
|
|
45
|
+
}
|
|
46
|
+
|
|
43
47
|
// look at first char of string.
|
|
44
48
|
var firstChar = value.charAt(0);
|
|
45
49
|
if (firstChar === "m") {
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
2
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
3
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
4
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
5
|
+
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); }
|
|
6
|
+
function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
|
|
7
|
+
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
|
|
8
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
9
|
+
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
|
|
10
|
+
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
|
|
11
|
+
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
|
|
12
|
+
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
|
|
13
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
14
|
+
import { snapshotToChannelState, snapshotToViewerChannelSetting } from "../../state/deserialize";
|
|
15
|
+
import { channelStateToSnapshot } from "../../state/serialize";
|
|
16
|
+
import { cloneChannelState } from "../../state/util";
|
|
17
|
+
import { VOLEAPP_VERSION } from "../constants";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A message sent from an external application after this app was opened,
|
|
21
|
+
* containing data that was too large to pack into the URL.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/** A snapshot of app state, containing (optional) global and per-channel settings. */
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* A complete description of a viewer session, containing image URLs, global
|
|
28
|
+
* and per-channel settings, and optional image metadata.
|
|
29
|
+
*/
|
|
30
|
+
|
|
31
|
+
/** Verifies that the given object is (likely) a `StoreSnapshot`. */
|
|
32
|
+
export var isStoreSnapshot = function isStoreSnapshot(settings) {
|
|
33
|
+
var castSettings = settings;
|
|
34
|
+
return settings !== null && settings !== undefined && typeof castSettings.version === "string" && _typeof(castSettings.channels) === "object" && !Array.isArray(castSettings.channels) && Object.entries(castSettings.channels).every(function (_ref) {
|
|
35
|
+
var _ref2 = _slicedToArray(_ref, 2),
|
|
36
|
+
key = _ref2[0],
|
|
37
|
+
value = _ref2[1];
|
|
38
|
+
return typeof key === "string" && _typeof(value) === "object" && !Array.isArray(value);
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/** Verifies that the given object is (likely) a `SessionSnapshot`. */
|
|
43
|
+
export var isSessionSnapshot = function isSessionSnapshot(settings) {
|
|
44
|
+
if (!isStoreSnapshot(settings)) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
var _ref3 = settings,
|
|
48
|
+
scenes = _ref3.scenes;
|
|
49
|
+
return Array.isArray(scenes) && scenes.every(function (scene) {
|
|
50
|
+
return typeof scene === "string" || Array.isArray(scene) && scene.every(function (url) {
|
|
51
|
+
return typeof url === "string";
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/** Converts an array of `ChannelState`s to a compact JSON representation that can be stringified into the clipboard. */
|
|
57
|
+
export var channelStatesToSnapshot = function channelStatesToSnapshot(channelStates, excludeKeys) {
|
|
58
|
+
var channels = {};
|
|
59
|
+
var _iterator = _createForOfIteratorHelper(channelStates),
|
|
60
|
+
_step;
|
|
61
|
+
try {
|
|
62
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
63
|
+
var ch = _step.value;
|
|
64
|
+
var setting = cloneChannelState(ch);
|
|
65
|
+
if (excludeKeys !== undefined) {
|
|
66
|
+
var _iterator2 = _createForOfIteratorHelper(excludeKeys),
|
|
67
|
+
_step2;
|
|
68
|
+
try {
|
|
69
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
70
|
+
var key = _step2.value;
|
|
71
|
+
delete setting[key];
|
|
72
|
+
}
|
|
73
|
+
} catch (err) {
|
|
74
|
+
_iterator2.e(err);
|
|
75
|
+
} finally {
|
|
76
|
+
_iterator2.f();
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
var state = channelStateToSnapshot(setting, false);
|
|
80
|
+
channels[ch.name] = state;
|
|
81
|
+
}
|
|
82
|
+
} catch (err) {
|
|
83
|
+
_iterator.e(err);
|
|
84
|
+
} finally {
|
|
85
|
+
_iterator.f();
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
version: VOLEAPP_VERSION,
|
|
89
|
+
channels: channels
|
|
90
|
+
};
|
|
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
|
+
|
|
117
|
+
/** Converts a compacted set of `ChannelState`s from the clipboard into a record of channel names and their states. */
|
|
118
|
+
export var snapshotToChannelStates = function snapshotToChannelStates(serialized) {
|
|
119
|
+
var result = {};
|
|
120
|
+
for (var _i = 0, _Object$entries = Object.entries(serialized.channels); _i < _Object$entries.length; _i++) {
|
|
121
|
+
var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2),
|
|
122
|
+
name = _Object$entries$_i[0],
|
|
123
|
+
state = _Object$entries$_i[1];
|
|
124
|
+
result[name] = _objectSpread(_objectSpread({}, snapshotToChannelState(state)), {}, {
|
|
125
|
+
name: name
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
return result;
|
|
129
|
+
};
|
|
130
|
+
export var snapshotToViewerChannelSettings = function snapshotToViewerChannelSettings(serialized) {
|
|
131
|
+
var snapshots = Object.entries(serialized.channels);
|
|
132
|
+
if (snapshots.length === 0) {
|
|
133
|
+
return undefined;
|
|
134
|
+
}
|
|
135
|
+
var channels = snapshots.map(function (_ref4) {
|
|
136
|
+
var _ref5 = _slicedToArray(_ref4, 2),
|
|
137
|
+
name = _ref5[0],
|
|
138
|
+
snap = _ref5[1];
|
|
139
|
+
return snapshotToViewerChannelSetting(name, snap);
|
|
140
|
+
});
|
|
141
|
+
return {
|
|
142
|
+
groups: [{
|
|
143
|
+
name: "Channels",
|
|
144
|
+
channels: channels
|
|
145
|
+
}]
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Parses a `ViewerMessage` into the relevant entries in `AppProps`.
|
|
151
|
+
*
|
|
152
|
+
* Optionally accepts the current value of the `imageUrl` prop, for the case where the message contains only metadata
|
|
153
|
+
* and the image URLs that correspond to the metadata were passed in by other means.
|
|
154
|
+
*/
|
|
155
|
+
export function viewerMessageToParams(message, propUrl) {
|
|
156
|
+
var _message$scenes;
|
|
157
|
+
// get scenes
|
|
158
|
+
var scenes = (_message$scenes = message.scenes) !== null && _message$scenes !== void 0 ? _message$scenes : propUrl && (typeof propUrl === "string" ? [propUrl] : propUrl.scenes);
|
|
159
|
+
if (scenes === undefined || scenes === "" || scenes.length === 0 || scenes.length === 1 && scenes[0] === "") {
|
|
160
|
+
return {};
|
|
161
|
+
}
|
|
162
|
+
var firstScene = scenes[0];
|
|
163
|
+
var imageUrl = scenes.length === 1 && typeof firstScene === "string" ? firstScene : {
|
|
164
|
+
scenes: scenes
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
// get metadata
|
|
168
|
+
var meta = message.meta;
|
|
169
|
+
var metadata = meta && scenes.map(function (scene) {
|
|
170
|
+
if (Array.isArray(scene) && scene.length > 1) {
|
|
171
|
+
// can't handle multi-source scenes (yet)
|
|
172
|
+
console.warn("Can't apply metadata to multi-source scene", scene);
|
|
173
|
+
return undefined;
|
|
174
|
+
}
|
|
175
|
+
var sceneString = Array.isArray(scene) ? scene[0] : scene;
|
|
176
|
+
return meta[sceneString];
|
|
177
|
+
});
|
|
178
|
+
return {
|
|
179
|
+
imageUrl: imageUrl,
|
|
180
|
+
metadata: metadata
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/** Formats the values of the `imageUrl` and `metadata` props to `App` as a `ViewerMessage`. */
|
|
185
|
+
export function paramsToViewerMessage(imageUrl, metadata) {
|
|
186
|
+
var scenes = typeof imageUrl === "string" ? [imageUrl] : imageUrl.scenes;
|
|
187
|
+
if (metadata === undefined) {
|
|
188
|
+
return {
|
|
189
|
+
scenes: scenes
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
var meta = {};
|
|
193
|
+
scenes.forEach(function (scene, index) {
|
|
194
|
+
var value = metadata[index];
|
|
195
|
+
// Can't save a metadata record if there isn't any metadata or the image is multi-source
|
|
196
|
+
if (value === undefined || Array.isArray(scene) && scene.length !== 1) {
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
meta[Array.isArray(scene) ? scene[0] : scene] = value;
|
|
200
|
+
});
|
|
201
|
+
return {
|
|
202
|
+
scenes: scenes,
|
|
203
|
+
meta: meta
|
|
204
|
+
};
|
|
205
|
+
}
|