0.2.3 — built-in code editor, .uasset previews, new icon
- Built-in code editor: edit working-copy source files in place (Edit → textarea → Save) before committing, no external IDE needed. Backend write_depot opens the file for edit, clears read-only, writes UTF-8; confined to the client root. - .uasset previews: pull the embedded Unreal thumbnail (PNG) server-side for both working copy and history; on-demand real 3D via a headless Unreal FBX export (commandlet mode, no editor window), temp file deleted right after — nothing cached on disk. Plugin content paths mapped to their mount point. - New app icon (brand mark on a theme tile) + theme-aware in-app logo. - Connection pill / Settings show the actual connected server (P4PORT), not the server's internal self-reported address. - Fix: the "select all" checkbox no longer renders as a giant empty square when not everything is selected (size pinned). - IDE picker chooses which installed editor opens code; AI replies in UI language. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -14,7 +14,7 @@ import { t } from "./i18n";
|
||||
|
||||
type Api = { toggleWire: (b: boolean) => void; toggleGrid: (b: boolean) => void; reset: () => void };
|
||||
|
||||
export default function ModelViewer({ depot, name, spec }: { depot: string; name: string; spec?: string }) {
|
||||
export default function ModelViewer({ depot, name, spec, bytes, forceExt }: { depot: string; name: string; spec?: string; bytes?: ArrayBuffer; forceExt?: string }) {
|
||||
const mount = useRef<HTMLDivElement>(null);
|
||||
const api = useRef<Api | null>(null);
|
||||
const [status, setStatus] = useState<"loading" | "ok" | "error">("loading");
|
||||
@ -69,7 +69,7 @@ export default function ModelViewer({ depot, name, spec }: { depot: string; name
|
||||
let gridHelper: THREE.GridHelper | null = null;
|
||||
let home = { pos: new THREE.Vector3(3, 2, 3), tgt: new THREE.Vector3() };
|
||||
|
||||
const ext = (name.toLowerCase().split(".").pop() || "");
|
||||
const ext = (forceExt || name.toLowerCase().split(".").pop() || "");
|
||||
|
||||
function collectStats(obj: THREE.Object3D) {
|
||||
let tris = 0, verts = 0, meshes = 0; const mats = new Set<THREE.Material>();
|
||||
@ -138,7 +138,8 @@ export default function ModelViewer({ depot, name, spec }: { depot: string; name
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
const buf = spec ? await p4.printDepot(spec) : await p4.readDepot(depot);
|
||||
// pre-supplied bytes (e.g. an FBX exported from Unreal) skip the p4 fetch
|
||||
const buf = bytes ? bytes : spec ? await p4.printDepot(spec) : await p4.readDepot(depot);
|
||||
if (disposed) return;
|
||||
const manager = new THREE.LoadingManager();
|
||||
if (ext === "glb" || ext === "gltf") new GLTFLoader(manager).parse(buf, "", (g) => !disposed && place(g.scene), fail);
|
||||
@ -173,7 +174,7 @@ export default function ModelViewer({ depot, name, spec }: { depot: string; name
|
||||
api.current = null;
|
||||
};
|
||||
// eslint-disable-next-line
|
||||
}, [depot, name, spec]);
|
||||
}, [depot, name, spec, bytes, forceExt]);
|
||||
|
||||
const fmt = (n: number) => n.toLocaleString("ru");
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user