fix both problems from copilot

This commit is contained in:
Alan Trebugeais
2026-05-09 12:08:27 +02:00
parent 7a6a2ac9ec
commit d7b4211b2c
2 changed files with 51 additions and 13 deletions
+32 -1
View File
@@ -85,6 +85,19 @@ function getRegisteredFramesSignature() {
.join("|");
}
function serializeExtensionSettingValue(value: unknown): string {
try {
const serialized = JSON.stringify(value);
return serialized ?? "undefined";
} catch {
try {
return String(value);
} catch {
return "[unserializable]";
}
}
}
function getExtensionSettingsSignature() {
return extensionHost
.getSettingsPanels()
@@ -92,7 +105,7 @@ function getExtensionSettingsSignature() {
const { extensionId, panel } = registeredPanel;
return panel.fields.map((field) => {
const value = extensionHost.getExtensionSetting(extensionId, field.id);
return `${extensionId}:${panel.id}:${field.id}:${JSON.stringify(value)}`;
return `${extensionId}:${panel.id}:${field.id}:${serializeExtensionSettingValue(value)}`;
});
})
.sort()
@@ -511,6 +524,7 @@ const VideoPlayback = forwardRef<VideoPlaybackRef, VideoPlaybackProps>(
const frameSpriteRef = useRef<Sprite | null>(null);
const frameContainerRef = useRef<Container | null>(null);
const frameIdRef = useRef<string | null>(frame);
const frameReloadKeyRef = useRef<string | null>(null);
const isPlayingRef = useRef(isPlaying);
const suspendRenderingRef = useRef(suspendRendering);
const isSeekingRef = useRef(false);
@@ -1042,6 +1056,18 @@ const VideoPlayback = forwardRef<VideoPlaybackRef, VideoPlaybackProps>(
useEffect(() => {
const frameContainer = frameContainerRef.current;
if (!frameContainer) return;
const nextFrameReloadKey = `${frame ?? ""}:${frameUpdateCounter}`;
const activeFrameData = frame
? extensionHost.getFrames().find((registeredFrame) => registeredFrame.id === frame)
: null;
const shouldRedrawDynamicFrame = Boolean(activeFrameData?.draw && frameSpriteRef.current);
// Layout-only changes should not force texture/sprite recreation.
if (frameReloadKeyRef.current === nextFrameReloadKey && !shouldRedrawDynamicFrame) {
layoutVideoContentRef.current?.();
return;
}
frameReloadKeyRef.current = nextFrameReloadKey;
// Clear existing frame sprite and its texture to free memory
if (frameSpriteRef.current) {
@@ -1116,6 +1142,11 @@ const VideoPlayback = forwardRef<VideoPlaybackRef, VideoPlaybackProps>(
};
}, [aspectRatio, borderRadius, cropRegion, frame, frameUpdateCounter, padding]);
// Always re-run geometric layout when layout props change, even if frame sprite isn't reloaded.
useEffect(() => {
layoutVideoContentRef.current?.();
}, [aspectRatio, borderRadius, cropRegion, padding]);
const selectedZoom = useMemo(() => {
if (!selectedZoomId) return null;
return zoomRegions.find((region) => region.id === selectedZoomId) ?? null;
+19 -12
View File
@@ -1,6 +1,7 @@
import * as PhosphorIcons from "@phosphor-icons/react";
type IconWeight = "thin" | "light" | "regular" | "bold" | "fill";
const missingIconPathCache = new Set<string>();
function resolveIconComponent(name: string): {
iconName: string;
@@ -49,6 +50,9 @@ export function resolveIconPath(
cache: Map<string, Path2D>,
): Path2D | null {
const cacheKey = `${name}:${weight}`;
if (missingIconPathCache.has(cacheKey)) {
return null;
}
const cached = cache.get(cacheKey);
if (cached) {
return cached;
@@ -57,6 +61,7 @@ export function resolveIconPath(
const resolved = resolveIconComponent(name);
if (!resolved) {
console.warn(`[extensions] Icon ${name} not found in Phosphor library`);
missingIconPathCache.add(cacheKey);
return null;
}
@@ -70,14 +75,15 @@ export function resolveIconPath(
const pathDataList: string[] = [];
collectPathData(children, pathDataList);
if (pathDataList.length === 0) {
console.warn(`[extensions] No path data found for ${name}:${weight}`, {
iconName: resolved.iconName,
element,
children,
});
return null;
}
if (pathDataList.length === 0) {
console.warn(`[extensions] No path data found for ${name}:${weight}`, {
iconName: resolved.iconName,
element,
children,
});
missingIconPathCache.add(cacheKey);
return null;
}
const combinedPath = new Path2D();
for (const pathData of pathDataList) {
@@ -85,8 +91,9 @@ export function resolveIconPath(
}
cache.set(cacheKey, combinedPath);
return combinedPath;
} catch (err) {
console.error(`[extensions] Failed to extract path for icon ${name}:`, err);
return null;
}
} catch (err) {
console.error(`[extensions] Failed to extract path for icon ${name}:`, err);
missingIconPathCache.add(cacheKey);
return null;
}
}