flipp_pomodoro.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #include <furi.h>
  2. #include <furi_hal.h>
  3. #include "../helpers/time.h"
  4. #include "flipp_pomodoro.h"
  5. PomodoroStage stages_sequence[] = {
  6. FlippPomodoroStageFocus,
  7. FlippPomodoroStageRest,
  8. FlippPomodoroStageFocus,
  9. FlippPomodoroStageRest,
  10. FlippPomodoroStageFocus,
  11. FlippPomodoroStageRest,
  12. FlippPomodoroStageFocus,
  13. FlippPomodoroStageLongBreak,
  14. };
  15. char *current_stage_label[] = {
  16. [FlippPomodoroStageFocus] = "Continue focus for:",
  17. [FlippPomodoroStageRest] = "Keep rest for:",
  18. [FlippPomodoroStageLongBreak] = "Long Break for:",
  19. };
  20. char *next_stage_label[] = {
  21. [FlippPomodoroStageFocus] = "Focus",
  22. [FlippPomodoroStageRest] = "Short Break",
  23. [FlippPomodoroStageLongBreak] = "Long Break",
  24. };
  25. PomodoroStage flipp_pomodoro__stage_by_index(int index) {
  26. const int one_loop_size = sizeof(stages_sequence);
  27. return stages_sequence[index % one_loop_size];
  28. }
  29. void flipp_pomodoro__toggle_stage(FlippPomodoroState *state)
  30. {
  31. furi_assert(state);
  32. state->current_stage_index = state->current_stage_index + 1;
  33. state->started_at_timestamp = time_now();
  34. };
  35. PomodoroStage flipp_pomodoro__get_stage(FlippPomodoroState *state)
  36. {
  37. furi_assert(state);
  38. return flipp_pomodoro__stage_by_index(state->current_stage_index);
  39. };
  40. char *flipp_pomodoro__current_stage_label(FlippPomodoroState *state)
  41. {
  42. furi_assert(state);
  43. return current_stage_label[flipp_pomodoro__get_stage(state)];
  44. };
  45. char *flipp_pomodoro__next_stage_label(FlippPomodoroState *state)
  46. {
  47. furi_assert(state);
  48. return next_stage_label[flipp_pomodoro__stage_by_index(state->current_stage_index + 1)];
  49. };
  50. void flipp_pomodoro__destroy(FlippPomodoroState *state)
  51. {
  52. furi_assert(state);
  53. free(state);
  54. };
  55. uint32_t flipp_pomodoro__current_stage_total_duration(FlippPomodoroState *state)
  56. {
  57. const int32_t stage_duration_seconds_map[] = {
  58. [FlippPomodoroStageFocus] = 25 * TIME_SECONDS_IN_MINUTE,
  59. [FlippPomodoroStageRest] = 5 * TIME_SECONDS_IN_MINUTE,
  60. [FlippPomodoroStageLongBreak] = 30 * TIME_SECONDS_IN_MINUTE,
  61. };
  62. return stage_duration_seconds_map[flipp_pomodoro__get_stage(state)];
  63. };
  64. uint32_t flipp_pomodoro__stage_expires_timestamp(FlippPomodoroState *state)
  65. {
  66. return state->started_at_timestamp + flipp_pomodoro__current_stage_total_duration(state);
  67. };
  68. TimeDifference flipp_pomodoro__stage_remaining_duration(FlippPomodoroState *state)
  69. {
  70. const uint32_t stage_ends_at = flipp_pomodoro__stage_expires_timestamp(state);
  71. return time_difference_seconds(time_now(), stage_ends_at);
  72. };
  73. bool flipp_pomodoro__is_stage_expired(FlippPomodoroState *state)
  74. {
  75. const uint32_t expired_by = flipp_pomodoro__stage_expires_timestamp(state);
  76. const uint8_t seamless_change_span_seconds = 1;
  77. return (time_now() - seamless_change_span_seconds) >= expired_by;
  78. };
  79. FlippPomodoroState *flipp_pomodoro__new()
  80. {
  81. FlippPomodoroState *state = malloc(sizeof(FlippPomodoroState));
  82. const uint32_t now = time_now();
  83. state->started_at_timestamp = now;
  84. state->current_stage_index = 0;
  85. return state;
  86. };