Restore Story Intelligence relationship lines
This commit is contained in:
parent
8e7f720141
commit
cea45d1278
@ -1177,9 +1177,9 @@ static void Phase21UEnforcesAliasAgeSemanticAndUiResetRules()
|
|||||||
Assert(adminDiagnostics.Contains("Reset my Story Intelligence data", StringComparison.Ordinal), "Admin diagnostics page must show the reset button.");
|
Assert(adminDiagnostics.Contains("Reset my Story Intelligence data", StringComparison.Ordinal), "Admin diagnostics page must show the reset button.");
|
||||||
Assert(developmentReset.Contains("PreservedIllustrationItems", StringComparison.Ordinal), "Admin reset result must report preserved generated images.");
|
Assert(developmentReset.Contains("PreservedIllustrationItems", StringComparison.Ordinal), "Admin reset result must report preserved generated images.");
|
||||||
Assert(!developmentReset.Contains("DELETE FROM dbo.IllustrationLibraryItems", StringComparison.Ordinal), "Admin reset must preserve generated illustration library records.");
|
Assert(!developmentReset.Contains("DELETE FROM dbo.IllustrationLibraryItems", StringComparison.Ordinal), "Admin reset must preserve generated illustration library records.");
|
||||||
Assert(script.Contains("renderPresenceCallout", StringComparison.Ordinal), "Stage should show a presence callout for characters in the active location.");
|
Assert(!script.Contains("renderPresenceCallout", StringComparison.Ordinal), "Stage should not draw a bordered character container.");
|
||||||
Assert(script.Contains("drawConnection(id, cluster, locationPoint, \"presence-cluster\", 54, \"\"", StringComparison.Ordinal), "Presence connector should not show a tiny count label.");
|
Assert(script.Contains("drawConnection(id, cluster, locationPoint, \"presence-cluster\", 54, `${presentCharacters.length} here`", StringComparison.Ordinal), "Presence connector should show the location join label.");
|
||||||
Assert(css.Contains(".story-exp-presence-callout", StringComparison.Ordinal), "Presence callout styling is missing.");
|
Assert(!css.Contains(".story-exp-presence-callout", StringComparison.Ordinal), "Character container styling should be removed.");
|
||||||
Assert(css.Contains("white-space: normal", StringComparison.Ordinal), "Location captions should wrap rather than ellipsise.");
|
Assert(css.Contains("white-space: normal", StringComparison.Ordinal), "Location captions should wrap rather than ellipsise.");
|
||||||
Assert(!script.Contains("renderOverflowSummary", StringComparison.Ordinal), "Side panels must not use hidden '+N more' overflow controls.");
|
Assert(!script.Contains("renderOverflowSummary", StringComparison.Ordinal), "Side panels must not use hidden '+N more' overflow controls.");
|
||||||
Assert(css.Contains("-webkit-line-clamp: 3", StringComparison.Ordinal), "Insight body text should be clamped inside its card.");
|
Assert(css.Contains("-webkit-line-clamp: 3", StringComparison.Ordinal), "Insight body text should be clamped inside its card.");
|
||||||
@ -1214,7 +1214,8 @@ static void Phase21RSceneBrowserAndPanelsAreReplayFriendly()
|
|||||||
Assert(script.Contains("Assets are recorded in insights/diagnostics but not rendered as stage nodes.", StringComparison.Ordinal), "Asset data should remain available without drawing asset stage nodes.");
|
Assert(script.Contains("Assets are recorded in insights/diagnostics but not rendered as stage nodes.", StringComparison.Ordinal), "Asset data should remain available without drawing asset stage nodes.");
|
||||||
Assert(script.Contains("width * 0.82 - size / 2", StringComparison.Ordinal), "Location should be a larger right-side anchor once asset nodes are removed.");
|
Assert(script.Contains("width * 0.82 - size / 2", StringComparison.Ordinal), "Location should be a larger right-side anchor once asset nodes are removed.");
|
||||||
Assert(script.Contains("{ x: 0.68, y: 0.26, role: \"context\" }", StringComparison.Ordinal), "Character layout should use more of the stage width.");
|
Assert(script.Contains("{ x: 0.68, y: 0.26, role: \"context\" }", StringComparison.Ordinal), "Character layout should use more of the stage width.");
|
||||||
Assert(script.Contains("presence-cluster", StringComparison.Ordinal), "Presence should be shown as a single location callout instead of many confusing location lines.");
|
Assert(script.Contains("scene.relationships", StringComparison.Ordinal), "Relationship lines should be rendered on the stage.");
|
||||||
|
Assert(script.Contains("presence-cluster", StringComparison.Ordinal), "Presence should still be shown as a location join.");
|
||||||
Assert(css.Contains(".story-exp-zone--location .story-exp-zone-label {\n left: 80%;", StringComparison.Ordinal), "Location lane label should follow the compact right-side anchor.");
|
Assert(css.Contains(".story-exp-zone--location .story-exp-zone-label {\n left: 80%;", StringComparison.Ordinal), "Location lane label should follow the compact right-side anchor.");
|
||||||
Assert(!css.Contains("grid-template-rows: minmax(218px, 1.35fr) minmax(185px, 1.08fr) auto", StringComparison.Ordinal), "Right rail must not use fixed-height panel tracks.");
|
Assert(!css.Contains("grid-template-rows: minmax(218px, 1.35fr) minmax(185px, 1.08fr) auto", StringComparison.Ordinal), "Right rail must not use fixed-height panel tracks.");
|
||||||
Assert(!css.Contains("grid-template-rows: auto auto minmax(170px, 1fr) minmax(96px, 0.56fr)", StringComparison.Ordinal), "Left rail must not use fixed-height panel tracks.");
|
Assert(!css.Contains("grid-template-rows: auto auto minmax(170px, 1fr) minmax(96px, 0.56fr)", StringComparison.Ordinal), "Left rail must not use fixed-height panel tracks.");
|
||||||
|
|||||||
@ -792,23 +792,6 @@ input:focus-visible {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.story-exp-presence-callout {
|
|
||||||
position: absolute;
|
|
||||||
left: var(--presence-left, 28px);
|
|
||||||
top: var(--presence-top, 58px);
|
|
||||||
z-index: 34;
|
|
||||||
width: var(--presence-width, 520px);
|
|
||||||
height: var(--presence-height, 320px);
|
|
||||||
border: 1px solid rgba(125, 193, 255, 0.22);
|
|
||||||
border-radius: 28px;
|
|
||||||
background:
|
|
||||||
radial-gradient(circle at 62% 45%, rgba(87, 149, 205, 0.14), transparent 58%),
|
|
||||||
linear-gradient(135deg, rgba(17, 41, 70, 0.22), rgba(4, 10, 20, 0.06));
|
|
||||||
box-shadow: inset 0 0 44px rgba(125, 193, 255, 0.08), 0 22px 80px rgba(0, 0, 0, 0.16);
|
|
||||||
pointer-events: none;
|
|
||||||
transition: left 850ms cubic-bezier(.16, .84, .28, 1), top 850ms cubic-bezier(.16, .84, .28, 1), width 850ms cubic-bezier(.16, .84, .28, 1), height 850ms cubic-bezier(.16, .84, .28, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.story-character {
|
.story-character {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: block;
|
display: block;
|
||||||
|
|||||||
@ -682,47 +682,38 @@
|
|||||||
const activeIds = new Set();
|
const activeIds = new Set();
|
||||||
const occupiedRects = layoutRects(stageRect);
|
const occupiedRects = layoutRects(stageRect);
|
||||||
|
|
||||||
|
scene.relationships
|
||||||
|
.filter((relationship) => relationship.weight >= 72)
|
||||||
|
.slice(0, 2)
|
||||||
|
.forEach((relationship, index) => {
|
||||||
|
const source = dom.visualStage.querySelector(`[data-character-id="${cssEscape(relationship.sourceId)}"]`);
|
||||||
|
const target = dom.visualStage.querySelector(`[data-character-id="${cssEscape(relationship.targetId)}"]`);
|
||||||
|
if (!source || !target) return;
|
||||||
|
|
||||||
|
const start = connectionPoint(source, stageRect, target);
|
||||||
|
const end = connectionPoint(target, stageRect, source);
|
||||||
|
const obstacles = connectionObstacles(stageRect, source, target);
|
||||||
|
const id = relationship.id || `relationship-${relationship.sourceId}-${relationship.targetId}`;
|
||||||
|
activeIds.add(id);
|
||||||
|
drawn.push(drawConnection(id, start, end, relationshipTone(relationship), relationship.weight, relationship.label || "", index, obstacles, occupiedRects));
|
||||||
|
});
|
||||||
|
|
||||||
const location = dom.visualStage.querySelector("[data-location-id]");
|
const location = dom.visualStage.querySelector("[data-location-id]");
|
||||||
const presentCharacters = scene.characters
|
const presentCharacters = scene.characters
|
||||||
.filter((character) => !character.status || !character.status.toLowerCase().includes("absent"))
|
.filter((character) => !character.status || !character.status.toLowerCase().includes("absent"))
|
||||||
.map((character) => dom.visualStage.querySelector(`[data-character-id="${cssEscape(character.id)}"]`))
|
.map((character) => dom.visualStage.querySelector(`[data-character-id="${cssEscape(character.id)}"]`))
|
||||||
.filter(Boolean);
|
.filter(Boolean);
|
||||||
const cluster = characterClusterPoint(presentCharacters, stageRect);
|
const cluster = characterClusterPoint(presentCharacters, stageRect);
|
||||||
renderPresenceCallout(presentCharacters, location, stageRect);
|
|
||||||
if (cluster && location) {
|
if (cluster && location) {
|
||||||
const id = `presence-cluster-${location.dataset.locationId}`;
|
const id = `presence-cluster-${location.dataset.locationId}`;
|
||||||
activeIds.add(id);
|
activeIds.add(id);
|
||||||
const locationPoint = connectionPoint(location, stageRect, { getBoundingClientRect: () => ({ left: stageRect.left + cluster.x, top: stageRect.top + cluster.y, width: 0, height: 0 }) });
|
const locationPoint = connectionPoint(location, stageRect, { getBoundingClientRect: () => ({ left: stageRect.left + cluster.x, top: stageRect.top + cluster.y, width: 0, height: 0 }) });
|
||||||
drawn.push(drawConnection(id, cluster, locationPoint, "presence-cluster", 54, "", drawn.length, [], occupiedRects));
|
drawn.push(drawConnection(id, cluster, locationPoint, "presence-cluster", 54, `${presentCharacters.length} here`, drawn.length, [], occupiedRects));
|
||||||
}
|
}
|
||||||
|
|
||||||
removeInactiveSvgConnections(activeIds);
|
removeInactiveSvgConnections(activeIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderPresenceCallout(characterNodes, locationNode, stageRect) {
|
|
||||||
let callout = dom.visualStage.querySelector("[data-presence-callout]");
|
|
||||||
if (!characterNodes.length || !locationNode) {
|
|
||||||
callout?.remove();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!callout) {
|
|
||||||
callout = document.createElement("div");
|
|
||||||
callout.className = "story-exp-presence-callout";
|
|
||||||
callout.dataset.presenceCallout = "true";
|
|
||||||
dom.visualStage.append(callout);
|
|
||||||
}
|
|
||||||
|
|
||||||
const left = Math.max(14, stageRect.width * 0.018);
|
|
||||||
const top = Math.max(38, stageRect.height * 0.062);
|
|
||||||
const right = Math.min(stageRect.width * 0.71, stageRect.width - 330);
|
|
||||||
const bottom = Math.min(stageRect.height - 62, stageRect.height * 0.78);
|
|
||||||
callout.style.setProperty("--presence-left", `${Math.round(left)}px`);
|
|
||||||
callout.style.setProperty("--presence-top", `${Math.round(top)}px`);
|
|
||||||
callout.style.setProperty("--presence-width", `${Math.round(Math.max(520, right - left))}px`);
|
|
||||||
callout.style.setProperty("--presence-height", `${Math.round(Math.max(300, bottom - top))}px`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawConnection(id, start, end, tone, weight, label, index, obstacles, occupiedRects) {
|
function drawConnection(id, start, end, tone, weight, label, index, obstacles, occupiedRects) {
|
||||||
let group = dom.connections.querySelector(`[data-connection-id="${cssEscape(id)}"]`);
|
let group = dom.connections.querySelector(`[data-connection-id="${cssEscape(id)}"]`);
|
||||||
const isNew = !group;
|
const isNew = !group;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user