Diverse änderungen am Push system
This commit is contained in:
@@ -29,42 +29,259 @@
|
||||
});
|
||||
}
|
||||
|
||||
// Request notification permission on page load
|
||||
if ('Notification' in window) {
|
||||
if (Notification.permission === 'default') {
|
||||
Notification.requestPermission().then(function(permission) {
|
||||
if (permission === 'granted') {
|
||||
console.log('✅ Notification permission granted');
|
||||
// Subscribe to push notifications
|
||||
subscribeToPush();
|
||||
} else {
|
||||
console.log('❌ Notification permission denied');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// Don't automatically request notification permission
|
||||
// User must click the button to enable push notifications
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Convert ArrayBuffer to Base64 string
|
||||
function arrayBufferToBase64(buffer) {
|
||||
const bytes = new Uint8Array(buffer);
|
||||
let binary = '';
|
||||
for (let i = 0; i < bytes.byteLength; i++) {
|
||||
binary += String.fromCharCode(bytes[i]);
|
||||
}
|
||||
return window.btoa(binary);
|
||||
}
|
||||
|
||||
// Push notification state
|
||||
let pushSubscription = null;
|
||||
let pushEnabled = false;
|
||||
|
||||
// Subscribe to push notifications
|
||||
async function subscribeToPush() {
|
||||
try {
|
||||
console.log('🔔 Starting push subscription...');
|
||||
|
||||
const registration = await navigator.serviceWorker.ready;
|
||||
const vapidPublicKey = 'BJmNVx0C3XeVxeKGTP9c-Z4HcuZNmdk6QdiLocZgCmb-miCS0ESFO3W2TvJlRhhNAShV63pWA5p36BTVSetyTds';
|
||||
const applicationServerKey = urlBase64ToUint8Array(vapidPublicKey);
|
||||
|
||||
const subscription = await registration.pushManager.subscribe({
|
||||
userVisibleOnly: true,
|
||||
applicationServerKey: 'BJmNVx0C3XeVxeKGTP9c-Z4HcuZNmdk6QdiLocZgCmb-miCS0ESFO3W2TvJlRhhNAShV63pWA5p36BTVSetyTds'
|
||||
applicationServerKey: applicationServerKey
|
||||
});
|
||||
|
||||
// Send subscription to server
|
||||
await fetch('/api/v1/public/subscribe', {
|
||||
pushSubscription = subscription;
|
||||
|
||||
// Generate or get player ID
|
||||
let playerId = window.currentPlayerId;
|
||||
if (!playerId) {
|
||||
// Generate a UUID for the player
|
||||
playerId = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
const r = Math.random() * 16 | 0;
|
||||
const v = c == 'x' ? r : (r & 0x3 | 0x8);
|
||||
return v.toString(16);
|
||||
});
|
||||
console.log(`📱 Generated player ID: ${playerId}`);
|
||||
} else {
|
||||
console.log(`📱 Using existing player ID: ${playerId}`);
|
||||
}
|
||||
|
||||
// Convert ArrayBuffer keys to Base64 strings
|
||||
const p256dhKey = subscription.getKey('p256dh');
|
||||
const authKey = subscription.getKey('auth');
|
||||
|
||||
// Convert ArrayBuffer to Base64 URL-safe string
|
||||
const p256dhString = arrayBufferToBase64(p256dhKey);
|
||||
const authString = arrayBufferToBase64(authKey);
|
||||
|
||||
console.log('📱 Converted keys to Base64 strings');
|
||||
console.log('📱 p256dh length:', p256dhString.length);
|
||||
console.log('📱 auth length:', authString.length);
|
||||
|
||||
// Send subscription to server with player ID
|
||||
const response = await fetch('/api/v1/public/subscribe', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(subscription)
|
||||
body: JSON.stringify({
|
||||
endpoint: subscription.endpoint,
|
||||
keys: {
|
||||
p256dh: p256dhString,
|
||||
auth: authString
|
||||
},
|
||||
playerId: playerId
|
||||
})
|
||||
});
|
||||
|
||||
console.log('✅ Push subscription successful');
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
pushEnabled = true;
|
||||
updatePushButton();
|
||||
console.log('✅ Push subscription successful');
|
||||
|
||||
// Store player ID for notifications
|
||||
if (result.playerId) {
|
||||
localStorage.setItem('pushPlayerId', result.playerId);
|
||||
}
|
||||
} else {
|
||||
throw new Error(result.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ Push subscription failed:', error);
|
||||
pushEnabled = false;
|
||||
updatePushButton();
|
||||
}
|
||||
}
|
||||
|
||||
// Unsubscribe from push notifications
|
||||
async function unsubscribeFromPush() {
|
||||
try {
|
||||
console.log('🔕 Unsubscribing from push notifications...');
|
||||
|
||||
// Get player ID from localStorage
|
||||
const playerId = localStorage.getItem('pushPlayerId');
|
||||
|
||||
if (pushSubscription) {
|
||||
await pushSubscription.unsubscribe();
|
||||
pushSubscription = null;
|
||||
console.log('✅ Local push subscription removed');
|
||||
}
|
||||
|
||||
// Notify server to remove from database
|
||||
if (playerId) {
|
||||
try {
|
||||
const response = await fetch('/api/v1/public/unsubscribe', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({ playerId: playerId })
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
if (result.success) {
|
||||
console.log('✅ Server notified - subscription removed from database');
|
||||
} else {
|
||||
console.warn('⚠️ Server notification failed:', result.message);
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('⚠️ Failed to notify server:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear stored player ID
|
||||
localStorage.removeItem('pushPlayerId');
|
||||
|
||||
pushEnabled = false;
|
||||
updatePushButton();
|
||||
console.log('🔕 Push notifications disabled');
|
||||
} catch (error) {
|
||||
console.error('❌ Push unsubscribe failed:', error);
|
||||
pushEnabled = false;
|
||||
updatePushButton();
|
||||
}
|
||||
}
|
||||
|
||||
// Toggle push notifications
|
||||
async function togglePushNotifications() {
|
||||
if (pushEnabled) {
|
||||
await unsubscribeFromPush();
|
||||
} else {
|
||||
// Check notification permission first
|
||||
if (Notification.permission === 'denied') {
|
||||
alert('Push-Benachrichtigungen sind blockiert. Bitte erlaube sie in den Browser-Einstellungen.');
|
||||
return;
|
||||
}
|
||||
|
||||
if (Notification.permission === 'default') {
|
||||
const permission = await Notification.requestPermission();
|
||||
if (permission !== 'granted') {
|
||||
alert('Push-Benachrichtigungen wurden nicht erlaubt.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await subscribeToPush();
|
||||
}
|
||||
}
|
||||
|
||||
// Update push button appearance
|
||||
function updatePushButton() {
|
||||
const button = document.getElementById('pushButton');
|
||||
if (!button) {
|
||||
console.log('❌ Push button not found in DOM');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`🔔 Updating push button - Status: ${pushEnabled ? 'ENABLED' : 'DISABLED'}`);
|
||||
|
||||
if (pushEnabled) {
|
||||
button.classList.add('active');
|
||||
button.setAttribute('data-de', '🔕 Push deaktivieren');
|
||||
button.setAttribute('data-en', '🔕 Disable Push');
|
||||
button.textContent = '🔕 Push deaktivieren';
|
||||
console.log('✅ Button updated to: Push deaktivieren (RED)');
|
||||
} else {
|
||||
button.classList.remove('active');
|
||||
button.setAttribute('data-de', '🔔 Push aktivieren');
|
||||
button.setAttribute('data-en', '🔔 Enable Push');
|
||||
button.textContent = '🔔 Push aktivieren';
|
||||
console.log('✅ Button updated to: Push aktivieren (GREEN)');
|
||||
}
|
||||
}
|
||||
|
||||
// Check existing push subscription on page load
|
||||
async function checkPushStatus() {
|
||||
try {
|
||||
console.log('🔍 Checking push status...');
|
||||
|
||||
if (!('serviceWorker' in navigator)) {
|
||||
console.log('❌ Service Worker not supported');
|
||||
pushEnabled = false;
|
||||
updatePushButton();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!('PushManager' in window)) {
|
||||
console.log('❌ Push Manager not supported');
|
||||
pushEnabled = false;
|
||||
updatePushButton();
|
||||
return;
|
||||
}
|
||||
|
||||
const registration = await navigator.serviceWorker.ready;
|
||||
console.log('✅ Service Worker ready');
|
||||
|
||||
const subscription = await registration.pushManager.getSubscription();
|
||||
console.log('📱 Current subscription:', subscription ? 'EXISTS' : 'NONE');
|
||||
|
||||
if (subscription) {
|
||||
pushSubscription = subscription;
|
||||
pushEnabled = true;
|
||||
updatePushButton();
|
||||
console.log('✅ Existing push subscription found and activated');
|
||||
|
||||
// Also check if we have a stored player ID
|
||||
const storedPlayerId = localStorage.getItem('pushPlayerId');
|
||||
if (storedPlayerId) {
|
||||
console.log(`📱 Push subscription linked to player: ${storedPlayerId}`);
|
||||
}
|
||||
} else {
|
||||
pushEnabled = false;
|
||||
updatePushButton();
|
||||
console.log('ℹ️ No existing push subscription found');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ Error checking push status:', error);
|
||||
pushEnabled = false;
|
||||
updatePushButton();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -84,6 +301,7 @@
|
||||
<div class="user-avatar" id="userAvatar">U</div>
|
||||
<span id="userEmail">user@example.com</span>
|
||||
</div>
|
||||
<button class="btn btn-push" id="pushButton" onclick="togglePushNotifications()" data-de="🔔 Push aktivieren" data-en="🔔 Enable Push">🔔 Push aktivieren</button>
|
||||
<a href="/" class="btn btn-primary" data-de="Zurück zu Zeiten" data-en="Back to Times">Back to Times</a>
|
||||
<button class="btn btn-logout" onclick="logout()" data-de="Logout" data-en="Logout">Logout</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user