Add pomodoro, microbreaks, breathing guide, screen dimming, presentation mode, goals, multi-monitor, and activity manager
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user