fix(tokens): импорт неигровых токенов из zip и плавные пути на macOS

Полный импорт/открытие проекта подхватывает app-tokens. Движение по путям пишется в DOM без ре-рендера кадра, у пульта и презентации выключен background throttling.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Ivan Fontosh
2026-09-07 16:16:30 +08:00
parent 586166cacd
commit fdccc0deb5
16 changed files with 285 additions and 111 deletions
@@ -1,4 +1,4 @@
import React, { useRef, useState } from 'react';
import React, { useLayoutEffect, useRef, useState } from 'react';
import type {
NpcDisposition,
@@ -16,6 +16,8 @@ import { sceneGridTokenFitFactor } from '../../../shared/types/sceneGrid';
import { useAssetUrl } from '../useAssetImageUrl';
import { PlayerTokenView } from './PlayerTokenView';
import { tokenPathKey } from '../../../shared/types/tokenPathSession';
import { registerPathTokenNode, writeTokenPathTransform } from '../tokens/tokenPathLiveDom';
import { useLiveDragBroadcast, useLiveResizeBroadcast } from './useLiveDragBroadcast';
import {
TokenInitiativeDecor,
@@ -100,6 +102,8 @@ function NpcSprite({
onResize,
String(placement.id),
);
const elRef = useRef<HTMLDivElement>(null);
const pathKey = tokenPathKey('npcToken', String(placement.id));
const pos = localPos ?? { nx, ny };
const shownSizeN = localSize ?? sizeN;
const minDim = Math.min(viewport.w, viewport.h);
@@ -107,6 +111,17 @@ function NpcSprite({
const canDrag = editable && dragEnabled && onMove !== undefined;
const canResize = editable && dragEnabled && onResize !== undefined;
useLayoutEffect(() => {
registerPathTokenNode(pathKey, elRef.current, viewport, false);
return () => registerPathTokenNode(pathKey, null, viewport, false);
}, [pathKey, viewport]);
useLayoutEffect(() => {
const el = elRef.current;
if (!el || el.dataset.pathLive === '1') return;
writeTokenPathTransform(el, pos.nx, pos.ny, 0, viewport, false);
}, [pos.nx, pos.ny, viewport]);
const point = (e: React.PointerEvent, host?: HTMLElement | null) => {
const rect = (host ?? e.currentTarget.parentElement)?.getBoundingClientRect();
return {
@@ -133,6 +148,7 @@ function NpcSprite({
return (
<div
ref={elRef}
className={[
styles.token,
canDrag ? styles.editable : '',
@@ -143,8 +159,6 @@ function NpcSprite({
data-testid={`session-npc-token-${placement.id}`}
data-initiative-active={initiativeActive ? '1' : '0'}
style={{
left: viewport.x + pos.nx * viewport.w,
top: viewport.y + pos.ny * viewport.h,
width: sizePx,
height: sizePx,
pointerEvents: canDrag || canResize || onContextMenu ? 'auto' : undefined,