Add pomodoro, microbreaks, breathing guide, screen dimming, presentation mode, goals, multi-monitor, and activity manager

This commit is contained in:
Your Name
2026-02-07 15:11:44 +02:00
parent 516524d76c
commit 6aac33b195
28 changed files with 3792 additions and 448 deletions

View File

@@ -11,7 +11,13 @@ export interface DaySchedule {
ranges: TimeRange[];
}
export type { TimeRange, DaySchedule };
export interface CustomActivity {
id: string;
category: string;
text: string;
is_favorite: boolean;
enabled: boolean;
}
export interface Config {
break_duration: number;
@@ -24,7 +30,7 @@ export interface Config {
allow_end_early: boolean;
immediately_start_breaks: boolean;
working_hours_enabled: boolean;
working_hours_schedule: DaySchedule[]; // 7 days: Mon, Tue, Wed, Thu, Fri, Sat, Sun
working_hours_schedule: DaySchedule[];
dark_mode: boolean;
color_scheme: string;
backdrop_opacity: number;
@@ -49,6 +55,45 @@ export interface Config {
background_blobs_enabled: boolean;
mini_click_through: boolean;
mini_hover_threshold: number;
// F8: Auto-start on login
auto_start_on_login: boolean;
// F6: Custom activities
custom_activities: CustomActivity[];
disabled_builtin_activities: string[];
favorite_builtin_activities: string[];
favorite_weight: number;
// F4: Breathing guide
breathing_guide_enabled: boolean;
breathing_pattern: string;
// F10: Gamification
daily_goal_enabled: boolean;
daily_goal_breaks: number;
milestone_celebrations: boolean;
streak_notifications: boolean;
// F1: Microbreaks
microbreak_enabled: boolean;
microbreak_frequency: number;
microbreak_duration: number;
microbreak_sound_enabled: boolean;
microbreak_show_activity: boolean;
microbreak_pause_during_break: boolean;
// F3: Pomodoro
pomodoro_enabled: boolean;
pomodoro_short_breaks: number;
pomodoro_long_break_duration: number;
pomodoro_long_break_title: string;
pomodoro_long_break_message: string;
pomodoro_reset_on_skip: boolean;
// F5: Screen dimming
screen_dim_enabled: boolean;
screen_dim_seconds: number;
screen_dim_max_opacity: number;
// F2: Presentation mode
presentation_mode_enabled: boolean;
presentation_mode_defer_microbreaks: boolean;
presentation_mode_notification: boolean;
// F9: Multi-monitor
multi_monitor_break: boolean;
}
const defaultConfig: Config = {
@@ -63,13 +108,13 @@ const defaultConfig: Config = {
immediately_start_breaks: false,
working_hours_enabled: false,
working_hours_schedule: [
{ enabled: true, ranges: [{ start: "09:00", end: "18:00" }] }, // Monday
{ enabled: true, ranges: [{ start: "09:00", end: "18:00" }] }, // Tuesday
{ enabled: true, ranges: [{ start: "09:00", end: "18:00" }] }, // Wednesday
{ enabled: true, ranges: [{ start: "09:00", end: "18:00" }] }, // Thursday
{ enabled: true, ranges: [{ start: "09:00", end: "18:00" }] }, // Friday
{ enabled: false, ranges: [{ start: "09:00", end: "18:00" }] }, // Saturday
{ enabled: false, ranges: [{ start: "09:00", end: "18:00" }] }, // Sunday
{ enabled: true, ranges: [{ start: "09:00", end: "18:00" }] },
{ enabled: true, ranges: [{ start: "09:00", end: "18:00" }] },
{ enabled: true, ranges: [{ start: "09:00", end: "18:00" }] },
{ enabled: true, ranges: [{ start: "09:00", end: "18:00" }] },
{ enabled: true, ranges: [{ start: "09:00", end: "18:00" }] },
{ enabled: false, ranges: [{ start: "09:00", end: "18:00" }] },
{ enabled: false, ranges: [{ start: "09:00", end: "18:00" }] },
],
dark_mode: true,
color_scheme: "Ocean",
@@ -95,6 +140,45 @@ const defaultConfig: Config = {
background_blobs_enabled: true,
mini_click_through: true,
mini_hover_threshold: 3.0,
// F8
auto_start_on_login: false,
// F6
custom_activities: [],
disabled_builtin_activities: [],
favorite_builtin_activities: [],
favorite_weight: 3,
// F4
breathing_guide_enabled: true,
breathing_pattern: "box",
// F10
daily_goal_enabled: true,
daily_goal_breaks: 8,
milestone_celebrations: true,
streak_notifications: true,
// F1
microbreak_enabled: false,
microbreak_frequency: 20,
microbreak_duration: 20,
microbreak_sound_enabled: true,
microbreak_show_activity: true,
microbreak_pause_during_break: true,
// F3
pomodoro_enabled: false,
pomodoro_short_breaks: 3,
pomodoro_long_break_duration: 15,
pomodoro_long_break_title: "Long break",
pomodoro_long_break_message: "Great work! Take a longer rest.",
pomodoro_reset_on_skip: false,
// F5
screen_dim_enabled: false,
screen_dim_seconds: 10,
screen_dim_max_opacity: 0.3,
// F2
presentation_mode_enabled: true,
presentation_mode_defer_microbreaks: true,
presentation_mode_notification: true,
// F9
multi_monitor_break: true,
};
export const config = writable<Config>(defaultConfig);

View File

@@ -26,6 +26,27 @@ export interface TimerSnapshot {
naturalBreakOccurred: boolean;
smartBreaksEnabled: boolean;
smartBreakThreshold: number;
// F1: Microbreaks
microbreakEnabled: boolean;
microbreakActive: boolean;
microbreakTimeRemaining: number;
microbreakTotalDuration: number;
microbreakCountdown: number;
microbreakFrequency: number;
// F3: Pomodoro
pomodoroEnabled: boolean;
pomodoroCyclePosition: number;
pomodoroTotalInCycle: number;
pomodoroIsLongBreak: boolean;
pomodoroNextIsLong: boolean;
// F5: Screen dimming
screenDimActive: boolean;
screenDimProgress: number;
// F2: Presentation mode
presentationModeActive: boolean;
deferredBreakPending: boolean;
// F10: Gamification
isLongBreak: boolean;
}
const defaultSnapshot: TimerSnapshot = {
@@ -50,6 +71,22 @@ const defaultSnapshot: TimerSnapshot = {
naturalBreakOccurred: false,
smartBreaksEnabled: true,
smartBreakThreshold: 300,
microbreakEnabled: false,
microbreakActive: false,
microbreakTimeRemaining: 0,
microbreakTotalDuration: 0,
microbreakCountdown: 0,
microbreakFrequency: 1200,
pomodoroEnabled: false,
pomodoroCyclePosition: 0,
pomodoroTotalInCycle: 4,
pomodoroIsLongBreak: false,
pomodoroNextIsLong: false,
screenDimActive: false,
screenDimProgress: 0,
presentationModeActive: false,
deferredBreakPending: false,
isLongBreak: false,
};
export const timer = writable<TimerSnapshot>(defaultSnapshot);
@@ -114,8 +151,43 @@ export async function initTimerStore() {
playSound(cfg.sound_preset as any, cfg.sound_volume * 0.5);
}
});
// F1: Microbreak events
await listen("microbreak-started", () => {
const cfg = get(config);
if (cfg.microbreak_sound_enabled && cfg.sound_enabled) {
playSound(cfg.sound_preset as any, cfg.sound_volume * 0.4);
}
});
await listen("microbreak-ended", () => {
const cfg = get(config);
if (cfg.microbreak_sound_enabled && cfg.sound_enabled) {
playBreakEndSound(cfg.sound_preset as any, cfg.sound_volume * 0.3);
}
});
// F10: Milestone and daily goal events
await listen<{ streak: number }>("milestone-reached", (event) => {
milestoneEvent.set(event.payload.streak);
setTimeout(() => milestoneEvent.set(null), 4000);
});
await listen("daily-goal-met", () => {
dailyGoalEvent.set(true);
setTimeout(() => dailyGoalEvent.set(false), 4000);
});
// F2: Break deferred
await listen("break-deferred", () => {
// Dashboard will show deferred status from snapshot
});
}
// F10: Gamification event stores
export const milestoneEvent = writable<number | null>(null);
export const dailyGoalEvent = writable<boolean>(false);
// Helper: format seconds as MM:SS
export function formatTime(secs: number): string {
const m = Math.floor(secs / 60);