"use client"; import FloatingBackground from "@/components/floating-background"; import ShortsMarquee from "@/components/shorts-marquee"; import { useEffect, useState } from "react"; import { signIn, signOut, useSession } from "next-auth/react"; import MonthlyBest from "@/components/monthly-best"; import Image from "next/image"; import SiteHeader from "../components/site-header"; import VoltgamingBanner from "@/components/voltgaming-banner"; import { faArrowLeft, faCheck, faClock, faComment, faThumbsUp, faEye, faPlay, faRocket, faUsers, faVideo, } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; type Video = { id: string; title: string; thumbnail: string; publishedAt: string; url: string; views: string | null; likes: string | null; comments: string | null; }; type Channel = { title?: string; subscribers?: number | string; totalViews?: number | string; videoCount?: number | string; }; type VideosResponse = { channel?: Channel; videos?: Video[]; error?: string; }; type IntroStep = "start" | "source" | "welcome" | "loading"; const messages = [ "جدیدترین ویدیوهای کانال رو همین‌جا دنبال کن.", "عضو خانواده ترونیکس شو تا ویدیوها و چالش‌های جدید رو از دست ندی.", "به کانال تلگراممون سر بزن تا از اخبار و اطلاعیه‌ها باخبر بمونی.", ]; const sources = [ { id: "youtube", label: "یوتیوب", detail: "از طریق ویدیوها و شورت‌ها" }, { id: "telegram", label: "تلگرام", detail: "از طریق کانال تلگرام" }, { id: "friends", label: "دوستان", detail: "با معرفی دوستانم" }, { id: "other", label: "جای دیگه", detail: "از یک مسیر دیگه آشنا شدم" }, ]; export default function Home() { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(""); const [sort, setSort] = useState("newest"); const [messageIndex, setMessageIndex] = useState(0); const [introStep, setIntroStep] = useState(null); const [selectedSource, setSelectedSource] = useState(""); const [introChecked, setIntroChecked] = useState(false); const [activeHeartVideo, setActiveHeartVideo] = useState(-1); const [fadingHeartVideo, setFadingHeartVideo] = useState(false); useEffect(() => { let timeout: ReturnType; let previousVideo = -1; let cancelled = false; const runCycle = () => { if (cancelled) return; const choices = [0, 1, 2].filter( (index) => index !== previousVideo ); const nextVideo = choices[Math.floor(Math.random() * choices.length)]; previousVideo = nextVideo; setActiveHeartVideo(nextVideo); timeout = setTimeout(() => { if (cancelled) return; setFadingHeartVideo(true); timeout = setTimeout(() => { if (cancelled) return; setActiveHeartVideo(-1); setFadingHeartVideo(false); }, 1800); timeout = setTimeout(runCycle, 5000); }, 10000); }; timeout = setTimeout(runCycle, Math.random() * 3000); return () => { cancelled = true; clearTimeout(timeout); }; }, []); useEffect(() => { let timeout: ReturnType; let cancelled = false; let previousVideo = -1; const scheduleNext = (delay: number) => { timeout = setTimeout(() => { if (cancelled) return; // بین این فاصله‌ها هیچ انیمیشنی فعال نیست setActiveHeartVideo(-1); const pause = 2500 + Math.random() * 6500; timeout = setTimeout(() => { if (cancelled) return; const choices = [0, 1, 2].filter( (index) => index !== previousVideo ); const next = choices[Math.floor(Math.random() * choices.length)]; previousVideo = next; setActiveHeartVideo(next); // مدت اجرای موج در هر نوبت متفاوت است scheduleNext(7000 + Math.random() * 7000); }, pause); }, delay); }; // شروع اولیه با تأخیر تصادفی timeout = setTimeout(() => { if (cancelled) return; const first = Math.floor(Math.random() * 3); previousVideo = first; setActiveHeartVideo(first); scheduleNext(7000 + Math.random() * 7000); }, 1500 + Math.random() * 5000); return () => { cancelled = true; clearTimeout(timeout); }; }, []); useEffect(() => { const completed = localStorage.getItem("tronix-onboarding-complete"); if (!completed) setIntroStep("start"); setIntroChecked(true); }, []); useEffect(() => { let cancelled = false; async function loadVideos() { try { const response = await fetch("/api/videos"); if (!response.ok) { throw new Error("دریافت اطلاعات کانال ناموفق بود."); } const result: VideosResponse = await response.json(); if (!cancelled) { setData(result); setError(result.error ?? ""); } } catch { if (!cancelled) { setError("بارگذاری اطلاعات با خطا مواجه شد. دوباره تلاش کن."); } } finally { if (!cancelled) setLoading(false); } } loadVideos(); return () => { cancelled = true; }; }, []); useEffect(() => { const interval = window.setInterval(() => { setMessageIndex((current) => (current + 1) % messages.length); }, 10000); return () => window.clearInterval(interval); }, []); useEffect(() => { if (introStep !== "loading") return; const timer = window.setTimeout(() => { localStorage.setItem("tronix-onboarding-complete", "true"); if (selectedSource) { localStorage.setItem("tronix-discovery-source", selectedSource); } setIntroStep(null); }, 3000); return () => window.clearTimeout(timer); }, [introStep, selectedSource]); const channel = data?.channel; const videos = data?.videos ?? []; const sortedVideos = [...videos].sort((a, b) => { const dateA = new Date(a.publishedAt).getTime(); const dateB = new Date(b.publishedAt).getTime(); if (sort === "oldest") return dateA - dateB; return dateB - dateA; }); const formatNumber = (value?: number | string | null) => { const number = Number(value ?? 0); if (!Number.isFinite(number)) return "0"; return new Intl.NumberFormat("en-US", { notation: "compact", maximumFractionDigits: 1, }).format(number); }; const formatDate = (date: string) => { if (!date) return "تاریخ نامشخص"; const parsed = new Date(date); if (Number.isNaN(parsed.getTime())) return "تاریخ نامشخص"; return parsed.toLocaleDateString("fa-IR", { year: "numeric", month: "long", day: "numeric", }); }; const beginLoading = () => setIntroStep("loading"); return ( <> {/* */}
{/* Hero */}
TRONIX COMMUNITY

به جمع{" "} تروبکس
خوش اومدی

{messages[messageIndex]}

پروفایل ترونیکس
TRONIX
{/* Videos */} {/* Shorts Showcase */}

TRONIX / SHORTS

جدیدترین ویدیو ها

جدیدترین اتفاقات کانال ترونیکس؛ کوتاه، سریع و بدون حاشیه.

مشاهده همه شورت‌ها
{error && (
{error}
)} {loading ? (
{[1, 2, 3].map((item) => (
))}
) : sortedVideos.length > 0 ? (
{/* Community callout */}

بخشی از تروبکس شو

برای ویدیوهای تازه، خبرها و اطلاعیه‌های ترونیکس همراه جامعه باش.

عضویت در تلگرام
{/* Monthly Best - placeholder */}

ساخته‌شده برای جامعه‌ی ترونیکس

© TRONIX

{/* First-visit onboarding */} {introChecked && introStep && (
{introStep !== "loading" && (
Tronix
TRONIX
YOUR NEXT LEVEL
)} {introStep === "start" && (

WELCOME TO TRONIX

اینجا خونه‌ی تروبکسه

به فضای ترونیکس خوش اومدی؛ جایی برای ویدیوها، خبرها و اتفاقات تازه.

)} {introStep === "source" && (

ONE QUICK QUESTION

از چه طریقی با ترونیکس آشنا شدی؟

انتخابت فقط برای شناخت بهتر جامعه‌مونه.

{sources.map((source) => ( ))}
)} {introStep === "welcome" && (

خوش اومدی به جمع تروبکس!

همه‌چیز آماده‌ست. بریم سراغ دنیای ترونیکس.

)} {introStep === "loading" && (
Tronix

داریم همه‌چیز رو آماده می‌کنیم

خوش اومدی به جمع تروبکس...

)}
)}
); } /* Tronix latest videos animations */