fix: Change UI language to English and fix notification toggle bug

Changes:
- Convert all Polish UI text to English (buttons, labels, messages)
  - Menu: "Powiadomienia" → "Notifications"
  - Status badges: "Włączone/Wyłączone/Zablokowane" → "Enabled/Disabled/Blocked"
  - Toast messages: all notification messages translated to English
  - Notification bodies: "Nowe: X kanały" → "New: X channels"

- Fix notification toggle UI bug
  - Badge now correctly shows "Disabled" when user turns off notifications
  - Previously showed "Enabled" whenever permission was granted (ignoring localStorage)
  - Now checks both permission AND localStorage state

This ensures the UI respects the international nature of the project
and fixes the toggle state display issue found during Android testing.

Files modified:
- app/templates/base.html
- app/static/js/app.js
- app/static/js/dm.js

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
MarekWo
2026-01-05 14:45:38 +01:00
parent ecb3618da7
commit 77c0a33da6
3 changed files with 21 additions and 19 deletions

View File

@@ -644,7 +644,7 @@ function setupAutoRefresh() {
*/
async function requestNotificationPermission() {
if (!('Notification' in window)) {
showNotification('Powiadomienia nie są obsługiwane w tej przeglądarce', 'warning');
showNotification('Notifications are not supported in this browser', 'warning');
return false;
}
@@ -654,17 +654,17 @@ async function requestNotificationPermission() {
if (permission === 'granted') {
localStorage.setItem('mc_notifications_enabled', 'true');
updateNotificationToggleUI();
showNotification('Powiadomienia zostały włączone', 'success');
showNotification('Notifications enabled', 'success');
return true;
} else if (permission === 'denied') {
localStorage.setItem('mc_notifications_enabled', 'false');
updateNotificationToggleUI();
showNotification('Powiadomienia zostały zablokowane. Zmień ustawienia przeglądarki aby je włączyć.', 'warning');
showNotification('Notifications blocked. Change browser settings to enable them.', 'warning');
return false;
}
} catch (error) {
console.error('Error requesting notification permission:', error);
showNotification('Błąd podczas włączania powiadomień', 'danger');
showNotification('Error enabling notifications', 'danger');
return false;
}
}
@@ -697,22 +697,24 @@ function updateNotificationToggleUI() {
if (!toggleBtn || !statusBadge) return;
const permission = getNotificationPermission();
const isEnabled = localStorage.getItem('mc_notifications_enabled') === 'true';
if (permission === 'unsupported') {
statusBadge.className = 'badge bg-secondary';
statusBadge.textContent = 'Niedostępne';
statusBadge.textContent = 'Unavailable';
toggleBtn.disabled = true;
} else if (permission === 'denied') {
statusBadge.className = 'badge bg-danger';
statusBadge.textContent = 'Zablokowane';
statusBadge.textContent = 'Blocked';
toggleBtn.disabled = false;
} else if (permission === 'granted') {
} else if (permission === 'granted' && isEnabled) {
statusBadge.className = 'badge bg-success';
statusBadge.textContent = 'Włączone';
statusBadge.textContent = 'Enabled';
toggleBtn.disabled = false;
} else {
// permission === 'default' OR (permission === 'granted' AND !isEnabled)
statusBadge.className = 'badge bg-secondary';
statusBadge.textContent = 'Wyłączone';
statusBadge.textContent = 'Disabled';
toggleBtn.disabled = false;
}
}
@@ -727,10 +729,10 @@ async function handleNotificationToggle() {
// Already granted - toggle off
localStorage.setItem('mc_notifications_enabled', 'false');
updateNotificationToggleUI();
showNotification('Powiadomienia zostały wyłączone', 'info');
showNotification('Notifications disabled', 'info');
} else if (permission === 'denied') {
// Blocked - show help message
showNotification('Powiadomienia są zablokowane. Zmień ustawienia w przeglądarce: Ustawienia → Strony → mc-webui → Powiadomienia', 'warning');
showNotification('Notifications are blocked. Change browser settings: Settings → Site Settings → Notifications', 'warning');
} else {
// Not yet requested - ask for permission
await requestNotificationPermission();
@@ -753,18 +755,18 @@ function sendBrowserNotification(channelCount, dmCount, pendingCount) {
const parts = [];
if (channelCount > 0) {
parts.push(`${channelCount} ${channelCount === 1 ? 'kanał' : 'kanały'}`);
parts.push(`${channelCount} ${channelCount === 1 ? 'channel' : 'channels'}`);
}
if (dmCount > 0) {
parts.push(`${dmCount} ${dmCount === 1 ? 'wiadomość prywatna' : 'wiadomości prywatne'}`);
parts.push(`${dmCount} ${dmCount === 1 ? 'private message' : 'private messages'}`);
}
if (pendingCount > 0) {
parts.push(`${pendingCount} ${pendingCount === 1 ? 'oczekujący kontakt' : 'oczekujące kontakty'}`);
parts.push(`${pendingCount} ${pendingCount === 1 ? 'pending contact' : 'pending contacts'}`);
}
if (parts.length === 0) return;
message = `Nowe: ${parts.join(', ')}`;
message = `New: ${parts.join(', ')}`;
try {
const notification = new Notification('mc-webui', {

View File

@@ -813,7 +813,7 @@ function checkDmNotifications(conversations) {
try {
const notification = new Notification('mc-webui', {
body: `Nowe wiadomości prywatne: ${delta}`,
body: `New private messages: ${delta}`,
icon: '/static/images/android-chrome-192x192.png',
badge: '/static/images/android-chrome-192x192.png',
tag: 'mc-webui-dm',

View File

@@ -68,11 +68,11 @@
<i class="bi bi-bell" style="font-size: 1.5rem;"></i>
<div class="flex-grow-1">
<div class="d-flex justify-content-between align-items-center">
<span>Powiadomienia</span>
<span id="notificationStatus" class="badge bg-secondary">Wyłączone</span>
<span>Notifications</span>
<span id="notificationStatus" class="badge bg-secondary">Disabled</span>
</div>
<small class="text-muted d-block mt-1" style="font-size: 0.75rem;">
Działa gdy app w tle
Works when app is hidden
</small>
</div>
</button>