fix some loading issues and rework cine button
This commit is contained in:
+79
-49
@@ -3189,29 +3189,37 @@ export default function App({ container_id, imageStacks, autoCacheStack, annotat
|
|||||||
name: string,
|
name: string,
|
||||||
requestedZone: ViewportDropZone,
|
requestedZone: ViewportDropZone,
|
||||||
) => {
|
) => {
|
||||||
const imageIds = await expandMultiframeImageIds(rawImageIds.map(normalizeToWadouriOrExternal));
|
const normalizedRawImageIds = dedupeImageIds(rawImageIds.map(normalizeToWadouriOrExternal));
|
||||||
|
if (normalizedRawImageIds.length === 0) return;
|
||||||
|
|
||||||
|
const existingStackIdx = availableStacks.findIndex((stackObj) => {
|
||||||
|
const existing = dedupeImageIds((stackObj.imageIds || []).map(normalizeToWadouriOrExternal));
|
||||||
|
return (
|
||||||
|
existing.length === normalizedRawImageIds.length
|
||||||
|
&& existing.every((id, idx) => id === normalizedRawImageIds[idx])
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingStackIdx !== -1) {
|
||||||
|
// Reuse existing stack definitions whenever possible to avoid expensive
|
||||||
|
// expansion/probing and unnecessary network requests.
|
||||||
|
await applyStackDrop(viewportIdx, existingStackIdx, requestedZone);
|
||||||
|
setActiveViewport(viewportIdx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const imageIds = await expandMultiframeImageIds(normalizedRawImageIds);
|
||||||
if (imageIds.length === 0) return;
|
if (imageIds.length === 0) return;
|
||||||
await setLoadedImageIdsAndCacheMeta(imageIds, { force: Boolean(autoCacheStack) });
|
await setLoadedImageIdsAndCacheMeta(imageIds, { force: Boolean(autoCacheStack) });
|
||||||
const seriesGroups = await deriveSeriesGroupsFromImageIds(imageIds);
|
const seriesGroups = await deriveSeriesGroupsFromImageIds(imageIds);
|
||||||
const primarySeries = seriesGroups[0]?.imageIds || imageIds;
|
const primarySeries = seriesGroups[0]?.imageIds || imageIds;
|
||||||
|
|
||||||
|
|
||||||
// Check if a stack with the same imageIds already exists
|
|
||||||
let existingStackIdx = -1;
|
|
||||||
let newStackIdx = -1;
|
let newStackIdx = -1;
|
||||||
setAvailableStacks(prev => {
|
setAvailableStacks(prev => {
|
||||||
existingStackIdx = prev.findIndex(
|
|
||||||
s =>
|
|
||||||
s.imageIds.length === imageIds.length &&
|
|
||||||
s.imageIds.every((id, idx) => id === imageIds[idx])
|
|
||||||
);
|
|
||||||
if (existingStackIdx !== -1) {
|
|
||||||
return prev;
|
|
||||||
}
|
|
||||||
newStackIdx = prev.length;
|
newStackIdx = prev.length;
|
||||||
return [...prev, { imageIds, name, seriesGroups, groupingSource: "derived" }];
|
return [...prev, { imageIds, name, seriesGroups, groupingSource: "derived" }];
|
||||||
});
|
});
|
||||||
const stackIdxToUse = existingStackIdx !== -1 ? existingStackIdx : newStackIdx;
|
const stackIdxToUse = newStackIdx;
|
||||||
|
|
||||||
const resolvedZone = resolveDropZone(requestedZone);
|
const resolvedZone = resolveDropZone(requestedZone);
|
||||||
if (resolvedZone === 'center') {
|
if (resolvedZone === 'center') {
|
||||||
@@ -5583,6 +5591,26 @@ export default function App({ container_id, imageStacks, autoCacheStack, annotat
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{loadingState === "displayset" && (
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
inset: 0,
|
||||||
|
zIndex: 58,
|
||||||
|
pointerEvents: "none",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
color: "rgba(255,255,255,0.78)",
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeight: 600,
|
||||||
|
letterSpacing: 0.2,
|
||||||
|
textShadow: "0 1px 3px rgba(0,0,0,0.55)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Loading images...
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<button
|
<button
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
@@ -5736,6 +5764,42 @@ export default function App({ container_id, imageStacks, autoCacheStack, annotat
|
|||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
style={{
|
||||||
|
position: "absolute",
|
||||||
|
top: 78,
|
||||||
|
left: 8,
|
||||||
|
zIndex: 20,
|
||||||
|
background: cineControlsOpenByViewport[i] ? "rgba(30,120,200,0.95)" : "#111",
|
||||||
|
color: "#fff",
|
||||||
|
border: "none",
|
||||||
|
borderRadius: "4px",
|
||||||
|
padding: "4px 8px",
|
||||||
|
cursor: "pointer",
|
||||||
|
fontSize: "16px",
|
||||||
|
lineHeight: 1,
|
||||||
|
opacity: 0.9,
|
||||||
|
}}
|
||||||
|
title={cineControlsOpenByViewport[i] ? "Hide cine controls" : "Show cine controls"}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
setCineControlsOpenByViewport((prev) => {
|
||||||
|
const next = [...prev];
|
||||||
|
const nextOpen = !next[i];
|
||||||
|
next[i] = nextOpen;
|
||||||
|
if (!nextOpen) {
|
||||||
|
setCinePlayingByViewport((playing) => {
|
||||||
|
const p = [...playing];
|
||||||
|
p[i] = false;
|
||||||
|
return p;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<span aria-hidden="true">▶</span>
|
||||||
|
</button>
|
||||||
{viewportModes[i] === "stack" && annotationNavEnabled && (() => {
|
{viewportModes[i] === "stack" && annotationNavEnabled && (() => {
|
||||||
// Get all annotations for this stack
|
// Get all annotations for this stack
|
||||||
const imageIds = viewportImageIds[i];
|
const imageIds = viewportImageIds[i];
|
||||||
@@ -6003,38 +6067,6 @@ export default function App({ container_id, imageStacks, autoCacheStack, annotat
|
|||||||
gap: 6,
|
gap: 6,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
background: cineControlsOpenByViewport[i] ? "rgba(30,120,200,0.95)" : "rgba(0,0,0,0.7)",
|
|
||||||
color: "#fff",
|
|
||||||
border: "1px solid rgba(255,255,255,0.2)",
|
|
||||||
borderRadius: "4px",
|
|
||||||
fontSize: "12px",
|
|
||||||
fontWeight: 700,
|
|
||||||
padding: "6px 9px",
|
|
||||||
cursor: "pointer",
|
|
||||||
minHeight: 30,
|
|
||||||
}}
|
|
||||||
title={cineControlsOpenByViewport[i] ? "Hide cine controls" : "Show cine controls"}
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
setCineControlsOpenByViewport((prev) => {
|
|
||||||
const next = [...prev];
|
|
||||||
const nextOpen = !next[i];
|
|
||||||
next[i] = nextOpen;
|
|
||||||
if (!nextOpen) {
|
|
||||||
setCinePlayingByViewport((playing) => {
|
|
||||||
const p = [...playing];
|
|
||||||
p[i] = false;
|
|
||||||
return p;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return next;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Cine
|
|
||||||
</button>
|
|
||||||
<div
|
<div
|
||||||
className="preset-menu"
|
className="preset-menu"
|
||||||
style={{
|
style={{
|
||||||
@@ -6716,7 +6748,7 @@ export default function App({ container_id, imageStacks, autoCacheStack, annotat
|
|||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
}}>
|
}}>
|
||||||
{/* Loading overlay */}
|
{/* Loading overlay */}
|
||||||
{loadingState && (
|
{loadingState && loadingState !== "displayset" && (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
position: "absolute",
|
position: "absolute",
|
||||||
@@ -6737,9 +6769,7 @@ export default function App({ container_id, imageStacks, autoCacheStack, annotat
|
|||||||
>
|
>
|
||||||
{loadingState === "annotations"
|
{loadingState === "annotations"
|
||||||
? "Loading Annotations..."
|
? "Loading Annotations..."
|
||||||
: loadingState === "displayset"
|
: "Loading Viewer State..."}
|
||||||
? "Loading Display Set..."
|
|
||||||
: "Loading Viewer State..."}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user