Diverse änderungen am Push system
This commit is contained in:
@@ -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();
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user