Spaces:
Sleeping
Sleeping
Commit ·
a285355
1
Parent(s): ca3e3fd
fix: use popup auth (redirect needs Firebase Hosting), fix BGR/RGB bug in InsightFace calls
Browse files- core/detector.py +2 -4
- core/swapper.py +6 -6
- frontend/src/pages/LandingPage.jsx +12 -23
core/detector.py
CHANGED
|
@@ -41,8 +41,7 @@ def detect_faces(image: np.ndarray) -> list:
|
|
| 41 |
app = _get_insightface()
|
| 42 |
if app is not None:
|
| 43 |
try:
|
| 44 |
-
|
| 45 |
-
faces = app.get(rgb)
|
| 46 |
if faces:
|
| 47 |
bboxes = []
|
| 48 |
for face in faces:
|
|
@@ -76,7 +75,6 @@ def get_insightface_faces(image: np.ndarray):
|
|
| 76 |
if app is None:
|
| 77 |
return []
|
| 78 |
try:
|
| 79 |
-
|
| 80 |
-
return app.get(rgb)
|
| 81 |
except Exception:
|
| 82 |
return []
|
|
|
|
| 41 |
app = _get_insightface()
|
| 42 |
if app is not None:
|
| 43 |
try:
|
| 44 |
+
faces = app.get(image) # InsightFace expects BGR (OpenCV native)
|
|
|
|
| 45 |
if faces:
|
| 46 |
bboxes = []
|
| 47 |
for face in faces:
|
|
|
|
| 75 |
if app is None:
|
| 76 |
return []
|
| 77 |
try:
|
| 78 |
+
return app.get(image) # InsightFace expects BGR
|
|
|
|
| 79 |
except Exception:
|
| 80 |
return []
|
core/swapper.py
CHANGED
|
@@ -57,13 +57,12 @@ def swap_face_insightface(source: np.ndarray, target: np.ndarray) -> np.ndarray:
|
|
| 57 |
return _fallback_swap(source, target)
|
| 58 |
|
| 59 |
try:
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
src_faces = app.get(src_rgb)
|
| 64 |
-
tgt_faces = app.get(tgt_rgb)
|
| 65 |
|
| 66 |
if not src_faces or not tgt_faces:
|
|
|
|
| 67 |
return _fallback_swap(source, target)
|
| 68 |
|
| 69 |
result = target.copy()
|
|
@@ -72,7 +71,8 @@ def swap_face_insightface(source: np.ndarray, target: np.ndarray) -> np.ndarray:
|
|
| 72 |
result = swapper.get(result, tgt_face, src_face, paste_back=True)
|
| 73 |
|
| 74 |
return result
|
| 75 |
-
except Exception:
|
|
|
|
| 76 |
return _fallback_swap(source, target)
|
| 77 |
|
| 78 |
|
|
|
|
| 57 |
return _fallback_swap(source, target)
|
| 58 |
|
| 59 |
try:
|
| 60 |
+
# InsightFace expects BGR (OpenCV native) — do NOT convert to RGB
|
| 61 |
+
src_faces = app.get(source)
|
| 62 |
+
tgt_faces = app.get(target)
|
|
|
|
|
|
|
| 63 |
|
| 64 |
if not src_faces or not tgt_faces:
|
| 65 |
+
print(f"[swapper] face detection failed: src={len(src_faces)} tgt={len(tgt_faces)}")
|
| 66 |
return _fallback_swap(source, target)
|
| 67 |
|
| 68 |
result = target.copy()
|
|
|
|
| 71 |
result = swapper.get(result, tgt_face, src_face, paste_back=True)
|
| 72 |
|
| 73 |
return result
|
| 74 |
+
except Exception as e:
|
| 75 |
+
print(f"[swapper] swap failed: {e}")
|
| 76 |
return _fallback_swap(source, target)
|
| 77 |
|
| 78 |
|
frontend/src/pages/LandingPage.jsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
-
import { useState
|
| 2 |
import { useNavigate } from 'react-router-dom';
|
| 3 |
import { motion } from 'framer-motion';
|
| 4 |
-
import { auth, googleProvider,
|
| 5 |
import useAuth, { saveSession, daysLeft } from '../hooks/useAuth';
|
| 6 |
import Aurora from '../components/ui/Aurora';
|
| 7 |
import SplitText from '../components/ui/SplitText';
|
|
@@ -49,33 +49,22 @@ export default function LandingPage() {
|
|
| 49 |
const isSignedIn = !!user;
|
| 50 |
const days = isSignedIn ? daysLeft() : 0;
|
| 51 |
|
| 52 |
-
// Handle redirect result when returning from Google sign-in redirect
|
| 53 |
-
useEffect(() => {
|
| 54 |
-
if (typeof getRedirectResult !== 'function') return;
|
| 55 |
-
getRedirectResult(auth).then(result => {
|
| 56 |
-
if (!result) return;
|
| 57 |
-
saveSession(result.user, '');
|
| 58 |
-
result.user.getIdToken(false).then(t => localStorage.setItem('df_token', t)).catch(() => {});
|
| 59 |
-
navigate('/app');
|
| 60 |
-
}).catch(err => {
|
| 61 |
-
if (err?.code && err.code !== 'auth/popup-closed-by-user') {
|
| 62 |
-
setError(`Sign in failed: ${err.code}`);
|
| 63 |
-
}
|
| 64 |
-
});
|
| 65 |
-
}, [navigate]);
|
| 66 |
-
|
| 67 |
const doGoogleSignIn = async () => {
|
| 68 |
setSigningIn(true);
|
| 69 |
setError('');
|
| 70 |
try {
|
| 71 |
-
await
|
| 72 |
-
|
|
|
|
|
|
|
| 73 |
} catch (err) {
|
| 74 |
console.error('[Firebase Auth Error]', err?.code, err?.message);
|
| 75 |
-
if (err?.code === 'auth/
|
| 76 |
-
|
| 77 |
-
} else if (err?.code === 'auth/
|
| 78 |
-
setError('
|
|
|
|
|
|
|
| 79 |
} else {
|
| 80 |
setError(`Sign in failed: ${err?.code || err?.message || 'unknown error'}`);
|
| 81 |
}
|
|
|
|
| 1 |
+
import { useState } from 'react';
|
| 2 |
import { useNavigate } from 'react-router-dom';
|
| 3 |
import { motion } from 'framer-motion';
|
| 4 |
+
import { auth, googleProvider, signInWithPopup } from '../firebase';
|
| 5 |
import useAuth, { saveSession, daysLeft } from '../hooks/useAuth';
|
| 6 |
import Aurora from '../components/ui/Aurora';
|
| 7 |
import SplitText from '../components/ui/SplitText';
|
|
|
|
| 49 |
const isSignedIn = !!user;
|
| 50 |
const days = isSignedIn ? daysLeft() : 0;
|
| 51 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 52 |
const doGoogleSignIn = async () => {
|
| 53 |
setSigningIn(true);
|
| 54 |
setError('');
|
| 55 |
try {
|
| 56 |
+
const result = await signInWithPopup(auth, googleProvider);
|
| 57 |
+
saveSession(result.user, '');
|
| 58 |
+
result.user.getIdToken(false).then(t => localStorage.setItem('df_token', t)).catch(() => {});
|
| 59 |
+
navigate('/app');
|
| 60 |
} catch (err) {
|
| 61 |
console.error('[Firebase Auth Error]', err?.code, err?.message);
|
| 62 |
+
if (err?.code === 'auth/popup-closed-by-user' || err?.code === 'auth/cancelled-popup-request') {
|
| 63 |
+
// user dismissed — no message needed
|
| 64 |
+
} else if (err?.code === 'auth/popup-blocked') {
|
| 65 |
+
setError('Popup blocked — please allow popups for this site in your browser, then try again.');
|
| 66 |
+
} else if (err?.code === 'auth/unauthorized-domain') {
|
| 67 |
+
setError('Domain not authorised in Firebase. Contact the app owner.');
|
| 68 |
} else {
|
| 69 |
setError(`Sign in failed: ${err?.code || err?.message || 'unknown error'}`);
|
| 70 |
}
|