161 lines
8.9 KiB
TypeScript
161 lines
8.9 KiB
TypeScript
export interface BreakActivity {
|
|
category: "eyes" | "stretch" | "breathing" | "movement";
|
|
text: string;
|
|
}
|
|
|
|
export const breakActivities: BreakActivity[] = [
|
|
// Eyes
|
|
{ category: "eyes", text: "Look at something 20 feet away for 20 seconds" },
|
|
{ category: "eyes", text: "Close your eyes and gently press your palms over them" },
|
|
{ category: "eyes", text: "Slowly roll your eyes in circles, 5 times each direction" },
|
|
{ category: "eyes", text: "Focus on a distant object, then a near one -- repeat 5 times" },
|
|
{ category: "eyes", text: "Blink rapidly 20 times to refresh your eyes" },
|
|
{ category: "eyes", text: "Look up, down, left, right -- hold each for 2 seconds" },
|
|
{ category: "eyes", text: "Cup your hands over closed eyes and breathe deeply" },
|
|
{ category: "eyes", text: "Trace a figure-8 with your eyes, slowly" },
|
|
{ category: "eyes", text: "Look out the nearest window and find the farthest point" },
|
|
{ category: "eyes", text: "Gently massage your temples in small circles" },
|
|
{ category: "eyes", text: "Close your eyes and visualize a calm, dark space for 20 seconds" },
|
|
{ category: "eyes", text: "Warm your palms by rubbing them together, then rest them over closed eyes" },
|
|
{ category: "eyes", text: "Slowly shift your gaze along the horizon line outside" },
|
|
{ category: "eyes", text: "Focus on the tip of your nose for 5 seconds, then a far wall" },
|
|
{ category: "eyes", text: "Look at something green -- plants reduce eye strain naturally" },
|
|
{ category: "eyes", text: "Close your eyes and gently press your eyebrows outward from center" },
|
|
{ category: "eyes", text: "Squeeze your eyes shut for 3 seconds, then open wide -- repeat 5 times" },
|
|
{ category: "eyes", text: "Trace the outline of a window frame with your eyes, slowly" },
|
|
|
|
// Stretches
|
|
{ category: "stretch", text: "Roll your shoulders backward slowly, 5 times" },
|
|
{ category: "stretch", text: "Interlace fingers behind your back and open your chest" },
|
|
{ category: "stretch", text: "Tilt your head to each side, holding for 10 seconds" },
|
|
{ category: "stretch", text: "Stretch your arms overhead and reach for the ceiling" },
|
|
{ category: "stretch", text: "Rotate your wrists in circles, 10 times each direction" },
|
|
{ category: "stretch", text: "Clasp hands together and push palms away from you" },
|
|
{ category: "stretch", text: "Gently twist your torso left and right from your chair" },
|
|
{ category: "stretch", text: "Drop your chin to your chest and slowly roll your neck" },
|
|
{ category: "stretch", text: "Extend each arm across your chest, hold for 15 seconds" },
|
|
{ category: "stretch", text: "Open and close your hands, spreading fingers wide" },
|
|
{ category: "stretch", text: "Place your right hand on your left knee and twist gently -- switch sides" },
|
|
{ category: "stretch", text: "Reach one arm overhead and lean to the opposite side, hold 10 seconds each" },
|
|
{ category: "stretch", text: "Interlace your fingers and flip your palms to the ceiling, push up" },
|
|
{ category: "stretch", text: "Pull each finger gently backward for 3 seconds to stretch your forearms" },
|
|
{ category: "stretch", text: "Press your palms together at chest height and push for 10 seconds" },
|
|
{ category: "stretch", text: "Sit tall, reach behind to grab the back of your chair, and open your chest" },
|
|
{ category: "stretch", text: "Cross one ankle over the opposite knee and lean forward gently" },
|
|
{ category: "stretch", text: "Shrug your shoulders up to your ears, hold 5 seconds, release slowly" },
|
|
|
|
// Breathing
|
|
{ category: "breathing", text: "Inhale for 4 seconds, hold for 4, exhale for 6" },
|
|
{ category: "breathing", text: "Take 5 deep belly breaths -- feel your diaphragm expand" },
|
|
{ category: "breathing", text: "Box breathing: inhale 4s, hold 4s, exhale 4s, hold 4s" },
|
|
{ category: "breathing", text: "Breathe in through your nose, out through your mouth -- 5 times" },
|
|
{ category: "breathing", text: "Sigh deeply 3 times to release tension" },
|
|
{ category: "breathing", text: "Place a hand on your chest and breathe so only your belly moves" },
|
|
{ category: "breathing", text: "Alternate nostril breathing: 3 cycles each side" },
|
|
{ category: "breathing", text: "Exhale completely, then take the deepest breath you can" },
|
|
{ category: "breathing", text: "Count your breaths backward from 10 to 1" },
|
|
{ category: "breathing", text: "Breathe in calm, breathe out tension -- 5 rounds" },
|
|
{ category: "breathing", text: "4-7-8 breathing: inhale 4s, hold 7s, exhale slowly for 8s" },
|
|
{ category: "breathing", text: "Take 3 breaths making your exhale twice as long as your inhale" },
|
|
{ category: "breathing", text: "Breathe in for 2 counts, out for 2 -- gradually increase to 6 each" },
|
|
{ category: "breathing", text: "Hum gently on each exhale for 5 breaths -- feel the vibration in your chest" },
|
|
{ category: "breathing", text: "Imagine breathing in cool blue air and exhaling warm red air -- 5 rounds" },
|
|
{ category: "breathing", text: "Place both hands on your ribs and breathe so you feel them expand sideways" },
|
|
{ category: "breathing", text: "Breathe in through pursed lips slowly, then exhale in a long, steady stream" },
|
|
|
|
// Movement
|
|
{ category: "movement", text: "Stand up and walk to the nearest window" },
|
|
{ category: "movement", text: "Do 10 standing calf raises" },
|
|
{ category: "movement", text: "Walk to get a glass of water" },
|
|
{ category: "movement", text: "Stand and do 5 gentle squats" },
|
|
{ category: "movement", text: "Take a short walk around your room" },
|
|
{ category: "movement", text: "Stand on one foot for 15 seconds, then switch" },
|
|
{ category: "movement", text: "Do 10 arm circles, forward then backward" },
|
|
{ category: "movement", text: "March in place for 30 seconds" },
|
|
{ category: "movement", text: "Shake out your hands and arms for 10 seconds" },
|
|
{ category: "movement", text: "Stand up, touch your toes, and slowly rise" },
|
|
{ category: "movement", text: "Walk to the farthest room in your home and back" },
|
|
{ category: "movement", text: "Do 5 wall push-ups -- hands on the wall, lean in and push back" },
|
|
{ category: "movement", text: "Stand up and slowly shift your weight side to side for 20 seconds" },
|
|
{ category: "movement", text: "Walk in a small circle, paying attention to each footstep" },
|
|
{ category: "movement", text: "Rise onto your tiptoes, hold for 5 seconds, lower slowly -- repeat 5 times" },
|
|
{ category: "movement", text: "Do a gentle standing forward fold -- let your arms hang loose" },
|
|
{ category: "movement", text: "Step away from your desk and do 10 hip circles in each direction" },
|
|
{ category: "movement", text: "Stand with your back against a wall and slide down into a gentle wall sit for 15 seconds" },
|
|
];
|
|
|
|
const categoryIcons: Record<BreakActivity["category"], string> = {
|
|
eyes: "👁",
|
|
stretch: "🤸",
|
|
breathing: "🌬",
|
|
movement: "🚶",
|
|
};
|
|
|
|
const categoryLabels: Record<BreakActivity["category"], string> = {
|
|
eyes: "Eye Exercise",
|
|
stretch: "Stretch",
|
|
breathing: "Breathing",
|
|
movement: "Movement",
|
|
};
|
|
|
|
export function getCategoryIcon(cat: BreakActivity["category"]): string {
|
|
return categoryIcons[cat];
|
|
}
|
|
|
|
export function getCategoryLabel(cat: BreakActivity["category"]): string {
|
|
return categoryLabels[cat];
|
|
}
|
|
|
|
/** Pick a random activity, optionally excluding a previous one.
|
|
* When config is provided, respects disabled/favorite/custom activity settings. */
|
|
export function pickRandomActivity(
|
|
exclude?: BreakActivity,
|
|
config?: {
|
|
disabled_builtin_activities?: string[];
|
|
favorite_builtin_activities?: string[];
|
|
custom_activities?: Array<{ category: string; text: string; is_favorite: boolean; enabled: boolean }>;
|
|
favorite_weight?: number;
|
|
},
|
|
): BreakActivity {
|
|
const disabled = new Set(config?.disabled_builtin_activities ?? []);
|
|
const favorites = new Set(config?.favorite_builtin_activities ?? []);
|
|
const weight = config?.favorite_weight ?? 3;
|
|
|
|
// Build pool: enabled builtins + enabled customs
|
|
let pool: BreakActivity[] = breakActivities.filter((a) => !disabled.has(a.text));
|
|
|
|
// Add enabled custom activities
|
|
if (config?.custom_activities) {
|
|
for (const ca of config.custom_activities) {
|
|
if (ca.enabled) {
|
|
const cat = (["eyes", "stretch", "breathing", "movement"].includes(ca.category)
|
|
? ca.category
|
|
: "movement") as BreakActivity["category"];
|
|
pool.push({ category: cat, text: ca.text });
|
|
}
|
|
}
|
|
}
|
|
|
|
// Exclude previous
|
|
if (exclude) {
|
|
pool = pool.filter((a) => a.text !== exclude.text);
|
|
}
|
|
|
|
if (pool.length === 0) {
|
|
return exclude ?? breakActivities[0];
|
|
}
|
|
|
|
// Build weighted pool: favorites appear `weight` times
|
|
const weighted: BreakActivity[] = [];
|
|
for (const a of pool) {
|
|
const isFav = favorites.has(a.text) ||
|
|
(config?.custom_activities?.some((c) => c.text === a.text && c.is_favorite) ?? false);
|
|
const count = isFav ? weight : 1;
|
|
for (let i = 0; i < count; i++) {
|
|
weighted.push(a);
|
|
}
|
|
}
|
|
|
|
return weighted[Math.floor(Math.random() * weighted.length)];
|
|
}
|