feat(studio): ����� ��������� (marquee) + hover-��������� #45

Merged
min merged 2 commits from feat/studio-marquee-hover-2026-06-15 into main 2026-06-15 17:37:35 +00:00
2 changed files with 15 additions and 5 deletions
Showing only changes of commit 2e1d915922 - Show all commits

View File

@ -4,6 +4,7 @@ import { jwtDecode } from 'jwt-decode';
import { useAuth, redirectToLogin } from '../auth/AuthContext.jsx';
import { useSanctions } from '../auth/SanctionsContext.jsx';
import { BabylonScene } from './engine/BabylonScene';
import { MIXAMO_SKINS } from './engine/PlayerController';
import { StudioCollab } from './engine/StudioCollab';
import { CollabOverlay } from './engine/CollabOverlay';
import { BLOCK_TYPES, BLOCK_CATEGORIES, blockPreview, registerCustomBlockType } from './engine/BlockTypes';
@ -938,7 +939,7 @@ const KubikonEditor = () => {
// === Game settings inline в TopRibbon (вкладка Тест) ===
// Дефолт R15-скин bacon-hair (классический Roblox-вид).
const [playerModelType, setPlayerModelTypeUI] = useState('skin_bacon-hair');
const [playerModelType, setPlayerModelTypeUI] = useState('skin_y-bot');
const [envPreset, setEnvPresetUI] = useState('day');
const [dayDurationMin, setDayDurationMinUI] = useState(5);
const [nightDurationMin, setNightDurationMinUI] = useState(3);
@ -964,7 +965,7 @@ const KubikonEditor = () => {
genre: 'other',
thumbnail: '',
is_public: false,
player_model_type: 'skin_bacon-hair',
player_model_type: 'skin_y-bot',
});
const projectNameRef = useRef(projectName);
useEffect(() => { projectNameRef.current = projectName; metaRef.current.title = projectName; }, [projectName]);
@ -1782,7 +1783,7 @@ const KubikonEditor = () => {
sceneRef.current.history?.initialize();
// Синхронизируем UI-state TopRibbon из загруженной сцены
try {
setPlayerModelTypeUI(sceneRef.current.getPlayerModelType?.() || 'skin_bacon-hair');
setPlayerModelTypeUI(sceneRef.current.getPlayerModelType?.() || 'skin_y-bot');
const env = sceneRef.current.getEnvironmentState?.();
if (env?.preset) setEnvPresetUI(env.preset);
if (env?.dayDurationMin) setDayDurationMinUI(env.dayDurationMin);
@ -2093,7 +2094,16 @@ const KubikonEditor = () => {
const uid = getCurrentUserId();
if (uid) {
const r = await Kubikon3DApi.getEquippedSkin(uid);
const sf = r?.data?.skin_folder;
let sf = r?.data?.skin_folder;
// ВАЛИДАЦИЯ: legacy R15-скины (bacon-hair и пр.) больше
// не существуют. Если БД отдала невалидный подменяем
// на skin_y-bot (как в плеере и кабинете).
if (sf && typeof sf === 'string'
&& !MIXAMO_SKINS.has(sf)
&& !sf.startsWith('customskin:')) {
console.log('[KubikonEditor] skin', sf, 'не валиден → skin_y-bot');
sf = 'skin_y-bot';
}
if (sf && typeof sf === 'string') {
// Подмешиваем в hash так чтобы не сломать ticket=...
const cur = window.location.hash || '';

View File

@ -32,7 +32,7 @@ import { MixamoAnimator, loadMixamoAnimations } from './MixamoAnimator';
// Список всех Mixamo-скинов. Должен совпадать со списком в плеере и
// каталоге сайта (rublox-site/src/data/skinsCatalog.js).
const MIXAMO_SKINS = new Set([
export const MIXAMO_SKINS = new Set([
'skin_aj', 'skin_akai', 'skin_arissa', 'skin_big-vegas',
'skin_castle-guard-1', 'skin_castle-guard-2',
'skin_ch01', 'skin_ch02', 'skin_ch03', 'skin_ch04', 'skin_ch07', 'skin_ch08',