Spaces:
Running
Running
Update cointube.jsx
Browse files- cointube.jsx +3 -17
cointube.jsx
CHANGED
|
@@ -50,7 +50,6 @@ export default function App() {
|
|
| 50 |
const coinIntervalRef = useRef(null);
|
| 51 |
const localCoinBufferRef = useRef(0);
|
| 52 |
|
| 53 |
-
// --- 1. INIT ---
|
| 54 |
useEffect(() => {
|
| 55 |
const initFirebase = async () => {
|
| 56 |
try {
|
|
@@ -74,7 +73,6 @@ export default function App() {
|
|
| 74 |
initFirebase();
|
| 75 |
}, []);
|
| 76 |
|
| 77 |
-
// --- 2. AUTH ---
|
| 78 |
useEffect(() => {
|
| 79 |
if (!firebaseReady || !auth) return;
|
| 80 |
const unsubscribeAuth = onAuthStateChanged(auth, (user) => {
|
|
@@ -91,7 +89,6 @@ export default function App() {
|
|
| 91 |
return () => unsubscribeAuth();
|
| 92 |
}, [firebaseReady]);
|
| 93 |
|
| 94 |
-
// --- 3. PROFILE ---
|
| 95 |
useEffect(() => {
|
| 96 |
if (!firebaseReady || !userId || !db) return;
|
| 97 |
const profileRef = doc(db, 'users', userId);
|
|
@@ -111,7 +108,6 @@ export default function App() {
|
|
| 111 |
return () => unsubscribeProfile();
|
| 112 |
}, [userId, user, firebaseReady]);
|
| 113 |
|
| 114 |
-
// --- 4. VIDEOS ---
|
| 115 |
useEffect(() => {
|
| 116 |
if (!firebaseReady || !db) return;
|
| 117 |
const q = query(collection(db, 'videos'), orderBy('createdAt', 'desc'), limit(50));
|
|
@@ -126,28 +122,22 @@ export default function App() {
|
|
| 126 |
return () => unsubscribe();
|
| 127 |
}, [firebaseReady]);
|
| 128 |
|
| 129 |
-
// --- 5. RANKING (FILTRADO POR GMAIL Y PUNTOS > 0) ---
|
| 130 |
useEffect(() => {
|
| 131 |
if (!firebaseReady || !db) return;
|
| 132 |
-
// Pedimos 100 para tener margen de filtrado
|
| 133 |
const q = query(collection(db, 'users'), orderBy('coins', 'desc'), limit(100));
|
| 134 |
const unsubscribe = onSnapshot(q, (snapshot) => {
|
| 135 |
let usersList = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
|
| 136 |
|
| 137 |
-
// --- FILTROS NUEVOS ---
|
| 138 |
usersList = usersList.filter(u =>
|
| 139 |
-
u.coins > 0 && // Que tenga monedas
|
| 140 |
u.email &&
|
| 141 |
-
u.email.endsWith('@gmail.com')
|
| 142 |
);
|
| 143 |
|
| 144 |
-
// Nos quedamos con los top 20 después de filtrar
|
| 145 |
setLeaderboard(usersList.slice(0, 20));
|
| 146 |
});
|
| 147 |
return () => unsubscribe();
|
| 148 |
}, [firebaseReady]);
|
| 149 |
|
| 150 |
-
// --- 6. YOUTUBE API ---
|
| 151 |
useEffect(() => {
|
| 152 |
if (!window.YT) {
|
| 153 |
const tag = document.createElement('script');
|
|
@@ -160,7 +150,6 @@ export default function App() {
|
|
| 160 |
}
|
| 161 |
}, []);
|
| 162 |
|
| 163 |
-
// --- LOGICA DE MONEDAS ---
|
| 164 |
const saveCoinBuffer = useCallback(() => {
|
| 165 |
if (localCoinBufferRef.current > 0 && userId && db) {
|
| 166 |
const coinsToSave = localCoinBufferRef.current;
|
|
@@ -358,26 +347,23 @@ export default function App() {
|
|
| 358 |
</div>
|
| 359 |
</div>
|
| 360 |
|
| 361 |
-
{/* RANKING ACTUALIZADO */}
|
| 362 |
<div className="bg-gray-800 rounded p-4 flex-1 flex flex-col min-h-[200px]">
|
| 363 |
<h3 className="text-yellow-500 text-sm uppercase font-bold mb-2">Ranking Global</h3>
|
| 364 |
<div className="overflow-y-auto flex-1 pr-2 custom-scrollbar space-y-2">
|
| 365 |
{leaderboard.length > 0 ? (
|
| 366 |
leaderboard.map((u, i) => (
|
| 367 |
<div key={u.id || i} className="flex justify-between items-center p-2 bg-gray-700 rounded">
|
| 368 |
-
{/* Correo en letra pequeña, sin #1 */}
|
| 369 |
<span className="text-xs text-gray-300 truncate mr-2" title={u.email}>
|
| 370 |
{u.email}
|
| 371 |
</span>
|
| 372 |
-
{/* Monedas */}
|
| 373 |
<span className="text-yellow-400 font-mono text-sm whitespace-nowrap">
|
| 374 |
-
{Math.floor(u.coins)}
|
| 375 |
</span>
|
| 376 |
</div>
|
| 377 |
))
|
| 378 |
) : (
|
| 379 |
<div className="text-center text-gray-500 text-sm py-4">
|
| 380 |
-
Esperando usuarios
|
| 381 |
</div>
|
| 382 |
)}
|
| 383 |
</div>
|
|
|
|
| 50 |
const coinIntervalRef = useRef(null);
|
| 51 |
const localCoinBufferRef = useRef(0);
|
| 52 |
|
|
|
|
| 53 |
useEffect(() => {
|
| 54 |
const initFirebase = async () => {
|
| 55 |
try {
|
|
|
|
| 73 |
initFirebase();
|
| 74 |
}, []);
|
| 75 |
|
|
|
|
| 76 |
useEffect(() => {
|
| 77 |
if (!firebaseReady || !auth) return;
|
| 78 |
const unsubscribeAuth = onAuthStateChanged(auth, (user) => {
|
|
|
|
| 89 |
return () => unsubscribeAuth();
|
| 90 |
}, [firebaseReady]);
|
| 91 |
|
|
|
|
| 92 |
useEffect(() => {
|
| 93 |
if (!firebaseReady || !userId || !db) return;
|
| 94 |
const profileRef = doc(db, 'users', userId);
|
|
|
|
| 108 |
return () => unsubscribeProfile();
|
| 109 |
}, [userId, user, firebaseReady]);
|
| 110 |
|
|
|
|
| 111 |
useEffect(() => {
|
| 112 |
if (!firebaseReady || !db) return;
|
| 113 |
const q = query(collection(db, 'videos'), orderBy('createdAt', 'desc'), limit(50));
|
|
|
|
| 122 |
return () => unsubscribe();
|
| 123 |
}, [firebaseReady]);
|
| 124 |
|
|
|
|
| 125 |
useEffect(() => {
|
| 126 |
if (!firebaseReady || !db) return;
|
|
|
|
| 127 |
const q = query(collection(db, 'users'), orderBy('coins', 'desc'), limit(100));
|
| 128 |
const unsubscribe = onSnapshot(q, (snapshot) => {
|
| 129 |
let usersList = snapshot.docs.map(doc => ({ id: doc.id, ...doc.data() }));
|
| 130 |
|
|
|
|
| 131 |
usersList = usersList.filter(u =>
|
|
|
|
| 132 |
u.email &&
|
| 133 |
+
u.email.endsWith('@gmail.com')
|
| 134 |
);
|
| 135 |
|
|
|
|
| 136 |
setLeaderboard(usersList.slice(0, 20));
|
| 137 |
});
|
| 138 |
return () => unsubscribe();
|
| 139 |
}, [firebaseReady]);
|
| 140 |
|
|
|
|
| 141 |
useEffect(() => {
|
| 142 |
if (!window.YT) {
|
| 143 |
const tag = document.createElement('script');
|
|
|
|
| 150 |
}
|
| 151 |
}, []);
|
| 152 |
|
|
|
|
| 153 |
const saveCoinBuffer = useCallback(() => {
|
| 154 |
if (localCoinBufferRef.current > 0 && userId && db) {
|
| 155 |
const coinsToSave = localCoinBufferRef.current;
|
|
|
|
| 347 |
</div>
|
| 348 |
</div>
|
| 349 |
|
|
|
|
| 350 |
<div className="bg-gray-800 rounded p-4 flex-1 flex flex-col min-h-[200px]">
|
| 351 |
<h3 className="text-yellow-500 text-sm uppercase font-bold mb-2">Ranking Global</h3>
|
| 352 |
<div className="overflow-y-auto flex-1 pr-2 custom-scrollbar space-y-2">
|
| 353 |
{leaderboard.length > 0 ? (
|
| 354 |
leaderboard.map((u, i) => (
|
| 355 |
<div key={u.id || i} className="flex justify-between items-center p-2 bg-gray-700 rounded">
|
|
|
|
| 356 |
<span className="text-xs text-gray-300 truncate mr-2" title={u.email}>
|
| 357 |
{u.email}
|
| 358 |
</span>
|
|
|
|
| 359 |
<span className="text-yellow-400 font-mono text-sm whitespace-nowrap">
|
| 360 |
+
{Math.floor(u.coins || 0)}
|
| 361 |
</span>
|
| 362 |
</div>
|
| 363 |
))
|
| 364 |
) : (
|
| 365 |
<div className="text-center text-gray-500 text-sm py-4">
|
| 366 |
+
Esperando usuarios...
|
| 367 |
</div>
|
| 368 |
)}
|
| 369 |
</div>
|