Skip to content

Commit d665a93

Browse files
authored
Merge pull request #42 from murdercode/39-bug-menu-bar-item-context-menu-is-stuck-in-italian
39 bug menu bar item context menu is stuck in italian
2 parents 214498c + 3f52ed8 commit d665a93

File tree

6 files changed

+413
-54
lines changed

6 files changed

+413
-54
lines changed

src-tauri/src/lib.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -968,19 +968,19 @@ pub fn run() {
968968
});
969969

970970
let show_item =
971-
MenuItem::with_id(app, "show", "Mostra Presto", true, None::<&str>)?;
971+
MenuItem::with_id(app, "show", "Show Presto", true, None::<&str>)?;
972972
let start_session_item = MenuItem::with_id(
973973
app,
974974
"start_session",
975-
"Inizia sessione",
975+
"Start Session",
976976
false,
977977
None::<&str>,
978978
)?;
979-
let pause_item = MenuItem::with_id(app, "pause", "Pausa", false, None::<&str>)?;
979+
let pause_item = MenuItem::with_id(app, "pause", "Pause", false, None::<&str>)?;
980980
let skip_item =
981-
MenuItem::with_id(app, "skip", "Salta sessione", false, None::<&str>)?;
982-
let cancel_item = MenuItem::with_id(app, "cancel", "Annulla", false, None::<&str>)?;
983-
let quit_item = MenuItem::with_id(app, "quit", "Esci", true, None::<&str>)?;
981+
MenuItem::with_id(app, "skip", "Skip Session", false, None::<&str>)?;
982+
let cancel_item = MenuItem::with_id(app, "cancel", "Cancel", false, None::<&str>)?;
983+
let quit_item = MenuItem::with_id(app, "quit", "Quit", true, None::<&str>)?;
984984
let menu = Menu::with_items(
985985
app,
986986
&[
@@ -1285,43 +1285,43 @@ async fn update_tray_menu(
12851285
let tray = app.tray_by_id("main");
12861286

12871287
if let Some(tray) = tray {
1288-
let show_item = MenuItem::with_id(&app, "show", "Mostra Presto", true, None::<&str>)
1288+
let show_item = MenuItem::with_id(&app, "show", "Show Presto", true, None::<&str>)
12891289
.map_err(|e| format!("Failed to create show item: {}", e))?;
12901290

1291-
// Inizia sessione: abilitato solo se non è in esecuzione
1291+
// Start Session: enabled only if not running
12921292
let start_session_item = MenuItem::with_id(
12931293
&app,
12941294
"start_session",
1295-
"Inizia sessione",
1295+
"Start Session",
12961296
!is_running,
12971297
None::<&str>,
12981298
)
12991299
.map_err(|e| format!("Failed to create start session item: {}", e))?;
13001300

1301-
// Pausa: abilitata solo se è in esecuzione e non in pausa
1301+
// Pause: enabled only if running and not paused
13021302
let pause_item = MenuItem::with_id(
13031303
&app,
13041304
"pause",
1305-
"Pausa",
1305+
"Pause",
13061306
is_running && !is_paused,
13071307
None::<&str>,
13081308
)
13091309
.map_err(|e| format!("Failed to create pause item: {}", e))?;
13101310

1311-
// Skip: abilitato solo se è in esecuzione
1312-
let skip_item = MenuItem::with_id(&app, "skip", "Salta sessione", is_running, None::<&str>)
1311+
// Skip: enabled only if running
1312+
let skip_item = MenuItem::with_id(&app, "skip", "Skip Session", is_running, None::<&str>)
13131313
.map_err(|e| format!("Failed to create skip item: {}", e))?;
13141314

1315-
// Annulla: abilitato se è in modalità focus, disabilitato in break/longBreak (undo)
1315+
// Cancel: enabled if in focus mode, disabled in break/longBreak (undo)
13161316
let cancel_text = if current_mode == "focus" {
1317-
"Annulla"
1317+
"Cancel"
13181318
} else {
1319-
"Annulla ultima"
1319+
"Cancel Last"
13201320
};
13211321
let cancel_item = MenuItem::with_id(&app, "cancel", cancel_text, true, None::<&str>)
13221322
.map_err(|e| format!("Failed to create cancel item: {}", e))?;
13231323

1324-
let quit_item = MenuItem::with_id(&app, "quit", "Esci", true, None::<&str>)
1324+
let quit_item = MenuItem::with_id(&app, "quit", "Quit", true, None::<&str>)
13251325
.map_err(|e| format!("Failed to create quit item: {}", e))?;
13261326

13271327
let new_menu = Menu::with_items(

src/core/pomodoro-timer.js

Lines changed: 197 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -778,10 +778,12 @@ export class PomodoroTimer {
778778
);
779779

780780
// Show desktop notification if enabled
781-
NotificationUtils.showDesktopNotification(
782-
'Session Time Limit Reached',
783-
`Your session has been automatically paused after ${maxTimeInMinutes} minutes. Consider taking a break!`
784-
);
781+
if (this.enableDesktopNotifications) {
782+
NotificationUtils.showDesktopNotification(
783+
'Session Time Limit Reached',
784+
`Your session has been automatically paused after ${maxTimeInMinutes} minutes. Consider taking a break!`
785+
);
786+
}
785787
}
786788
}
787789

@@ -2297,56 +2299,222 @@ export class PomodoroTimer {
22972299
}
22982300
}
22992301

2300-
// Simple notification system
2302+
// Enhanced notification system with better error handling and debugging
23012303
async showNotification() {
2304+
// Only show desktop notifications if the setting is enabled
2305+
if (!this.enableDesktopNotifications) {
2306+
console.log('🔔 Desktop notifications are disabled in settings');
2307+
return;
2308+
}
2309+
2310+
const messages = {
2311+
focus: 'Break time! Take a rest 😌',
2312+
break: 'Break over! Time to focus 🍅',
2313+
longBreak: 'Long break over! Ready for more focus? 🚀'
2314+
};
2315+
2316+
const notificationTitle = 'Presto - Pomodoro Timer';
2317+
const notificationBody = messages[this.currentMode];
2318+
2319+
console.log(`🔔 Attempting to show desktop notification: "${notificationBody}"`);
2320+
23022321
try {
23032322
// Check if we're in a Tauri context and use Tauri notifications
23042323
if (window.__TAURI__ && window.__TAURI__.notification) {
2324+
console.log('🔔 Using Tauri notification system');
23052325
const { isPermissionGranted, requestPermission, sendNotification } = window.__TAURI__.notification;
23062326

23072327
// Check if permission is granted
23082328
let permissionGranted = await isPermissionGranted();
2329+
console.log(`🔔 Tauri notification permission status: ${permissionGranted}`);
23092330

23102331
// If not granted, request permission
23112332
if (!permissionGranted) {
2333+
console.log('🔔 Requesting Tauri notification permission...');
23122334
const permission = await requestPermission();
23132335
permissionGranted = permission === 'granted';
2336+
console.log(`🔔 Permission request result: ${permission} (granted: ${permissionGranted})`);
2337+
2338+
if (!permissionGranted) {
2339+
console.warn('❌ Tauri notification permission was denied');
2340+
NotificationUtils.showNotificationPing('Desktop notifications are disabled. Enable them in system settings to get timer alerts! 🔔', 'warning', this.currentMode);
2341+
return;
2342+
}
23142343
}
23152344

23162345
// Send notification if permission is granted
23172346
if (permissionGranted) {
2318-
const messages = {
2319-
focus: 'Break time! Take a rest 😌',
2320-
break: 'Break over! Time to focus 🍅',
2321-
longBreak: 'Long break over! Ready for more focus? 🚀'
2322-
};
2323-
2347+
console.log('🔔 Sending Tauri notification...');
23242348
await sendNotification({
2325-
title: 'Presto - Pomodoro Timer',
2326-
body: messages[this.currentMode],
2349+
title: notificationTitle,
2350+
body: notificationBody,
23272351
icon: '/assets/tauri.svg'
23282352
});
2353+
console.log('✅ Tauri notification sent successfully');
2354+
} else {
2355+
console.warn('❌ Tauri notification permission not available');
2356+
this.fallbackToWebNotifications(notificationTitle, notificationBody);
23292357
}
23302358
} else {
2331-
// Fallback to Web Notification API
2332-
if ('Notification' in window && Notification.permission === 'granted') {
2333-
const messages = {
2334-
focus: 'Break time! Take a rest 😌',
2335-
break: 'Break over! Time to focus 🍅',
2336-
longBreak: 'Long break over! Ready for more focus? 🚀'
2337-
};
2338-
2339-
NotificationUtils.showDesktopNotification('Presto - Pomodoro Timer', messages[this.currentMode]);
2359+
console.log('🔔 Tauri not available, falling back to Web Notification API');
2360+
this.fallbackToWebNotifications(notificationTitle, notificationBody);
2361+
}
2362+
} catch (error) {
2363+
console.error('❌ Failed to show Tauri notification:', error);
2364+
console.log('🔄 Attempting fallback to Web Notification API...');
2365+
this.fallbackToWebNotifications(notificationTitle, notificationBody);
2366+
}
2367+
}
2368+
2369+
// Fallback to Web Notification API with improved error handling
2370+
async fallbackToWebNotifications(title, body) {
2371+
try {
2372+
if ('Notification' in window) {
2373+
console.log(`🔔 Web Notification API available, permission: ${Notification.permission}`);
2374+
2375+
if (Notification.permission === 'granted') {
2376+
console.log('🔔 Sending Web notification...');
2377+
NotificationUtils.showDesktopNotification(title, body);
2378+
console.log('✅ Web notification sent successfully');
2379+
} else if (Notification.permission === 'default') {
2380+
console.log('🔔 Requesting Web notification permission...');
2381+
const permission = await Notification.requestPermission();
2382+
console.log(`🔔 Web permission request result: ${permission}`);
2383+
2384+
if (permission === 'granted') {
2385+
NotificationUtils.showDesktopNotification(title, body);
2386+
console.log('✅ Web notification sent after permission granted');
2387+
} else {
2388+
console.warn('❌ Web notification permission was denied');
2389+
NotificationUtils.showNotificationPing('Desktop notifications are disabled. Enable them in your browser to get timer alerts! 🔔', 'warning', this.currentMode);
2390+
}
2391+
} else {
2392+
console.warn('❌ Web notification permission was previously denied');
2393+
NotificationUtils.showNotificationPing('Desktop notifications are disabled. Enable them in your browser settings to get timer alerts! 🔔', 'warning', this.currentMode);
23402394
}
2395+
} else {
2396+
console.warn('❌ Web Notification API not supported');
2397+
this.fallbackToInAppNotification(body);
23412398
}
23422399
} catch (error) {
2343-
console.error('Failed to show notification:', error);
2344-
// Fallback to in-app notification
2345-
this.showNotificationPing(
2346-
this.currentMode === 'focus' ? 'Break time! Take a rest 😌' :
2347-
this.currentMode === 'break' ? 'Break over! Time to focus 🍅' :
2348-
'Long break over! Ready for more focus? 🚀'
2349-
);
2400+
console.error('❌ Failed to show Web notification:', error);
2401+
this.fallbackToInAppNotification(body);
2402+
}
2403+
}
2404+
2405+
// Final fallback to in-app notification
2406+
fallbackToInAppNotification(message) {
2407+
console.log('🔔 Using in-app notification as final fallback');
2408+
NotificationUtils.showNotificationPing(message, 'info', this.currentMode);
2409+
}
2410+
2411+
// Test notification function for debugging
2412+
// Usage: Open browser console and type: window.pomodoroTimer.testNotification()
2413+
async testNotification() {
2414+
console.log('🧪 Testing notification system...');
2415+
console.log('📝 Instructions: This will test the notification system and show debug info in the console');
2416+
console.log(`🔧 Current settings: desktop notifications = ${this.enableDesktopNotifications}`);
2417+
2418+
// Detect if we're in development mode
2419+
const isDevMode = window.location.protocol === 'tauri:' ? false : true;
2420+
const bundleId = 'com.presto.app';
2421+
2422+
console.log(`🔧 Environment: ${isDevMode ? 'Development (tauri dev)' : 'Production (built app)'}`);
2423+
console.log(`🔧 Bundle ID: ${bundleId}`);
2424+
2425+
if (isDevMode) {
2426+
console.log('⚠️ IMPORTANT: You\'re running in development mode (tauri dev)');
2427+
console.log('⚠️ On macOS, Tauri notifications often don\'t work in dev mode due to:');
2428+
console.log(' 1. Tauri uses Terminal.app for dev mode, which may not have notification permissions');
2429+
console.log(' 2. Bundle identifier is handled differently in dev vs production');
2430+
console.log(' 3. macOS requires proper app bundle registration for notifications');
2431+
console.log('');
2432+
console.log('🔧 To test notifications properly:');
2433+
console.log(' 1. Run: npm run tauri build');
2434+
console.log(' 2. Install the built app from src-tauri/target/release/bundle/');
2435+
console.log(' 3. Test notifications in the installed production app');
2436+
console.log('');
2437+
console.log('🔧 For dev mode, check Terminal.app permissions:');
2438+
console.log(' - System Preferences > Notifications & Focus > Terminal');
2439+
console.log(' - Make sure "Allow Notifications" is enabled');
2440+
console.log('');
2441+
}
2442+
2443+
// Show in-app notification first
2444+
NotificationUtils.showNotificationPing('Testing notification system... 🧪', 'info', this.currentMode);
2445+
2446+
// Test desktop notification
2447+
const originalSetting = this.enableDesktopNotifications;
2448+
this.enableDesktopNotifications = true; // Temporarily enable for testing
2449+
2450+
try {
2451+
await this.showNotification();
2452+
console.log('✅ Test notification API call completed - check console logs above for detailed debug info');
2453+
console.log('🔍 Look for messages starting with 🔔 for notification flow details');
2454+
2455+
if (isDevMode) {
2456+
console.log('');
2457+
console.log('⚠️ If you see "✅ Tauri notification sent successfully" but no notification appeared:');
2458+
console.log(' - This is NORMAL in development mode on macOS');
2459+
console.log(' - Test with a production build to verify notifications work');
2460+
console.log('');
2461+
console.log('🔄 Trying Web Notification API as fallback...');
2462+
await this.testWebNotificationFallback();
2463+
}
2464+
} catch (error) {
2465+
console.error('❌ Test notification failed:', error);
2466+
console.log('💡 Troubleshooting steps:');
2467+
if (isDevMode) {
2468+
console.log(' 1. This is likely due to dev mode limitations on macOS');
2469+
console.log(' 2. Check Terminal.app notification permissions in System Preferences');
2470+
console.log(' 3. Test with a production build: npm run tauri build');
2471+
} else {
2472+
console.log(' 1. Check if notifications are enabled in System Preferences > Notifications');
2473+
console.log(' 2. Look for "presto" or "com.presto.app" in the notifications list');
2474+
console.log(' 3. Ensure "Allow Notifications" is enabled for the app');
2475+
}
2476+
} finally {
2477+
// Restore original setting
2478+
this.enableDesktopNotifications = originalSetting;
2479+
}
2480+
}
2481+
2482+
// Test Web Notification API fallback
2483+
async testWebNotificationFallback() {
2484+
try {
2485+
if ('Notification' in window) {
2486+
console.log('🌐 Web Notification API available');
2487+
console.log(`🌐 Current permission: ${Notification.permission}`);
2488+
2489+
if (Notification.permission === 'default') {
2490+
console.log('🌐 Requesting Web notification permission...');
2491+
const permission = await Notification.requestPermission();
2492+
console.log(`🌐 Permission result: ${permission}`);
2493+
}
2494+
2495+
if (Notification.permission === 'granted') {
2496+
console.log('🌐 Sending Web notification...');
2497+
const notification = new Notification('Presto - Test Web Notification', {
2498+
body: 'This is a fallback Web notification test',
2499+
icon: '/assets/tauri.svg'
2500+
});
2501+
2502+
notification.onshow = () => console.log('✅ Web notification displayed');
2503+
notification.onerror = (error) => console.error('❌ Web notification error:', error);
2504+
2505+
// Auto-close after 5 seconds
2506+
setTimeout(() => {
2507+
notification.close();
2508+
console.log('🌐 Web notification closed automatically');
2509+
}, 5000);
2510+
} else {
2511+
console.log('❌ Web notification permission denied');
2512+
}
2513+
} else {
2514+
console.log('❌ Web Notification API not available');
2515+
}
2516+
} catch (error) {
2517+
console.error('❌ Web notification test failed:', error);
23502518
}
23512519
}
23522520

src/index.html

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -606,8 +606,12 @@ <h3>Notification Types</h3>
606606
Desktop Notifications
607607
</label>
608608
<p class="setting-description">Show system notifications when timer completes. Browser permission will
609-
be
610-
requested when enabled.</p>
609+
be requested when enabled.<br>
610+
<strong>Note:</strong> On macOS, notifications may not work in development mode. Test with a production build for full functionality.</p>
611+
<div id="notification-status" class="notification-status" style="margin-top: 8px; padding: 8px 12px; border-radius: 6px; font-size: 13px; display: none;">
612+
<span id="notification-status-text"></span>
613+
<button id="test-notifications-btn" style="margin-left: 8px; padding: 4px 8px; border: none; border-radius: 4px; font-size: 12px; cursor: pointer;">Test</button>
614+
</div>
611615
</div>
612616

613617
<div class="setting-item">

0 commit comments

Comments
 (0)