// LoadingScreen — брендовый сплеш плеера.
// Скопирован 1-в-1 с Android LoadingView.kt:
// - синий gradient brandTop #2841C8 → brandBottom #4B6EF0
// - лого A02 130px по центру
// - "Рублокс" 56sp белый под лого
// - 8-точечный spinner с активной точкой
// - подпись (text + анимированные точки)
// - декоративные пузыри с "дышащим" alpha
//
// CSS-анимации, без JS-фрейма каждый кадр.
import React, { useState } from 'react';
const TITLE = 'Рублокс';
/**
* Dev-only панель вставки JWT. Показывается на экране «Нужен JWT» (только
* localhost). Кнопка → инпут → сохраняет в localStorage['player_jwt'] и
* перезагружает страницу. На проде этот экран не наступает (там redirect).
*/
function DevJwtPanel() {
const [open, setOpen] = useState(false);
const [val, setVal] = useState('');
const apply = () => {
const t = (val || '').trim();
if (!t) return;
try {
localStorage.setItem('player_jwt', t);
// совместимость с другими местами чтения токена
localStorage.setItem('Authorization', t);
} catch (e) { /* ignore */ }
window.location.reload();
};
if (!open) {
return (
);
}
return (
);
}
export default function LoadingScreen({ text = 'Подключение', subText = null, devJwt = false }) {
return (
{/* Декоративные пузыри — те же позиции что в Android LoadingView */}
{bubbles.map((b, i) => (
))}
{TITLE}
{/* 8-точечный spinner */}
{Array.from({ length: 8 }).map((_, i) => (
))}
{text}…
{subText &&
{subText}
}
{/* Dev-only: вставка JWT прямо с экрана (вместо ручного localStorage). */}
{devJwt &&
}
);
}
const bubbles = [
{ x: 0.05, y: 0.93, size: 48, phase: 0.0 },
{ x: 0.12, y: 0.88, size: 28, phase: 1.2 },
{ x: 0.20, y: 0.95, size: 20, phase: 2.4 },
{ x: 0.85, y: 0.85, size: 36, phase: 0.7 },
{ x: 0.92, y: 0.92, size: 44, phase: 1.9 },
{ x: 0.50, y: 0.97, size: 16, phase: 3.1 },
];
const splashCss = `
.rb-splash {
position: fixed; inset: 0;
display: flex; flex-direction: column; align-items: center; justify-content: center;
background: linear-gradient(160deg, #2841C8 0%, #4B6EF0 100%);
color: #fff;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
overflow: hidden;
}
.rb-logo {
filter: drop-shadow(0 6px 14px rgba(0,0,0,0.35));
margin-bottom: 28px;
}
.rb-title {
font-size: 56px;
font-weight: 700;
letter-spacing: 1px;
margin-bottom: 40px;
text-shadow: 0 2px 8px rgba(0,0,0,0.25);
}
.rb-spinner {
position: relative;
width: 64px; height: 64px;
margin-bottom: 16px;
}
.rb-dot {
position: absolute;
top: 50%; left: 50%;
width: 6px; height: 6px; border-radius: 50%;
background: rgba(255,255,255,0.45);
transform:
translate(-50%, -50%)
rotate(calc(var(--i) * 45deg))
translateY(-22px);
animation: rbDotPulse 1s linear infinite;
animation-delay: calc(var(--i) * 0.125s);
}
@keyframes rbDotPulse {
0%, 70%, 100% { background: rgba(255,255,255,0.35); }
10% { background: rgba(255,255,255,1.0); }
}
.rb-status {
font-size: 16px; opacity: 0.85;
letter-spacing: 0.3px;
}
.rb-dots {
display: inline-block; width: 24px; text-align: left;
animation: rbDotsBlink 1.4s steps(4, end) infinite;
}
@keyframes rbDotsBlink {
0% { clip-path: inset(0 100% 0 0); }
100% { clip-path: inset(0 0 0 0); }
}
.rb-substatus {
margin-top: 14px;
font-size: 13px; opacity: 0.65;
max-width: 360px; padding: 0 20px;
text-align: center; line-height: 1.45;
}
.rb-bubble {
position: absolute;
border-radius: 50%;
background: rgba(255,255,255,0.16);
animation: rbBubble 3.5s ease-in-out infinite;
transform: translate(-50%, -50%);
pointer-events: none;
}
/* === Dev JWT panel === */
.rb-devbtn {
margin-top: 22px;
background: rgba(255,255,255,0.14);
border: 1px solid rgba(255,255,255,0.3);
color: #fff;
font-size: 13px; font-weight: 600;
padding: 8px 16px; border-radius: 10px;
cursor: pointer;
transition: background 0.15s;
}
.rb-devbtn:hover { background: rgba(255,255,255,0.24); }
.rb-devpanel {
margin-top: 20px;
width: 380px; max-width: calc(100vw - 40px);
display: flex; flex-direction: column; gap: 8px;
}
.rb-devinput {
width: 100%; height: 70px; resize: vertical;
background: rgba(0,0,0,0.28);
border: 1px solid rgba(255,255,255,0.3);
border-radius: 10px;
color: #fff; font-size: 12px;
font-family: ui-monospace, "SF Mono", Menlo, Consolas, monospace;
padding: 10px; box-sizing: border-box;
outline: none;
}
.rb-devinput:focus { border-color: rgba(255,255,255,0.6); }
.rb-devrow { display: flex; gap: 8px; }
.rb-devapply {
flex: 1;
background: #ffffff; color: #2841C8;
border: none; border-radius: 10px;
font-size: 14px; font-weight: 700;
padding: 9px 0; cursor: pointer;
}
.rb-devapply:disabled { opacity: 0.4; cursor: default; }
.rb-devcancel {
background: transparent; color: rgba(255,255,255,0.8);
border: 1px solid rgba(255,255,255,0.3); border-radius: 10px;
font-size: 13px; padding: 9px 16px; cursor: pointer;
}
.rb-devhint {
font-size: 11px; opacity: 0.6; text-align: center;
}
@keyframes rbBubble {
0%, 100% { opacity: 0.35; }
50% { opacity: 0.70; }
}
`;