~aleteoryx/muditaos

ref: 5e919448eb2af24c675bbad96669d2bc0a3afaf2 muditaos/module-apps/application-alarm-clock/presenter/AlarmPresenter.cpp -rw-r--r-- 4.2 KiB
5e919448 — Adam Dobrowolski [EGD-7501] Rrules presenter added 4 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "AlarmPresenter.hpp"
#include "log.hpp"

namespace app::alarmClock
{

    utl::Day AlarmPresenter::dayToDay(uint32_t day_no)
    {
        if (day_no == uint8_t(rrule::RRule::RRuleWeekday::SUNDAY_WEEKDAY)) {
            return utl::Sun;
        }
        return utl::Day(day_no - 1);
    }

    uint8_t AlarmPresenter::dayToDay(utl::Day day)
    {
        if (day == utl::Sun) {
            return uint8_t(rrule::RRule::RRuleWeekday::SUNDAY_WEEKDAY);
        }
        return day + 1;
    }

    uint8_t AlarmPresenter::set_bit_days()
    {
        const auto &rr = rrule::RRule(alarm->rruleText);
        uint8_t days   = 0;
        if (rr.freq != rrule::RRule::RRuleFrequency::WEEKLY_RECURRENCE) {
            return 0;
        }
        for (const auto &day : rr.byDay) {
            if (auto real = dayToDay(day); real < utl::num_days) {
                days |= 1 << real;
            }
        }
        return days;
    }

    UTF8 AlarmPresenter::getDescription()
    {
        auto setDays = set_bit_days();
        if (setDays == weekdaysMask) {
            return utils::translate("app_alarm_clock_repeat_week_days");
        }
        if (setDays == weekMask) {
            return utils::translate("app_alarm_clock_repeat_everyday");
        }
        UTF8 retval = "";
        if (setDays > 0) {
            for (unsigned int i = 0; i < utl::num_days; ++i) {
                if ((0x1 & (setDays >> i)) != 0) {
                    auto dayname = utils::time::Locale::get_short_day(i);
                    retval += dayname + ",";
                }
            }
            if (retval.length() > 0) {
                retval.removeChar(retval.length() - 1);
            }
        }
        return retval;
    }

    AlarmPresenter::Spinner AlarmPresenter::getSpinner()
    {
        auto setDays = set_bit_days();
        if (setDays == 0) {
            return Spinner::Never;
        }
        if (setDays == weekdaysMask) {
            return Spinner::Weekdays;
        }
        if (setDays == weekMask) {
            return Spinner::Weekly;
        }
        auto get_set_days_count = [&]() {
            uint8_t singleday = 0;
            for (unsigned int i = 0; i < utl::num_days; ++i) {
                singleday += 0x1 & (setDays >> i);
            }
            return singleday;
        };
        if (get_set_days_count() == 1) {
            return Spinner::OnDay;
        }
        return Spinner::Custom;
    }

    void AlarmPresenter::setSpinner(AlarmPresenter::Spinner spin,
                                    const std::function<void(AlarmPresenter::Spinner)> &cb)
    {
        switch (spin) {
        case AlarmPresenter::Spinner::Never:
            setDays({});
            break;
        case AlarmPresenter::Spinner::OnDay:
            if (cb != nullptr) {
                cb(spin);
            }
            break;
        case AlarmPresenter::Spinner::Custom:
            if (cb != nullptr) {
                cb(spin);
            }
            break;
        case AlarmPresenter::Spinner::Weekly:
            setDays({utl::Mon, utl::Tue, utl::Wed, utl::Thu, utl::Fri, utl::Sat, utl::Sun});
            break;
        case AlarmPresenter::Spinner::Weekdays:
            setDays({utl::Mon, utl::Tue, utl::Wed, utl::Thu, utl::Fri});
            break;
        }
    }

    void AlarmPresenter::setDays(const std::list<utl::Day> &days)
    {
        if (days.empty()) {
            alarm->rruleText = "";
        }
        else {
            auto rr = rrule::RRule();
            // interval each week
            rr.interval = 1;
            rr.freq     = rrule::RRule::RRuleFrequency::WEEKLY_RECURRENCE;
            for (const auto &day : days) {
                rr.byDay.push_back(dayToDay(day));
            }
            alarm->rruleText = rr.parseToString();
        }
    }

    std::list<utl::Day> AlarmPresenter::getDays()
    {
        std::list<utl::Day> ret;
        auto setDays = set_bit_days();
        for (unsigned int i = 0; i < utl::num_days; ++i) {
            if ((0x1 & (setDays >> i)) != 0) {
                ret.push_back(utl::Day(i));
            }
        }
        return ret;
    }

} // namespace app::alarmClock