~aleteoryx/muditaos

ref: df7535f10afe6d1c74b0dfcb2f5808711e96e725 muditaos/module-apps/application-alarm-clock/presenter/AlarmRRulePresenter.cpp -rw-r--r-- 5.1 KiB
df7535f1 — rrandomsky [MOS-948] Revert: Fix for tethering popup was losing app context 2 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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "AlarmRRulePresenter.hpp"
#include "log/log.hpp"

namespace app::alarmClock
{
    AlarmRRulePresenter::AlarmRRulePresenter(std::shared_ptr<AlarmEventRecord> recordToLoad)
        : alarm(std::move(recordToLoad))
    {}

    void AlarmRRulePresenter::loadRecord(std::shared_ptr<AlarmEventRecord> recordToLoad)
    {
        alarm = std::move(recordToLoad);
    }

    utl::Day AlarmRRulePresenter::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 AlarmRRulePresenter::dayToDay(utl::Day day)
    {
        if (day == utl::Sun) {
            return uint8_t(rrule::RRule::RRuleWeekday::SUNDAY_WEEKDAY);
        }
        return day + 1;
    }

    uint8_t AlarmRRulePresenter::setBitDays()
    {
        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 AlarmRRulePresenter::getDescription()
    {
        auto setDays = setBitDays();
        if (setDays == 0) {
            return utils::translate("app_alarm_clock_repeat_never");
        }
        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() - 2);
            }
        }
        return retval;
    }

    bool AlarmRRulePresenter::isDaySet(uint8_t &days, uint8_t day)
    {
        return 0x1 & (days >> day);
    }

    AlarmRRulePresenter::RRuleOptions AlarmRRulePresenter::getOption()
    {
        auto setDays = setBitDays();
        if (setDays == 0) {
            return RRuleOptions::Never;
        }
        if (setDays == weekdaysMask) {
            return RRuleOptions::Weekdays;
        }
        if (setDays == weekMask) {
            return RRuleOptions::Everyday;
        }
        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 RRuleOptions::OnDay;
        }
        return RRuleOptions::Custom;
    }

    std::vector<std::pair<std::string, bool>> AlarmRRulePresenter::getCustomDays()
    {
        std::vector<std::pair<std::string, bool>> selectedDays;
        auto setDays = setBitDays();

        for (unsigned int i = 0; i < utl::num_days; ++i) {
            selectedDays.push_back({utils::time::Locale::get_day(i), isDaySet(setDays, i)});
        }

        return selectedDays;
    }

    void AlarmRRulePresenter::setOption(AlarmRRulePresenter::RRuleOptions options, const std::list<utl::Day> &days)
    {
        switch (options) {
        case AlarmRRulePresenter::RRuleOptions::Never:
            setDays({});
            break;
        case AlarmRRulePresenter::RRuleOptions::OnDay:
            setDays(days);
            break;
        case AlarmRRulePresenter::RRuleOptions::Custom:
            setDays(days);
            break;
        case AlarmRRulePresenter::RRuleOptions::Everyday:
            setDays({utl::Mon, utl::Tue, utl::Wed, utl::Thu, utl::Fri, utl::Sat, utl::Sun});
            break;
        case AlarmRRulePresenter::RRuleOptions::Weekdays:
            setDays({utl::Mon, utl::Tue, utl::Wed, utl::Thu, utl::Fri});
            break;
        }
    }

    void AlarmRRulePresenter::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> AlarmRRulePresenter::getDays()
    {
        std::list<utl::Day> ret;
        auto setDays = setBitDays();
        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