// screens-onboarding.jsx — first-run onboarding + contextual help const { useState: _ob_useState, useEffect: _ob_useEffect, useMemo: _ob_useMemo } = React; // ============================================================ // First-run onboarding overlay // ============================================================ function Onboarding({ open, lang, onClose, onComplete, navigate }){ const [step, setStep] = _ob_useState(0); _ob_useEffect(() => { if (open) setStep(0); }, [open]); const steps = [ { kind: 'welcome', title: lang === 'ru' ? 'Добро пожаловать\nв Ravana Swap' : 'Welcome to\nRavana Swap', sub: lang === 'ru' ? 'Меняй лица на фото и видео, генерируй картинки и собирай награды каждый день.' : 'Swap faces in photos and videos, generate images, and collect rewards every day.', cta: lang === 'ru' ? 'Поехали' : 'Let’s go', }, { kind: 'faceswap', title: lang === 'ru' ? 'Face Swap\nза три шага' : 'Face Swap\nin three steps', sub: lang === 'ru' ? 'Загрузи свое лицо, выбери цель (фото или видео) и получи результат.' : 'Upload your source face, pick a target photo or video, and get the result.', cta: lang === 'ru' ? 'Дальше' : 'Next', }, { kind: 'premium', title: lang === 'ru' ? 'MultiFace и Image Gen' : 'MultiFace & Image Gen', sub: lang === 'ru' ? 'Меняй сразу несколько лиц в сцене или создавай новые изображения по промпту. Доступно с любым пакетом.' : 'Swap multiple faces at once, or generate fresh images from a prompt. Unlocked by any package.', cta: lang === 'ru' ? 'Дальше' : 'Next', }, { kind: 'fortune', title: lang === 'ru' ? 'Колесо Фортуны\nкаждый день' : 'Spin Fortune\nevery day', sub: lang === 'ru' ? 'Получай ежедневный спин и зарабатывай дополнительные через рефералов, серии и покупки.' : 'Daily spin is free. Earn extra spins via referrals, streaks, and purchases.', cta: lang === 'ru' ? 'Дальше' : 'Next', }, { kind: 'invite', title: lang === 'ru' ? 'Приглашай —\nполучай Premium' : 'Invite friends —\nunlock Premium', sub: lang === 'ru' ? 'Делись ссылкой: за каждого друга +1 фото и +1 видео-кредит. Сильные рефереры открывают Referral Premium.' : 'Each friend earns you +1 photo and +1 video credit. Top referrers unlock Referral Premium.', cta: lang === 'ru' ? 'Дальше' : 'Next', }, { kind: 'cta', title: lang === 'ru' ? 'Сделай свой\nпервый swap' : 'Make your\nfirst swap', sub: lang === 'ru' ? 'Старт — 5 бесплатных фото-кредитов. Этого хватит на 5 face-swaps.' : 'You get 5 free photo credits to start — enough for 5 face swaps.', cta: lang === 'ru' ? 'Начать создание' : 'Start creating', done: true, }, ]; if (!open) return null; const s = steps[step]; const total = steps.length; const next = () => { if (step >= total - 1) { onComplete && onComplete(); if (s.done && navigate) navigate('faceswap'); } else { setStep(step + 1); } }; const skip = () => onComplete && onComplete(); return (
{/* Top bar — progress + skip */}
{steps.map((_, i) => (
))}
{step < total - 1 && ( )}
{s.title}
{s.sub}
{step + 1} / {total}
); } function OnboardVisual({ kind }){ if (kind === 'welcome') { return (
); } if (kind === 'faceswap') { return (
); } if (kind === 'premium') { return (
MultiFace
Image Gen
); } if (kind === 'fortune') { return (
); } if (kind === 'invite') { return (
+1 / +1
); } if (kind === 'cta') { return (
Ready
); } return null; } window.Onboarding = Onboarding; // ============================================================ // Contextual help sheet // ============================================================ function HelpSheet({ open, onClose, content, lang }){ if (!open || !content) return null; return (
{content.title}
{lang === 'ru' ? 'Подсказки и советы' : 'Tips & tricks'}
{content.tips.map((tip, i) => (
{i + 1}
{typeof tip === 'string' ?
{tip}
: <>
{tip.t}
{tip.d}
}
))}
{content.warning && (
{content.warning}
)}
); } window.HelpSheet = HelpSheet; // ============================================================ // Help content per-screen // ============================================================ const HELP_CONTENT = { en: { home: { title: 'Your dashboard', tips: [ { t: 'Balances', d: 'Photo credits power face swaps on images and Image Gen. Video credits are consumed per minute of the target video.' }, { t: 'Three creators', d: 'Face Swap, MultiFace and Image Gen are the three modes. MultiFace stays premium; Image Gen uses photo credits.' }, { t: 'Active jobs', d: 'Long renders keep going while you browse. Tap a job to jump back to it.' }, { t: 'Daily Fortune', d: 'Spin once a day for free. Extra spins come from invites, streaks and purchases.' }, ], }, faceswap: { title: 'Face Swap tips', tips: [ { t: 'Good source faces', d: 'Front-facing, well-lit, no sunglasses or face masks. 512×512 or larger works best.' }, { t: 'Photo or video targets', d: 'Photos use photo credits. Videos use video minutes — minimum charge per video is 1 minute.' }, { t: 'High clarity mode', d: 'Costs 2× credits, sharper result. Use it for portraits and close-ups.' }, { t: 'Long video / large file', d: 'Videos longer than 60 seconds and files above Telegram limits require any paid package.' }, ], warning: 'Source files are processed temporarily and never shared. Don\'t use the bot to deceive or harass others.', }, multiface: { title: 'MultiFace mapping', tips: [ { t: 'How detection works', d: 'We scan every frame of your media and group similar faces together — that\'s why detection takes a few seconds.' }, { t: 'Assign per face', d: 'Each detected face needs a source. Skip any face you don\'t want changed.' }, { t: 'Pricing', d: 'You pay only for swapped faces. Minimum charge for a MultiFace video is 3 video credits.' }, { t: 'Premium feature', d: 'MultiFace is unlocked by any paid package — once unlocked, it stays unlocked.' }, ], }, imagegen: { title: 'Image Gen prompts', tips: [ { t: 'Be specific', d: 'Style, mood, camera, lighting, and subject all change the output. "Cinematic portrait, 35mm, neon rain" beats "cool photo".' }, { t: 'Aspect ratio matters', d: '1:1 is good for portraits, 16:9 for landscapes, 9:16 for stories.' }, { t: 'Cost', d: '1 photo credit per generation. Regenerate uses the same prompt.' }, ], warning: 'NSFW, real people without consent, and other policy-violating prompts are rejected automatically.', }, fortune: { title: 'Fortune mechanics', tips: [ { t: 'Daily spin', d: 'Free spin resets every 24 hours. Don\'t skip days — streaks unlock bonus spins.' }, { t: 'Earn extra spins', d: '+1 per friend joining via your link, +3 per package, +5 when a friend goes premium.' }, { t: 'Lucky points', d: 'Stack them via spins, then exchange — 100 → 20 photos, 300 → 1 spin, 500 → 1 video.' }, { t: 'Jackpot', d: 'Rare sector. Drops 100 photos + 5 videos + 500 lucky points in one go.' }, ], }, credits: { title: 'Buying credits', tips: [ { t: 'Telegram Stars', d: 'Primary method. Pay in-app, no card needed. New Stripe subscriptions are disabled.' }, { t: 'Packages', d: 'Hot Combo gives the best photo+video balance. Ultra is for heavy video creators.' }, { t: 'Bonus spins', d: 'Every successful purchase grants +3 Fortune spins on top of the credits.' }, { t: 'No subscription required', d: 'All packages are one-time top-ups. Auto-renew is only on legacy subscriptions.' }, ], }, referrals: { title: 'How referrals work', tips: [ { t: 'Per-join reward', d: '+1 video minute and +1 photo credit each time a friend opens the bot via your link.' }, { t: 'Per-paid reward', d: '+5 video and +5 photo when a referred friend buys any package.' }, { t: 'Referral Premium', d: 'Bring 10+ paying friends and unlock Referral Premium — full access without buying yourself.' }, { t: 'Monthly challenge', d: 'Top 200 referrers split a prize pool of 1500+ video minutes plus Premium days.' }, ], }, history: { title: 'Your projects', tips: [ { t: 'Retention', d: 'Photos stay 30 days, videos stay 7 days. Download or send to Telegram to keep them longer.' }, { t: 'Filters', d: 'Switch between Face Swap, MultiFace, Image Gen, photos or videos. Search is coming.' }, { t: 'Failed jobs', d: 'Failed projects don\'t cost credits. Tap retry to re-run with the same inputs.' }, { t: 'Create similar', d: 'Re-use a project\'s source or prompt as a starting point for a new render.' }, ], }, create: { title: 'Choosing a mode', tips: [ { t: 'Face Swap', d: 'One source face, one target. Photo or video. Best entry point.' }, { t: 'MultiFace', d: 'When the target has multiple people and you want different swaps per face.' }, { t: 'Image Gen', d: 'When you have no target media — just a description.' }, { t: 'Quick start', d: 'Re-use your last source or prompt to skip the upload step entirely.' }, ], }, }, ru: { home: { title: 'Главный экран', tips: [ { t: 'Балансы', d: 'Фото-кредиты тратятся на swap фото и Image Gen. Видео-минуты — по длительности целевого видео.' }, { t: 'Три режима', d: 'Face Swap, MultiFace и Image Gen. MultiFace и Image Gen открываются любым платным пакетом.' }, { t: 'Активные задачи', d: 'Долгие рендеры продолжаются пока ты ходишь по другим экранам. Тапни на задачу — откроется её прогресс.' }, { t: 'Ежедневная Фортуна', d: 'Один бесплатный спин в сутки. Дополнительные — за приглашения, серии и покупки.' }, ], }, faceswap: { title: 'Face Swap — советы', tips: [ { t: 'Хорошее лицо-источник', d: 'Анфас, ровный свет, без очков и маски. Лучше всего 512×512 и больше.' }, { t: 'Цели — фото или видео', d: 'Фото тратит фото-кредиты. Видео — минуты, минимальное списание 1 минута.' }, { t: 'High clarity', d: '×2 кредитов, но результат заметно чётче. Хорошо для портретов крупным планом.' }, { t: 'Длинное видео', d: 'Видео длиннее 60с и файлы выше лимита Telegram доступны после любого платного пакета.' }, ], warning: 'Файлы обрабатываются временно и не публикуются. Не используй бота для обмана и преследования.', }, multiface: { title: 'MultiFace mapping', tips: [ { t: 'Как работает детект', d: 'Мы сканируем все кадры и группируем похожие лица — поэтому первый шаг занимает несколько секунд.' }, { t: 'Назначение источников', d: 'Каждому найденному лицу — свой источник. Лица, которые менять не нужно, можно пропустить.' }, { t: 'Стоимость', d: 'Платишь только за заменённые лица. Минимум за MultiFace video — 3 видео-кредита.' }, { t: 'Premium-функция', d: 'MultiFace открывается любым пакетом и остаётся доступной навсегда.' }, ], }, imagegen: { title: 'Image Gen — промпты', tips: [ { t: 'Будь конкретным', d: 'Стиль, настроение, камера, свет — всё меняет результат. «Кинематографичный портрет, 35мм, неоновый дождь» лучше, чем «крутое фото».' }, { t: 'Соотношение сторон', d: '1:1 — портреты, 16:9 — пейзажи, 9:16 — сторис.' }, { t: 'Стоимость', d: '1 фото-кредит за генерацию. Regenerate использует тот же промпт.' }, ], warning: 'NSFW, реальные люди без согласия и другие запрещённые промпты отклоняются автоматически.', }, fortune: { title: 'Как работает Фортуна', tips: [ { t: 'Ежедневный спин', d: 'Сбрасывается каждые 24 часа. Не пропускай дни — серии открывают бонусные спины.' }, { t: 'Дополнительные спины', d: '+1 за каждого друга, +3 за пакет, +5 когда друг купил premium.' }, { t: 'Lucky points', d: 'Копи их через спины и обменивай — 100 → 20 фото, 300 → 1 спин, 500 → 1 видео.' }, { t: 'Джекпот', d: 'Редкий сектор. 100 фото + 5 видео + 500 поинтов одним выстрелом.' }, ], }, credits: { title: 'Покупка кредитов', tips: [ { t: 'Telegram Stars', d: 'Основной способ. Платёж прямо в Telegram, карта не нужна. Stripe-подписки отключены.' }, { t: 'Пакеты', d: 'Hot Combo — лучший баланс фото+видео. Ultra — для тяжёлых видео-креаторов.' }, { t: 'Бонусные спины', d: 'Каждая успешная покупка добавляет +3 спина Фортуны сверху.' }, { t: 'Без подписки', d: 'Все пакеты — разовые. Автопродление — только на старых подписках.' }, ], }, referrals: { title: 'Как работают рефералы', tips: [ { t: 'За подключение', d: '+1 видео-минута и +1 фото-кредит каждый раз когда друг заходит по твоей ссылке.' }, { t: 'За оплату друга', d: '+5 видео и +5 фото когда приглашённый покупает любой пакет.' }, { t: 'Referral Premium', d: 'Приведи 10+ платящих друзей и открой Referral Premium — полный доступ без покупки.' }, { t: 'Ежемесячный челлендж', d: 'Топ-200 рефереров делят 1500+ видео-минут и Premium-дни.' }, ], }, history: { title: 'Твои проекты', tips: [ { t: 'Хранение', d: 'Фото — 30 дней, видео — 7 дней. Скачай или отправь в Telegram, чтобы сохранить надолго.' }, { t: 'Фильтры', d: 'Переключай Face Swap, MultiFace, Image Gen, фото или видео.' }, { t: 'Неудачные задачи', d: 'Failed-проекты не списывают кредиты. Жми retry чтобы запустить заново.' }, { t: 'Создать похожее', d: 'Можно использовать источник или промпт прошлого проекта как старт для нового.' }, ], }, create: { title: 'Какой режим выбрать', tips: [ { t: 'Face Swap', d: 'Одно лицо, одна цель. Фото или видео. Точка входа для всех.' }, { t: 'MultiFace', d: 'Когда в кадре несколько людей и хочешь поменять разные лица на разные.' }, { t: 'Image Gen', d: 'Когда нет исходных файлов — только описание.' }, { t: 'Быстрый старт', d: 'Используй прошлый источник или промпт, чтобы пропустить шаг загрузки.' }, ], }, }, }; window.HELP_CONTENT = HELP_CONTENT; // ============================================================ // Help icon button — drop-in for screen headers // ============================================================ function HelpButton({ topic, lang }){ const [open, setOpen] = _ob_useState(false); const content = (HELP_CONTENT[lang] || HELP_CONTENT.en)[topic]; return ( <> setOpen(false)} content={content} lang={lang}/> ); } window.HelpButton = HelpButton;