98 lines
2.6 KiB
TypeScript
98 lines
2.6 KiB
TypeScript
/**
|
|
* Tempo Mode engine — Phase D.3.
|
|
*
|
|
* Adjusts timer urgency and cascade presets based on the user's current
|
|
* energy/focus level. Pure TS, no React.
|
|
*/
|
|
|
|
export type TempoLevel = 'deep_focus' | 'normal' | 'low_energy' | 'winding_down';
|
|
|
|
export interface TempoConfig {
|
|
level: TempoLevel;
|
|
label: string;
|
|
description: string;
|
|
urgencyOverride: string;
|
|
cascadeOverride: string;
|
|
notificationMute: boolean;
|
|
}
|
|
|
|
export const TEMPO_CONFIGS: Record<TempoLevel, TempoConfig> = {
|
|
deep_focus: {
|
|
level: 'deep_focus',
|
|
label: 'Deep Focus',
|
|
description: 'Minimal interruptions. Only critical timers fire.',
|
|
urgencyOverride: 'passive',
|
|
cascadeOverride: 'minimal',
|
|
notificationMute: true,
|
|
},
|
|
normal: {
|
|
level: 'normal',
|
|
label: 'Normal',
|
|
description: 'Standard timer behavior.',
|
|
urgencyOverride: 'standard',
|
|
cascadeOverride: 'standard',
|
|
notificationMute: false,
|
|
},
|
|
low_energy: {
|
|
level: 'low_energy',
|
|
label: 'Low Energy',
|
|
description: 'Gentler reminders. Extended snooze times.',
|
|
urgencyOverride: 'gentle',
|
|
cascadeOverride: 'minimal',
|
|
notificationMute: false,
|
|
},
|
|
winding_down: {
|
|
level: 'winding_down',
|
|
label: 'Winding Down',
|
|
description: 'Quiet mode. Non-critical timers deferred.',
|
|
urgencyOverride: 'passive',
|
|
cascadeOverride: 'minimal',
|
|
notificationMute: true,
|
|
},
|
|
};
|
|
|
|
/**
|
|
* Compute effective urgency based on tempo mode.
|
|
*/
|
|
export function getEffectiveUrgency(
|
|
timerUrgency: string,
|
|
tempoLevel: TempoLevel,
|
|
): string {
|
|
if (tempoLevel === 'normal') return timerUrgency;
|
|
|
|
// Critical timers always fire regardless of tempo
|
|
if (timerUrgency === 'critical') return 'critical';
|
|
|
|
// In deep_focus or winding_down, downgrade non-critical to passive
|
|
if (tempoLevel === 'deep_focus' || tempoLevel === 'winding_down') {
|
|
return timerUrgency === 'important' ? 'standard' : 'passive';
|
|
}
|
|
|
|
// low_energy: make everything gentler
|
|
if (tempoLevel === 'low_energy') {
|
|
if (timerUrgency === 'important') return 'standard';
|
|
if (timerUrgency === 'standard') return 'gentle';
|
|
return 'passive';
|
|
}
|
|
|
|
return timerUrgency;
|
|
}
|
|
|
|
/**
|
|
* Compute effective cascade preset based on tempo mode.
|
|
*/
|
|
export function getEffectiveCascade(
|
|
cascadePreset: string,
|
|
tempoLevel: TempoLevel,
|
|
): string {
|
|
if (tempoLevel === 'normal') return cascadePreset;
|
|
return TEMPO_CONFIGS[tempoLevel].cascadeOverride;
|
|
}
|
|
|
|
/**
|
|
* Check if notifications should be muted for this tempo level.
|
|
*/
|
|
export function shouldMuteNotifications(tempoLevel: TempoLevel): boolean {
|
|
return TEMPO_CONFIGS[tempoLevel].notificationMute;
|
|
}
|