mirror of
https://github.com/webadderallorg/Recordly.git
synced 2026-09-26 15:55:35 +00:00
fix both problems from copilot
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user