Skip to content

Commit 749f740

Browse files
authored
Merge pull request #19 from murdercode/casio-theme
Casio theme
2 parents 7b19f6e + 7dfddf3 commit 749f740

File tree

12 files changed

+227
-21
lines changed

12 files changed

+227
-21
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ tempo/
120120
### Backend (Rust/Tauri)
121121
- **Tauri framework**: Secure, fast native app wrapper
122122
- **File-based storage**: JSON files for data persistence
123-
- **Cross-platform**: Works on Windows, macOS, and Linux
124123
- **Small bundle size**: Efficient Rust backend
124+
<br /><strike>- **Cross-platform**: Works on Windows, macOS, and Linux</strike>
125125

126126
### Data Persistence
127127
The application stores data in the following locations:
@@ -163,9 +163,9 @@ The Pomodoro Technique is a time management method developed by Francesco Cirill
163163

164164
## 📱 Platform Support
165165

166-
- **Windows** (7, 8, 10, 11)
167166
- **macOS** (10.13+)
168-
- **Linux** (Ubuntu 18.04+, and other distributions)
167+
- _**Windows** (coming soon TBA)_
168+
- _**Linux** (coming soon TBA)_
169169

170170
## 🤝 Contributing
171171

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "presto",
33
"private": true,
4-
"version": "0.2.12",
4+
"version": "0.2.13",
55
"type": "module",
66
"scripts": {
77
"tauri": "tauri",

src-tauri/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "presto"
3-
version = "0.2.12"
3+
version = "0.2.13"
44
description = "A Tauri App"
55
authors = ["Stefano Novelli"]
66
edition = "2021"

src-tauri/tauri.conf.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"$schema": "https://schema.tauri.app/config/2",
33
"productName": "presto",
4-
"version": "0.2.12",
4+
"version": "0.2.13",
55
"identifier": "com.presto.app",
66
"build": {
77
"frontendDist": "../src"

src/managers/navigation-manager.js

Lines changed: 115 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ export class NavigationManager {
88
this.initialized = false;
99
this.currentTooltip = null; // Track current tooltip for proper cleanup
1010
this.tooltipTimeout = null; // Track timeout for debounced tooltip removal
11+
12+
// Apply timer-active class on initial load since default view is timer
13+
document.body.classList.add('timer-active');
14+
document.documentElement.classList.add('timer-active');
1115
}
1216

1317
async init() {
@@ -57,14 +61,18 @@ export class NavigationManager {
5761

5862
// Handle background based on view
5963
const body = document.body;
64+
const html = document.documentElement;
6065
if (view === 'timer') {
61-
// Timer view - reapply timer background by triggering display update
66+
// Timer view - add timer-active class to prevent scrolling and reapply timer background
67+
body.classList.add('timer-active');
68+
html.classList.add('timer-active');
6269
if (window.pomodoroTimer) {
6370
window.pomodoroTimer.updateDisplay();
6471
}
6572
} else {
66-
// Non-timer views - remove timer background classes and apply default background
67-
body.classList.remove('focus', 'break', 'longBreak');
73+
// Non-timer views - remove timer-active class to allow scrolling and remove timer background classes
74+
body.classList.remove('timer-active', 'focus', 'break', 'longBreak');
75+
html.classList.remove('timer-active');
6876
}
6977

7078
// Initialize view-specific content
@@ -1037,16 +1045,28 @@ export class NavigationManager {
10371045

10381046
const offsetX = e.clientX - sessionRect.left;
10391047

1048+
// Create drag time tooltip
1049+
const dragTooltip = this.createDragTimeTooltip();
1050+
document.body.appendChild(dragTooltip);
1051+
10401052
const handleMouseMove = (e) => {
10411053
const x = e.clientX - timelineRect.left - offsetX;
10421054
const percentage = Math.max(0, Math.min(100, (x / timelineRect.width) * 100));
10431055
sessionElement.style.left = `${percentage}%`;
1056+
1057+
// Update tooltip with current time
1058+
this.updateDragTooltip(dragTooltip, e, percentage, session);
10441059
};
10451060

10461061
const handleMouseUp = () => {
10471062
sessionElement.classList.remove('dragging');
10481063
document.removeEventListener('mousemove', handleMouseMove);
10491064
document.removeEventListener('mouseup', handleMouseUp);
1065+
1066+
// Remove tooltip
1067+
if (dragTooltip && dragTooltip.parentNode) {
1068+
dragTooltip.parentNode.removeChild(dragTooltip);
1069+
}
10501070

10511071
// Update session time based on new position
10521072
this.updateSessionTimeFromPosition(sessionElement, session);
@@ -1063,6 +1083,10 @@ export class NavigationManager {
10631083
const timeline = document.getElementById('timeline-track');
10641084
const timelineRect = timeline.getBoundingClientRect();
10651085

1086+
// Create resize time tooltip
1087+
const resizeTooltip = this.createDragTimeTooltip();
1088+
document.body.appendChild(resizeTooltip);
1089+
10661090
const handleMouseMove = (e) => {
10671091
const x = e.clientX - timelineRect.left;
10681092
const percentage = Math.max(0, Math.min(100, (x / timelineRect.width) * 100));
@@ -1080,12 +1104,20 @@ export class NavigationManager {
10801104
const newWidth = Math.max(2, percentage - currentLeft); // Minimum 2% width
10811105
sessionElement.style.width = `${newWidth}%`;
10821106
}
1107+
1108+
// Update tooltip with current time range
1109+
this.updateResizeTooltip(resizeTooltip, e, sessionElement);
10831110
};
10841111

10851112
const handleMouseUp = () => {
10861113
sessionElement.classList.remove('resizing');
10871114
document.removeEventListener('mousemove', handleMouseMove);
10881115
document.removeEventListener('mouseup', handleMouseUp);
1116+
1117+
// Remove tooltip
1118+
if (resizeTooltip && resizeTooltip.parentNode) {
1119+
resizeTooltip.parentNode.removeChild(resizeTooltip);
1120+
}
10891121

10901122
// Update session time based on new size and position
10911123
this.updateSessionTimeFromPosition(sessionElement, session);
@@ -1136,14 +1168,10 @@ export class NavigationManager {
11361168

11371169
// Save changes if using SessionManager
11381170
if (window.sessionManager && !session.isHistorical) {
1139-
// Update the session in SessionManager
1140-
const dateString = this.currentDate.toDateString();
1141-
if (window.sessionManager.sessions[dateString]) {
1142-
const sessionIndex = window.sessionManager.sessions[dateString].findIndex(s => s.id === session.id);
1143-
if (sessionIndex !== -1) {
1144-
window.sessionManager.sessions[dateString][sessionIndex] = { ...session };
1145-
}
1146-
}
1171+
// Set the selected date for SessionManager
1172+
window.sessionManager.selectedDate = this.currentDate;
1173+
// Use the proper updateSession method to ensure persistence
1174+
window.sessionManager.updateSession(session);
11471175
}
11481176
}
11491177

@@ -1255,6 +1283,82 @@ export class NavigationManager {
12551283
this.currentTooltip = null;
12561284
}
12571285

1286+
createDragTimeTooltip() {
1287+
const tooltip = document.createElement('div');
1288+
tooltip.className = 'drag-time-tooltip';
1289+
tooltip.style.cssText = `
1290+
position: fixed;
1291+
background: var(--shared-text);
1292+
color: var(--card-bg);
1293+
padding: 8px 12px;
1294+
border-radius: 6px;
1295+
font-size: 0.85rem;
1296+
font-weight: 600;
1297+
white-space: nowrap;
1298+
z-index: 10000;
1299+
pointer-events: none;
1300+
box-shadow: 0 4px 12px var(--shared-border);
1301+
opacity: 0;
1302+
transition: opacity 0.2s ease;
1303+
`;
1304+
return tooltip;
1305+
}
1306+
1307+
updateDragTooltip(tooltip, mouseEvent, percentage, session) {
1308+
// Calculate time from percentage
1309+
const timelineStartMinutes = 6 * 60; // 6 AM
1310+
const timelineRangeMinutes = 16 * 60; // 16 hours (6 AM to 10 PM)
1311+
const widthPercent = parseFloat(session.duration) / timelineRangeMinutes * 100;
1312+
1313+
const startMinutes = timelineStartMinutes + (percentage / 100) * timelineRangeMinutes;
1314+
const endMinutes = startMinutes + (session.duration || 25); // Default 25 min if no duration
1315+
1316+
const startHour = Math.floor(startMinutes / 60);
1317+
const startMin = Math.round(startMinutes % 60);
1318+
const endHour = Math.floor(endMinutes / 60);
1319+
const endMin = Math.round(endMinutes % 60);
1320+
1321+
const startTime = `${startHour.toString().padStart(2, '0')}:${startMin.toString().padStart(2, '0')}`;
1322+
const endTime = `${endHour.toString().padStart(2, '0')}:${endMin.toString().padStart(2, '0')}`;
1323+
1324+
tooltip.textContent = `${startTime} - ${endTime}`;
1325+
1326+
// Position tooltip near mouse
1327+
tooltip.style.left = `${mouseEvent.clientX + 15}px`;
1328+
tooltip.style.top = `${mouseEvent.clientY - 35}px`;
1329+
tooltip.style.opacity = '1';
1330+
}
1331+
1332+
updateResizeTooltip(tooltip, mouseEvent, sessionElement) {
1333+
const leftPercent = parseFloat(sessionElement.style.left);
1334+
const widthPercent = parseFloat(sessionElement.style.width);
1335+
const rightPercent = leftPercent + widthPercent;
1336+
1337+
// Convert percentages to time (6 AM to 10 PM range)
1338+
const timelineStartMinutes = 6 * 60; // 6 AM
1339+
const timelineRangeMinutes = 16 * 60; // 16 hours
1340+
1341+
const startMinutes = timelineStartMinutes + (leftPercent / 100) * timelineRangeMinutes;
1342+
const endMinutes = timelineStartMinutes + (rightPercent / 100) * timelineRangeMinutes;
1343+
const durationMinutes = endMinutes - startMinutes;
1344+
1345+
const startHour = Math.floor(startMinutes / 60);
1346+
const startMin = Math.round(startMinutes % 60);
1347+
const endHour = Math.floor(endMinutes / 60);
1348+
const endMin = Math.round(endMinutes % 60);
1349+
1350+
const startTime = `${startHour.toString().padStart(2, '0')}:${startMin.toString().padStart(2, '0')}`;
1351+
const endTime = `${endHour.toString().padStart(2, '0')}:${endMin.toString().padStart(2, '0')}`;
1352+
const duration = `${Math.round(durationMinutes)}min`;
1353+
1354+
tooltip.textContent = `${startTime} - ${endTime} (${duration})`;
1355+
1356+
// Position tooltip near mouse
1357+
tooltip.style.left = `${mouseEvent.clientX + 15}px`;
1358+
tooltip.style.top = `${mouseEvent.clientY - 35}px`;
1359+
tooltip.style.opacity = '1';
1360+
}
1361+
12581362
calculateSessionOffset(session, allSessions) {
12591363
if (!allSessions || allSessions.length <= 1) return 0;
12601364

src/managers/session-manager.js

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,34 @@ export class SessionManager {
1111
}
1212

1313
init() {
14+
this.loadSessionsFromStorage();
1415
this.setupEventListeners();
1516
}
1617

18+
// Load sessions from localStorage
19+
loadSessionsFromStorage() {
20+
try {
21+
const savedSessions = localStorage.getItem('presto_manual_sessions');
22+
if (savedSessions) {
23+
this.sessions = JSON.parse(savedSessions);
24+
console.log('Loaded', this.sessions.length, 'manual sessions from storage');
25+
}
26+
} catch (error) {
27+
console.error('Error loading sessions from storage:', error);
28+
this.sessions = [];
29+
}
30+
}
31+
32+
// Save sessions to localStorage
33+
saveSessionsToStorage() {
34+
try {
35+
localStorage.setItem('presto_manual_sessions', JSON.stringify(this.sessions));
36+
console.log('Saved', this.sessions.length, 'manual sessions to storage');
37+
} catch (error) {
38+
console.error('Error saving sessions to storage:', error);
39+
}
40+
}
41+
1742
setupEventListeners() {
1843
// Add session button
1944
const addSessionBtn = document.getElementById('add-session-btn');
@@ -220,6 +245,9 @@ export class SessionManager {
220245
}
221246

222247
this.sessions[dateString].push(sessionData);
248+
249+
// Save to localStorage
250+
this.saveSessionsToStorage();
223251

224252
// TODO: Call backend when available
225253
// await invoke('add_session', { date: dateString, session: sessionData });
@@ -236,6 +264,9 @@ export class SessionManager {
236264
}
237265
}
238266

267+
// Save to localStorage
268+
this.saveSessionsToStorage();
269+
239270
// TODO: Call backend when available
240271
// await invoke('update_session', { date: dateString, sessionId: sessionData.id, updatedSession: sessionData });
241272
}
@@ -253,6 +284,9 @@ export class SessionManager {
253284
this.sessions[dateString] = this.sessions[dateString].filter(s => s.id !== this.currentEditingSession.id);
254285
}
255286

287+
// Save to localStorage
288+
this.saveSessionsToStorage();
289+
256290
// TODO: Call backend when available
257291
// await invoke('delete_session', { date: dateString, sessionId: this.currentEditingSession.id });
258292

src/styles/calendar.css

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,4 +572,50 @@
572572
font-weight: 600;
573573
}
574574

575+
/* Sessions Header Styles */
576+
.sessions-header {
577+
display: flex;
578+
align-items: center;
579+
justify-content: space-between;
580+
margin-bottom: 0.75rem;
581+
}
582+
583+
.sessions-header h4 {
584+
margin: 0;
585+
color: var(--accent-color);
586+
font-size: 0.95rem;
587+
font-weight: 600;
588+
}
589+
590+
.add-session-btn {
591+
width: 32px;
592+
height: 32px;
593+
border: none;
594+
border-radius: 50%;
595+
background: var(--accent-color);
596+
color: var(--text-on-focus);
597+
cursor: pointer;
598+
display: flex;
599+
align-items: center;
600+
justify-content: center;
601+
transition: all 0.3s ease;
602+
box-shadow: 0 2px 4px var(--shared-border);
603+
}
604+
605+
.add-session-btn:hover {
606+
background: var(--focus-timer-color);
607+
transform: scale(1.1);
608+
box-shadow: 0 4px 8px var(--shared-border);
609+
}
610+
611+
.add-session-btn:active {
612+
transform: scale(0.95);
613+
}
614+
615+
.add-session-btn svg {
616+
width: 16px;
617+
height: 16px;
618+
stroke-width: 2.5;
619+
}
620+
575621
/* Theme support is now handled through CSS variables in individual theme files */

src/styles/layout.css

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,28 @@ body {
55
padding: 0;
66
}
77

8+
/* Timer view specific - prevent scrolling */
9+
body.timer-active {
10+
overflow: hidden;
11+
height: 100vh;
12+
}
13+
14+
html.timer-active {
15+
overflow: hidden;
16+
height: 100vh;
17+
}
18+
19+
/* Non-timer views - ensure scrolling is allowed */
20+
body:not(.timer-active) {
21+
overflow: auto;
22+
height: auto;
23+
}
24+
25+
html:not(.timer-active) {
26+
overflow: auto;
27+
height: auto;
28+
}
29+
830
/* Timer background states - applied to body when timer is active */
931
/* These styles have higher specificity and will override the default background */
1032
body.focus {

0 commit comments

Comments
 (0)