Diverse änderungen am Push system

This commit is contained in:
2025-09-16 21:00:12 +02:00
parent 69e3985af3
commit b2fc63e2d0
7 changed files with 992 additions and 164 deletions

View File

@@ -324,6 +324,9 @@ document.addEventListener('DOMContentLoaded', function () {
loadLanguagePreference();
changeLanguage(); // Apply saved language
initDashboard();
// Push notifications are now handled manually via the button
// No automatic subscription on page load
});
// Modal functions
@@ -1739,6 +1742,25 @@ function initializeAchievements(playerId) {
loadPlayerAchievements();
}
// Convert VAPID key from base64url to Uint8Array
function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
.replace(/\-/g, '+')
.replace(/_/g, '/');
const rawData = window.atob(base64);
const outputArray = new Uint8Array(rawData.length);
for (let i = 0; i < rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
}
return outputArray;
}
// Push notifications are now handled in dashboard.html
// This function has been moved to the HTML file for better integration
// Web Notification Functions
function showWebNotification(title, message, icon = '🏆') {
if ('Notification' in window && Notification.permission === 'granted') {
@@ -1763,9 +1785,23 @@ function showWebNotification(title, message, icon = '🏆') {
}
}
// Track which notifications have been sent today
let notificationsSentToday = {
daily: false,
weekly: false,
monthly: false
};
// Check for best time achievements and show notifications
async function checkBestTimeNotifications() {
try {
// Check if push notifications are enabled
const pushPlayerId = localStorage.getItem('pushPlayerId');
if (!pushPlayerId) {
console.log('🔕 Push notifications disabled, skipping best time check');
return;
}
const response = await fetch('/api/v1/public/best-times');
const result = await response.json();
@@ -1774,28 +1810,95 @@ async function checkBestTimeNotifications() {
// Check if current player has best times
if (currentPlayerId) {
if (daily && daily.player_id === currentPlayerId) {
const title = currentLanguage === 'de' ? '🏆 Tageskönig!' : '🏆 Daily King!';
const message = currentLanguage === 'de' ?
`Glückwunsch! Du hast die beste Zeit des Tages mit ${daily.best_time} erreicht!` :
`Congratulations! You achieved the best time of the day with ${daily.best_time}!`;
showWebNotification(title, message, '👑');
const now = new Date();
const isEvening = now.getHours() >= 19;
// Check daily best time (only in the evening, only once per day)
if (daily && daily.player_id === currentPlayerId && isEvening) {
// Check if notification was already sent today
const dailyCheck = await fetch(`/api/v1/public/notification-sent/${currentPlayerId}/daily_best`);
const dailyResult = await dailyCheck.json();
if (!dailyResult.wasSent) {
const title = currentLanguage === 'de' ? '🏆 Tageskönig!' : '🏆 Daily King!';
const message = currentLanguage === 'de' ?
`Glückwunsch! Du hast die beste Zeit des Tages mit ${daily.best_time} erreicht!` :
`Congratulations! You achieved the best time of the day with ${daily.best_time}!`;
showWebNotification(title, message, '👑');
// Mark as sent in database
await fetch('/api/v1/public/notification-sent', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
playerId: currentPlayerId,
notificationType: 'daily_best'
})
});
console.log('🏆 Daily best notification sent');
}
}
// Check weekly best time (only on Sunday evening, only once per week)
if (weekly && weekly.player_id === currentPlayerId) {
const title = currentLanguage === 'de' ? '🏆 Wochenchampion!' : '🏆 Weekly Champion!';
const message = currentLanguage === 'de' ?
`Fantastisch! Du bist der Wochenchampion mit ${weekly.best_time}!` :
`Fantastic! You are the weekly champion with ${weekly.best_time}!`;
showWebNotification(title, message, '🏆');
const isSunday = now.getDay() === 0; // 0 = Sunday
if (isSunday && isEvening) {
// Check if notification was already sent this week
const weeklyCheck = await fetch(`/api/v1/public/notification-sent/${currentPlayerId}/weekly_best`);
const weeklyResult = await weeklyCheck.json();
if (!weeklyResult.wasSent) {
const title = currentLanguage === 'de' ? '🏆 Wochenchampion!' : '🏆 Weekly Champion!';
const message = currentLanguage === 'de' ?
`Fantastisch! Du bist der Wochenchampion mit ${weekly.best_time}!` :
`Fantastic! You are the weekly champion with ${weekly.best_time}!`;
showWebNotification(title, message, '🏆');
// Mark as sent in database
await fetch('/api/v1/public/notification-sent', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
playerId: currentPlayerId,
notificationType: 'weekly_best'
})
});
console.log('🏆 Weekly best notification sent');
}
}
}
// Check monthly best time (only on last evening of month at 19:00, only once per month)
if (monthly && monthly.player_id === currentPlayerId) {
const title = currentLanguage === 'de' ? '🏆 Monatsmeister!' : '🏆 Monthly Master!';
const message = currentLanguage === 'de' ?
`Unglaublich! Du bist der Monatsmeister mit ${monthly.best_time}!` :
`Incredible! You are the monthly master with ${monthly.best_time}!`;
showWebNotification(title, message, '🥇');
const lastDayOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0);
const isLastDayOfMonth = now.getDate() === lastDayOfMonth.getDate();
// Only show monthly notification on last day of month at 19:00 or later
if (isLastDayOfMonth && isEvening) {
// Check if notification was already sent this month
const monthlyCheck = await fetch(`/api/v1/public/notification-sent/${currentPlayerId}/monthly_best`);
const monthlyResult = await monthlyCheck.json();
if (!monthlyResult.wasSent) {
const title = currentLanguage === 'de' ? '🏆 Monatsmeister!' : '🏆 Monthly Master!';
const message = currentLanguage === 'de' ?
`Unglaublich! Du bist der Monatsmeister mit ${monthly.best_time}!` :
`Incredible! You are the monthly master with ${monthly.best_time}!`;
showWebNotification(title, message, '🥇');
// Mark as sent in database
await fetch('/api/v1/public/notification-sent', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
playerId: currentPlayerId,
notificationType: 'monthly_best'
})
});
console.log('🏆 Monthly best notification sent');
}
}
}
}
}
@@ -1809,6 +1912,13 @@ async function checkAchievementNotifications() {
try {
if (!currentPlayerId) return;
// Check if push notifications are enabled
const pushPlayerId = localStorage.getItem('pushPlayerId');
if (!pushPlayerId) {
console.log('🔕 Push notifications disabled, skipping achievement check');
return;
}
const response = await fetch(`/api/achievements/player/${currentPlayerId}?t=${Date.now()}`);
const result = await response.json();
@@ -1821,14 +1931,33 @@ async function checkAchievementNotifications() {
});
if (newAchievements.length > 0) {
newAchievements.forEach(achievement => {
const translatedAchievement = translateAchievement(achievement);
showWebNotification(
`🏆 ${translatedAchievement.name}`,
translatedAchievement.description,
achievement.icon || '🏆'
);
});
for (const achievement of newAchievements) {
// Check if notification was already sent for this achievement
const achievementCheck = await fetch(`/api/v1/public/notification-sent/${currentPlayerId}/achievement?achievementId=${achievement.achievement_id}&locationId=${achievement.location_id || ''}`);
const achievementResult = await achievementCheck.json();
if (!achievementResult.wasSent) {
const translatedAchievement = translateAchievement(achievement);
showWebNotification(
`🏆 ${translatedAchievement.name}`,
translatedAchievement.description,
achievement.icon || '🏆'
);
// Mark as sent in database
await fetch('/api/v1/public/notification-sent', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
playerId: currentPlayerId,
notificationType: 'achievement',
achievementId: achievement.achievement_id,
locationId: achievement.location_id || null
})
});
console.log(`🏆 Achievement notification sent: ${achievement.name}`);
}
}
}
}
} catch (error) {
@@ -1967,4 +2096,9 @@ document.addEventListener('DOMContentLoaded', function () {
}
});
}
// Check push notification status on dashboard load
if (typeof checkPushStatus === 'function') {
checkPushStatus();
}
});