fix: Poll sofort bei Dashboard-Besuch, User-Badge bleibt bis Favorit gelöscht, Navigation zu Favoriten

This commit is contained in:
2026-06-18 16:41:50 +02:00
parent 6884078d03
commit 161e43f58a
3 changed files with 12 additions and 13 deletions

View File

@@ -511,16 +511,12 @@ router.get('/favorites/unacked', authenticate, (req, res) => {
res.json({ count: count.n, isAdmin: true });
} else {
// User: Favoriten die vom Admin quittiert wurden aber User noch nicht gesehen hat
const count = db.prepare('SELECT COUNT(*) as n FROM movie_favorites WHERE user_id=? AND acknowledged=1 AND user_notified=0').get(req.user.id);
const count = db.prepare('SELECT COUNT(*) as n FROM movie_favorites WHERE user_id=? AND acknowledged=1').get(req.user.id);
res.json({ count: count.n, isAdmin: false });
}
});
// POST /favorites/user-notify User bestätigt Kenntnis der quittierten Favoriten
router.post('/favorites/user-notify', authenticate, (req, res) => {
db.prepare('UPDATE movie_favorites SET user_notified=1 WHERE user_id=? AND acknowledged=1 AND user_notified=0').run(req.user.id);
res.json({ ok: true });
});
// POST /favorites/acknowledge-all Admin: alle quittieren
router.post('/favorites/acknowledge-all', authenticate, requireAdmin, (req, res) => {

View File

@@ -1988,9 +1988,8 @@ function Dashboard({ toast, mobile, setActive, setDevToolsNav, unreadMsgs=0, unr
setActive('media');
setTimeout(()=>window.dispatchEvent(new CustomEvent('media-navigate',{detail:'favoriten'})),80);
} else {
api('/tools/media/favorites/user-notify',{method:'POST',body:{}})
.then(()=>{ setUnackedFavs({count:0,isAdmin:false}); setActive('media'); setTimeout(()=>window.dispatchEvent(new CustomEvent('media-navigate',{detail:'favoriten'})),80); })
.catch(()=>{});
setActive('media');
setTimeout(()=>window.dispatchEvent(new CustomEvent('media-navigate',{detail:'favoriten'})),80);
}
}} style={{
background:'rgba(245,158,11,0.12)', border:'1px solid rgba(245,158,11,0.35)',
@@ -3619,9 +3618,14 @@ export default function App() {
const [user,setUser]=useState(null);
const [active,setActiveRaw]=useState('dashboard');
const [devToolsNav, setDevToolsNav] = useState(null);
const pollUnackedFavs = () => api('/tools/media/favorites/unacked').then(d=>setUnackedFavs({count:d.count||0,isAdmin:d.isAdmin})).catch(()=>{});
const setActive = (page) => {
if (page === 'dashboard' && window.__newBuildAvailable && window.__safeReloadIfNewBuild?.()) return;
if (page === 'dashboard') setDashboardKey(k => k + 1); // Force-Refresh
if (page === 'dashboard') {
setDashboardKey(k => k + 1);
pollUnackedFavs(); // Sofort aktualisieren
}
setActiveRaw(page);
};
const [toastMsg,setToastMsg]=useState({msg:'',type:'success'});
@@ -3670,8 +3674,7 @@ export default function App() {
useEffect(()=>{
if(!user)return;
const poll=()=>api('/tools/media/favorites/unacked').then(d=>setUnackedFavs({count:d.count||0,isAdmin:d.isAdmin})).catch(()=>{});
poll(); const ti=setInterval(poll,60000); return()=>clearInterval(ti);
pollUnackedFavs(); const ti=setInterval(pollUnackedFavs,30000); return()=>clearInterval(ti);
},[user]);
useEffect(()=>{

View File

@@ -526,7 +526,7 @@ function SucheGrid({ onOpenModal, xrelIds, onXrelLoaded }) {
function FavCard({ f, onOpenModal, onRemove }) {
const genres = (() => { try { return JSON.parse(f.genres||'[]'); } catch { return []; } })();
const fskStyle = FSK_COLOR(f.fsk);
const isAcked = !!f.acknowledged && !f.user_notified;
const isAcked = !!f.acknowledged; // Badge bleibt bis Favorit gelöscht
return (
<div onClick={() => onOpenModal({ id: f.tmdb_id, media_type: f.media_type || 'movie' })} style={{
display:'flex', gap:12, alignItems:'flex-start',