mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-12 04:42:16 +00:00
frontend: Sonar follow-ups (S8786, S6852, S7059) (#2824)
Two issues SonarCloud raised on main after #2821/#2822 merged: - **typescript:S8786** `SceneState.ts` `base64ToFile`: #2821's `/:([^;]*);/` is still flagged. The mime type is now read with `indexOf`: the text between the first `:` and the `;` after it, else `image/png`. Checked equal to the regex on `data:image/png;base64`, `data:;base64`, a header with no `:` or `;`, and several `:`. - **typescript:S6852** `MentionTextarea`: the `role="textbox"` editor gets `tabIndex={disabled ? -1 : 0}`. A `contentEditable` element was focusable already, so nothing changes for users. Typechecked locally against main (no new errors). <!-- This is an auto-generated comment: release notes by coderabbit.ai --> <!-- coderabbit-ai-generated:v1 --> ## Summary by CodeRabbit * **Bug Fixes** * Improved image import handling so MIME types are identified more reliably, with PNG used as a fallback when the type cannot be determined. * Disabled text editors are no longer reachable through sequential keyboard navigation; enabled editors remain tabbable. * Physics support is initialized during editor setup after the required canvas and container elements are available. <!-- end of auto-generated comment: release notes by coderabbit.ai --> - **typescript:S7059** `editor.ts`: `ensureAmmoLoaded()` (an async load) moves out of the `Editor` constructor to `EngineProvider`, the only place an `Editor` is built, right before `new Editor(...)`. The loader is a singleton, so the script is still appended once.
This commit is contained in:
1 parent
7c8419fabd
commit
55e6e5cabb
4 files changed
+9
-7
No files matched your search
@@ -1129,7 +1129,10 @@ export const useSceneStore = create<SceneState>((set, get, store) => ({
|
||||
|
||||
const base64ToFile = (base64: string, filename: string): File => {
|
||||
const arr = base64.split(",");
|
||||
const mime = arr[0].match(/:([^;]*);/)?.[1] || "image/png";
|
||||
// data:<mime>;base64: the text between the first ":" and the ";" after it.
|
||||
const start = arr[0].indexOf(":") + 1;
|
||||
const end = arr[0].indexOf(";", start);
|
||||
const mime = (start > 0 && end !== -1 && arr[0].slice(start, end)) || "image/png";
|
||||
const bstr = atob(arr[1]);
|
||||
let n = bstr.length;
|
||||
const u8arr = new Uint8Array(n);
|
||||
|
||||
@@ -2,6 +2,7 @@ import { ReactNode, useEffect, useRef, useState } from "react";
|
||||
import { EngineContext, setActiveEditor } from "./EngineContext";
|
||||
|
||||
import Editor from "../../engine/editor";
|
||||
import { ensureAmmoLoaded } from "../../engine/ammoLoader";
|
||||
import type { PageSceneAdapter } from "../../adapter";
|
||||
import { getSceneGenerationMetaData } from "../../sceneMetadata";
|
||||
import { usePageSceneStore } from "../../PageSceneStore";
|
||||
@@ -61,6 +62,9 @@ export const EngineProvider = ({
|
||||
// them to null on unmount).
|
||||
if (!sceneContainer || !editorCanvas || !camViewCanvas) return undefined;
|
||||
|
||||
// Ammo.js WASM is a global side-effect script the physics path depends on; the singleton
|
||||
// appends it to document.body once, however often the Editor is constructed.
|
||||
void ensureAmmoLoaded();
|
||||
const newEditor = new Editor(adapterRef.current);
|
||||
newEditor.initialize({
|
||||
sceneToken: sceneToken || "",
|
||||
|
||||
@@ -31,7 +31,6 @@ import { ModalTransformController } from "./editor/ModalTransformController";
|
||||
import Stats from "three/examples/jsm/libs/stats.module.js";
|
||||
import { SparkRenderer } from "@sparkjsdev/spark";
|
||||
import { usePageSceneStore } from "../PageSceneStore";
|
||||
import { ensureAmmoLoaded } from "./ammoLoader";
|
||||
import { EngineEventBus } from "./events/EngineEventBus";
|
||||
import { EngineStoreBridge } from "./EngineStoreBridge";
|
||||
import {
|
||||
@@ -187,11 +186,6 @@ class Editor {
|
||||
this.adapter = adapter;
|
||||
this.can_initialize = true;
|
||||
this.stats = new Stats();
|
||||
// Ammo.js WASM is a global side-effect script the physics path
|
||||
// depends on. The singleton ensures it's appended to document.body
|
||||
// exactly once, even across Editor re-construction.
|
||||
void ensureAmmoLoaded();
|
||||
|
||||
// Version and name.
|
||||
this.version = 2.0;
|
||||
// Clock, scene and camera essentials.
|
||||
|
||||
@@ -1587,6 +1587,7 @@ export const MentionTextarea = forwardRef<HTMLDivElement, MentionTextareaProps>(
|
||||
role="textbox"
|
||||
aria-multiline="true"
|
||||
aria-label={placeholder || "Prompt"}
|
||||
tabIndex={disabled ? -1 : 0}
|
||||
ref={editorRef}
|
||||
contentEditable={!disabled}
|
||||
onInput={handleInput}
|
||||
|
||||
Reference in new issue
Block a user