Skip to content

Commit 835fad3

Browse files
committed
try to fix notif on mobile
1 parent fdbe659 commit 835fad3

File tree

1 file changed

+216
-17
lines changed

1 file changed

+216
-17
lines changed

index.html

Lines changed: 216 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,37 @@
8888
box-shadow: 0 0 5px #00ff00;
8989
}
9090

91+
.notification-button {
92+
background: #003300;
93+
border: 1px solid #00ff00;
94+
color: #00ff00;
95+
padding: 5px 8px;
96+
font-family: inherit;
97+
font-size: 14px;
98+
cursor: pointer;
99+
transition: all 0.2s;
100+
border-radius: 3px;
101+
}
102+
103+
.notification-button:hover {
104+
background: #00ff00;
105+
color: #000;
106+
box-shadow: 0 0 5px #00ff00;
107+
}
108+
109+
.notification-button.enabled {
110+
background: #00ff00;
111+
color: #000;
112+
}
113+
114+
.notification-button.disabled {
115+
background: #660000;
116+
border-color: #ff0000;
117+
color: #ff6666;
118+
opacity: 0.7;
119+
cursor: not-allowed;
120+
}
121+
91122
.status-group {
92123
display: flex;
93124
flex-direction: column;
@@ -190,6 +221,11 @@
190221
font-size: 11px;
191222
}
192223

224+
.notification-button {
225+
padding: 3px 6px;
226+
font-size: 12px;
227+
}
228+
193229
.status-group {
194230
align-items: flex-end;
195231
gap: 1px;
@@ -763,6 +799,7 @@
763799
<div class="title">RetroChat</div>
764800
<div class="user-info">
765801
<input type="text" class="nickname-input" placeholder="Enter nickname..." value="">
802+
<button class="notification-button" id="notificationButton" title="Enable notifications">🔔</button>
766803
<div class="status-group">
767804
<span class="status connecting" id="status">
768805
Connecting...
@@ -852,7 +889,7 @@
852889
this.initProtobuf();
853890
this.initElements();
854891
this.initEventListeners();
855-
this.requestNotificationPermission();
892+
this.initNotificationButton();
856893
this.initWaku();
857894
}
858895

@@ -894,34 +931,139 @@
894931
return nickname;
895932
}
896933

897-
async requestNotificationPermission() {
934+
initNotificationButton() {
898935
if (!('Notification' in window)) {
899936
console.log('This browser does not support notifications');
937+
this.notificationButton.style.display = 'none';
900938
this.addSystemMessage('Browser notifications not supported');
901939
return;
902940
}
903941

942+
// Set initial button state
943+
this.updateNotificationButtonState();
944+
945+
// Add click handler for notification button
946+
this.notificationButton.addEventListener('click', () => {
947+
this.requestNotificationPermission();
948+
});
949+
950+
// Check if we're in a PWA context
951+
const isPWA = window.matchMedia('(display-mode: standalone)').matches ||
952+
window.navigator.standalone === true;
953+
954+
if (isPWA) {
955+
this.addSystemMessage('Running in PWA mode - notifications should work better');
956+
} else {
957+
this.addSystemMessage('For best notification support on mobile, add this app to your home screen');
958+
}
959+
}
960+
961+
updateNotificationButtonState() {
962+
const permission = Notification.permission;
963+
964+
if (permission === 'granted') {
965+
this.notificationButton.className = 'notification-button enabled';
966+
this.notificationButton.title = 'Notifications enabled';
967+
this.notificationButton.textContent = '🔔';
968+
this.notificationsEnabled = true;
969+
} else if (permission === 'denied') {
970+
this.notificationButton.className = 'notification-button disabled';
971+
this.notificationButton.title = 'Notifications blocked - enable in browser settings';
972+
this.notificationButton.textContent = '🔕';
973+
this.notificationsEnabled = false;
974+
} else if (permission === 'default') {
975+
this.notificationButton.className = 'notification-button';
976+
this.notificationButton.title = 'Click to request notification permission';
977+
this.notificationButton.textContent = '🔔';
978+
this.notificationsEnabled = false;
979+
} else {
980+
this.notificationButton.className = 'notification-button';
981+
this.notificationButton.title = `Unknown permission state: ${permission}`;
982+
this.notificationButton.textContent = '🔔';
983+
this.notificationsEnabled = false;
984+
}
985+
986+
// Log state for debugging
987+
console.log('Button state updated:', permission, this.notificationsEnabled);
988+
}
989+
990+
async requestNotificationPermission() {
991+
if (!('Notification' in window)) {
992+
this.addSystemMessage('Browser notifications not supported');
993+
return;
994+
}
995+
996+
// Log current permission state for debugging
997+
console.log('Current notification permission:', Notification.permission);
998+
this.addSystemMessage(`Current permission state: ${Notification.permission}`);
999+
1000+
// If already granted, just update state
9041001
if (Notification.permission === 'granted') {
9051002
this.notificationsEnabled = true;
906-
this.addSystemMessage('Browser notifications enabled');
1003+
this.updateNotificationButtonState();
1004+
this.addSystemMessage('Notifications are already enabled');
9071005
return;
9081006
}
9091007

910-
if (Notification.permission !== 'denied') {
1008+
// If denied, show instruction message
1009+
if (Notification.permission === 'denied') {
1010+
this.addSystemMessage('Notifications are blocked. Please enable them in your browser settings and reload the page.');
1011+
return;
1012+
}
1013+
1014+
// For 'default' state (ask to allow), request permission
1015+
if (Notification.permission === 'default') {
1016+
this.addSystemMessage('Requesting notification permission...');
1017+
1018+
// Request permission (this must be user-initiated)
9111019
try {
912-
const permission = await Notification.requestPermission();
1020+
let permission;
1021+
1022+
// Try different methods for different browsers
1023+
if (Notification.requestPermission.length === 0) {
1024+
// Modern Promise-based API
1025+
permission = await Notification.requestPermission();
1026+
} else {
1027+
// Older callback-based API (fallback for some mobile browsers)
1028+
permission = await new Promise((resolve) => {
1029+
Notification.requestPermission(resolve);
1030+
});
1031+
}
1032+
1033+
console.log('Permission result:', permission);
1034+
this.addSystemMessage(`Permission result: ${permission}`);
1035+
9131036
if (permission === 'granted') {
9141037
this.notificationsEnabled = true;
915-
this.addSystemMessage('Browser notifications enabled');
1038+
this.addSystemMessage('Notifications enabled successfully!');
1039+
1040+
// Test notification
1041+
setTimeout(() => {
1042+
this.createNotification('System', 'Notifications are now working!', false);
1043+
}, 1000);
1044+
} else if (permission === 'denied') {
1045+
this.addSystemMessage('Notification permission denied by user');
9161046
} else {
917-
this.addSystemMessage('Browser notifications disabled');
1047+
this.addSystemMessage('Notification permission not granted (unknown state)');
9181048
}
1049+
1050+
this.updateNotificationButtonState();
1051+
9191052
} catch (error) {
9201053
console.error('Error requesting notification permission:', error);
921-
this.addSystemMessage('Failed to request notification permission');
1054+
this.addSystemMessage(`Permission request failed: ${error.message}`);
1055+
1056+
// For mobile browsers that don't support requestPermission()
1057+
if (error.name === 'NotAllowedError') {
1058+
this.addSystemMessage('NotAllowedError - Permission blocked by browser policy');
1059+
} else if (error.message.includes('user gesture')) {
1060+
this.addSystemMessage('User gesture required - try clicking the button again');
1061+
} else {
1062+
this.addSystemMessage('This may be due to browser restrictions on mobile - try adding to home screen');
1063+
}
9221064
}
9231065
} else {
924-
this.addSystemMessage('Browser notifications blocked');
1066+
this.addSystemMessage(`Unexpected permission state: ${Notification.permission}`);
9251067
}
9261068
}
9271069

@@ -930,31 +1072,85 @@
9301072
return; // Don't show notifications for our own messages
9311073
}
9321074

1075+
// Double-check permission before creating notification
1076+
if (Notification.permission !== 'granted') {
1077+
console.log('Notification permission not granted, skipping notification');
1078+
return;
1079+
}
1080+
9331081
try {
9341082
const title = isReply ? `${sender} replied in RetroChat` : `${sender} in RetroChat`;
9351083
const body = text.length > 100 ? text.substring(0, 100) + '...' : text;
9361084

937-
const notification = new Notification(title, {
1085+
// Enhanced notification options for better mobile support
1086+
const options = {
9381087
body: body,
9391088
tag: 'retro-chat-message',
1089+
icon: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5NiIgaGVpZ2h0PSI5NiIgdmlld0JveD0iMCAwIDk2IDk2Ij4KICA8cmVjdCB3aWR0aD0iOTYiIGhlaWdodD0iOTYiIGZpbGw9IiMwMDAiLz4KICA8dGV4dCB4PSI0OCIgeT0iNTgiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZpbGw9IiMwMGZmMDAiIGZvbnQtZmFtaWx5PSJtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMzIiIGZvbnQtd2VpZ2h0PSJib2xkIj5SQzwvdGV4dD4KPC9zdmc+',
1090+
badge: 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI3MiIgaGVpZ2h0PSI3MiIgdmlld0JveD0iMCAwIDcyIDcyIj4KICA8cmVjdCB3aWR0aD0iNzIiIGhlaWdodD0iNzIiIGZpbGw9IiMwMGZmMDAiLz4KICA8dGV4dCB4PSIzNiIgeT0iNDUiIHRleHQtYW5jaG9yPSJtaWRkbGUiIGZpbGw9IiMwMDAiIGZvbnQtZmFtaWx5PSJtb25vc3BhY2UiIGZvbnQtc2l6ZT0iMjQiIGZvbnQtd2VpZ2h0PSJib2xkIj5SQzwvdGV4dD4KPC9zdmc+',
9401091
requireInteraction: false,
941-
silent: false
942-
});
1092+
silent: false,
1093+
timestamp: Date.now(),
1094+
data: {
1095+
sender: sender,
1096+
text: text,
1097+
isReply: isReply,
1098+
timestamp: Date.now()
1099+
}
1100+
};
1101+
1102+
const notification = new Notification(title, options);
9431103

944-
// Auto-close notification after 5 seconds
1104+
// Auto-close notification after 8 seconds (longer for mobile)
9451105
setTimeout(() => {
946-
notification.close();
947-
}, 5000);
1106+
try {
1107+
notification.close();
1108+
} catch (e) {
1109+
// Ignore if already closed
1110+
}
1111+
}, 8000);
9481112

9491113
// Focus window when notification is clicked
9501114
notification.onclick = () => {
951-
window.focus();
952-
notification.close();
1115+
try {
1116+
window.focus();
1117+
notification.close();
1118+
1119+
// Try to bring the window to foreground on mobile
1120+
if (document.visibilityState === 'hidden') {
1121+
// App was backgrounded, try to focus
1122+
document.addEventListener('visibilitychange', function focusOnceVisible() {
1123+
if (document.visibilityState === 'visible') {
1124+
window.focus();
1125+
document.removeEventListener('visibilitychange', focusOnceVisible);
1126+
}
1127+
}, { once: true });
1128+
}
1129+
} catch (e) {
1130+
console.log('Error handling notification click:', e);
1131+
}
1132+
};
1133+
1134+
// Handle notification error
1135+
notification.onerror = (error) => {
1136+
console.error('Notification error:', error);
1137+
this.addSystemMessage('Notification failed to display');
9531138
};
9541139

1140+
console.log('Notification created successfully');
1141+
9551142
} catch (error) {
9561143
console.error('Error creating notification:', error);
9571144
console.error('Error details:', error.message);
1145+
1146+
// Provide specific error feedback
1147+
if (error.name === 'NotAllowedError') {
1148+
this.addSystemMessage('Notifications blocked by browser');
1149+
} else if (error.message.includes('ServiceWorker')) {
1150+
this.addSystemMessage('Notification failed: Service Worker issue');
1151+
} else {
1152+
this.addSystemMessage('Notification failed: ' + error.message);
1153+
}
9581154
}
9591155
}
9601156

@@ -987,6 +1183,9 @@
9871183
this.replyText = document.getElementById('replyText');
9881184
this.cancelReplyButton = document.getElementById('cancelReply');
9891185

1186+
// Notification button element
1187+
this.notificationButton = document.getElementById('notificationButton');
1188+
9901189
// Set the generated nickname in the input field
9911190
this.nicknameInput.value = this.nickname;
9921191
}

0 commit comments

Comments
 (0)