diff --git a/image/system_a/data/lang/English.json b/image/system_a/data/lang/English.json index 0694d3f83..cee9f7641 100644 --- a/image/system_a/data/lang/English.json +++ b/image/system_a/data/lang/English.json @@ -103,6 +103,11 @@ "app_bell_onboarding_shortcuts_step_restart": "Press both side buttons for 10s to restart the device", "app_bell_onboarding_shortcuts_step_rotate": "Rotate to select", "app_bell_onboarding_shortcuts_step_turn_off": "Press back for 10s to turn off the device", + "app_bell_whatsnew_title": "What's New", + "app_bell_whatsnew_version": "OS version: $VERSION", + "app_bell_whatsnew_continue": "Continue", + "app_bell_whatsnew_skip": "Skip", + "app_bell_whatsnew_end_screen_text": "We'd love to hear your feedback about this update at
mudita.com/forum
", "app_bell_relaxation_loop": "loop", "app_bell_relaxation_loop_description": "the song will play until you turn it off", "app_bell_relaxation_looped": "looped", diff --git a/module-apps/apps-common/widgets/BellSideListItem.hpp b/module-apps/apps-common/widgets/BellSideListItem.hpp index d6e3defde..1dc3fa97a 100644 --- a/module-apps/apps-common/widgets/BellSideListItem.hpp +++ b/module-apps/apps-common/widgets/BellSideListItem.hpp @@ -17,7 +17,7 @@ namespace gui void setBottomDescriptionText(const std::string &description); protected: - BellSideListItem(BellBaseLayout::LayoutType type = BellBaseLayout::LayoutType::WithArrows); + explicit BellSideListItem(BellBaseLayout::LayoutType type = BellBaseLayout::LayoutType::WithArrows); void setupBottomTextBox(const std::string &description); void setupTopTextBox(const std::string &description); diff --git a/module-db/Common/Types.hpp b/module-db/Common/Types.hpp index c458eeb65..1197c6341 100644 --- a/module-db/Common/Types.hpp +++ b/module-db/Common/Types.hpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once @@ -10,4 +10,4 @@ /// Zero terminated string with single-quotes on both ends, for instance: 'my string' #define str_ "%Q" /// The same as above with additional comma at the end, for instance: 'my string', -#define str_c "%Q," \ No newline at end of file +#define str_c "%Q," diff --git a/products/BellHybrid/apps/application-bell-background-sounds/ApplicationBellBackgroundSounds.cpp b/products/BellHybrid/apps/application-bell-background-sounds/ApplicationBellBackgroundSounds.cpp deleted file mode 100644 index e69de29bb..000000000 diff --git a/products/BellHybrid/apps/application-bell-meditation-timer/CMakeLists.txt b/products/BellHybrid/apps/application-bell-meditation-timer/CMakeLists.txt index 2c401ddfc..4fe0c6453 100644 --- a/products/BellHybrid/apps/application-bell-meditation-timer/CMakeLists.txt +++ b/products/BellHybrid/apps/application-bell-meditation-timer/CMakeLists.txt @@ -27,7 +27,6 @@ target_sources(application-bell-meditation-timer presenter/MeditationProgressPresenter.cpp presenter/MeditationTimerPresenter.cpp presenter/ReadyGoingPresenter.cpp - presenter/SessionEndedPresenter.cpp presenter/SettingsPresenter.cpp presenter/StatisticsPresenter.cpp windows/MeditationMainWindow.cpp diff --git a/products/BellHybrid/apps/application-bell-meditation-timer/presenter/SessionEndedPresenter.cpp b/products/BellHybrid/apps/application-bell-meditation-timer/presenter/SessionEndedPresenter.cpp deleted file mode 100644 index 8eb84d3f9..000000000 --- a/products/BellHybrid/apps/application-bell-meditation-timer/presenter/SessionEndedPresenter.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. -// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md - -#include "SessionEndedPresenter.hpp" - -#include - -namespace app::meditation -{ - SessionEndedPresenter::SessionEndedPresenter(app::ApplicationCommon *app) : app{app} - {} - - void SessionEndedPresenter::activate() - { - app::manager::Controller::sendAction(app, app::manager::actions::Home); - } -} // namespace app::meditation diff --git a/products/BellHybrid/apps/application-bell-meditation-timer/presenter/SessionEndedPresenter.hpp b/products/BellHybrid/apps/application-bell-meditation-timer/presenter/SessionEndedPresenter.hpp deleted file mode 100644 index f9805ccad..000000000 --- a/products/BellHybrid/apps/application-bell-meditation-timer/presenter/SessionEndedPresenter.hpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. -// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md - -#pragma once - -#include -#include - -namespace app -{ - class ApplicationCommon; -} - -namespace app::meditation -{ - class SessionEndedPresenterContract - { - public: - class View - { - public: - virtual ~View() = default; - }; - class Presenter : public BasePresenter - { - public: - virtual void activate() = 0; - }; - }; - - class SessionEndedPresenter : public SessionEndedPresenterContract::Presenter - { - app::ApplicationCommon *app{}; - void activate() override; - - public: - explicit SessionEndedPresenter(app::ApplicationCommon *app); - }; -} // namespace app::meditation diff --git a/products/BellHybrid/apps/application-bell-onboarding/ApplicationBellOnBoarding.cpp b/products/BellHybrid/apps/application-bell-onboarding/ApplicationBellOnBoarding.cpp index 70088dad1..cffc64400 100644 --- a/products/BellHybrid/apps/application-bell-onboarding/ApplicationBellOnBoarding.cpp +++ b/products/BellHybrid/apps/application-bell-onboarding/ApplicationBellOnBoarding.cpp @@ -97,7 +97,6 @@ namespace app void ApplicationBellOnBoarding::createUserInterface() { - windowsFactory.attach(gui::name::window::main_window, [this](ApplicationCommon *app, const std::string &name) { auto powerOffPresenter = std::make_unique(app); return std::make_unique(app, std::move(powerOffPresenter), name); diff --git a/products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.hpp b/products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.hpp index 52dc768e6..946ad2a5c 100644 --- a/products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.hpp +++ b/products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.hpp @@ -1,7 +1,8 @@ -// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #pragma once + #include #include diff --git a/products/BellHybrid/apps/application-bell-settings/windows/AboutYourBellWindow.cpp b/products/BellHybrid/apps/application-bell-settings/windows/AboutYourBellWindow.cpp index f8e888325..67eca3c9b 100644 --- a/products/BellHybrid/apps/application-bell-settings/windows/AboutYourBellWindow.cpp +++ b/products/BellHybrid/apps/application-bell-settings/windows/AboutYourBellWindow.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. +// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include "AboutYourBellWindow.hpp" @@ -11,7 +11,7 @@ namespace gui { namespace { - static constexpr auto top_margin = 41U; + constexpr auto top_margin = 41U; } AboutYourBellWindow::AboutYourBellWindow( diff --git a/products/BellHybrid/apps/application-bell-whats-new/ApplicationWhatsNew.cpp b/products/BellHybrid/apps/application-bell-whats-new/ApplicationWhatsNew.cpp index 9f6786bc2..dcbde6b4a 100644 --- a/products/BellHybrid/apps/application-bell-whats-new/ApplicationWhatsNew.cpp +++ b/products/BellHybrid/apps/application-bell-whats-new/ApplicationWhatsNew.cpp @@ -3,11 +3,13 @@ #include "ApplicationWhatsNew.hpp" #include "WhatsNewCommon.hpp" +#include "WhatsNewMainWindow.hpp" +#include "WhatsNewMainPresenter.hpp" +#include "WhatsNewFeaturesWindow.hpp" +#include "WhatsNewFeaturesPresenter.hpp" +#include "WhatsNewFeaturesModel.hpp" -#include "windows/WhatsNewWindow.hpp" -#include "presenter/WhatsNewPresenter.hpp" -#include "models/WhatsNewModel.hpp" - +#include #include #include @@ -33,10 +35,6 @@ namespace app return ret; } - whatsNewModel = std::make_unique(this); - - batteryModel = std::make_unique(this); - lowBatteryInfoModel = std::make_unique(); cpuSentinel = std::make_shared(applicationWhatsNewName, this); auto sentinelRegistrationMsg = std::make_shared(cpuSentinel); bus.sendUnicast(std::move(sentinelRegistrationMsg), service::name::system_manager); @@ -49,16 +47,27 @@ namespace app void ApplicationWhatsNew::createUserInterface() { - windowsFactory.attach(whatsNew::window::name::main, [this](ApplicationCommon *app, const std::string &name) { - auto presenter = std::make_unique(*batteryModel, *lowBatteryInfoModel); - return std::make_unique(app, std::move(presenter)); + windowsFactory.attach(whatsnew::window::name::main, [this](ApplicationCommon *app, const std::string &name) { + auto presenter = std::make_unique(settings.get()); + return std::make_unique(app, std::move(presenter), name); }); - windowsFactory.attach(whatsNew::window::name::whatsNewLowBattery, + windowsFactory.attach( + whatsnew::window::name::features, [this](ApplicationCommon *app, const std::string &name) { + auto model = std::make_unique(this, settings.get()); + auto presenter = std::make_unique(std::move(model)); + return std::make_unique(app, std::move(presenter), name); + }); + windowsFactory.attach(gui::window::bell_finished::defaultName, [](ApplicationCommon *app, const std::string &name) { - return std::make_unique(app, name); + return std::make_unique(app, name); }); + // windowsFactory.attach(whatsnew::window::name::whatsNewLowBattery, + // [](ApplicationCommon *app, const std::string &name) { + // return std::make_unique(app, name); + // }); + attachPopups({gui::popup::ID::AlarmActivated, gui::popup::ID::AlarmDeactivated, gui::popup::ID::PowerOff, diff --git a/products/BellHybrid/apps/application-bell-whats-new/CMakeLists.txt b/products/BellHybrid/apps/application-bell-whats-new/CMakeLists.txt index c397fcdd1..d7ef4f041 100644 --- a/products/BellHybrid/apps/application-bell-whats-new/CMakeLists.txt +++ b/products/BellHybrid/apps/application-bell-whats-new/CMakeLists.txt @@ -12,6 +12,7 @@ target_include_directories(application-bell-whats-new data models presenter + widgets windows > PUBLIC @@ -21,10 +22,16 @@ target_include_directories(application-bell-whats-new target_sources(application-bell-whats-new PRIVATE ApplicationWhatsNew.cpp - - windows/WhatsNewWindow.cpp - presenter/WhatsNewPresenter.cpp - models/WhatsNewModel.cpp + + models/WhatsNewFeaturesModel.cpp + + presenter/WhatsNewFeaturesPresenter.cpp + presenter/WhatsNewMainPresenter.cpp + + widgets/WhatsNewFeaturesLayout.cpp + + windows/WhatsNewMainWindow.cpp + windows/WhatsNewFeaturesWindow.cpp PUBLIC include/application-bell-whats-new/ApplicationWhatsNew.hpp diff --git a/products/BellHybrid/apps/application-bell-whats-new/data/WhatsNewCommon.hpp b/products/BellHybrid/apps/application-bell-whats-new/data/WhatsNewCommon.hpp index 9251b206e..6702dbd4c 100644 --- a/products/BellHybrid/apps/application-bell-whats-new/data/WhatsNewCommon.hpp +++ b/products/BellHybrid/apps/application-bell-whats-new/data/WhatsNewCommon.hpp @@ -5,12 +5,12 @@ #include -namespace app::whatsNew +namespace app::whatsnew { namespace window::name { inline constexpr auto main = gui::name::window::main_window; - inline constexpr auto whatsNewLowBattery = "WhatsNewLowBatteryWindow"; + inline constexpr auto features = "WhatsNewFeaturesWindow"; + // inline constexpr auto whatsNewLowBattery = "WhatsNewLowBatteryWindow"; } // namespace window::name - -} // namespace app::whatsNew +} // namespace app::whatsnew diff --git a/products/BellHybrid/apps/application-bell-whats-new/data/WhatsNewStyle.hpp b/products/BellHybrid/apps/application-bell-whats-new/data/WhatsNewStyle.hpp index 83b155c34..1599487a5 100644 --- a/products/BellHybrid/apps/application-bell-whats-new/data/WhatsNewStyle.hpp +++ b/products/BellHybrid/apps/application-bell-whats-new/data/WhatsNewStyle.hpp @@ -6,5 +6,56 @@ #include #include "widgets/BellBaseLayout.hpp" -namespace app::whatsNew -{} // namespace app::whatsNew +namespace gui::whats_new_style +{ + namespace main_window + { + inline constexpr auto list_title_font = style::window::font::large; + inline constexpr auto description_font = style::window::font::mediumbigbold; + inline constexpr auto description_height = 136U; + } // namespace main_window + + namespace features_window + { + namespace layout + { + inline constexpr auto width = style::window_width; + inline constexpr auto height = style::window_height; + } // namespace layout + + namespace container + { + inline constexpr auto width = 544U; + inline constexpr auto height = 436U; + inline constexpr auto margin_top = 42U; + } // namespace container + + namespace center_box + { + inline constexpr auto width = 448U; + inline constexpr auto height = 436U; + } // namespace center_box + + namespace icon + { + inline constexpr auto width = center_box::width; + inline constexpr auto height = 120U; + } // namespace icon + + namespace title + { + inline constexpr auto font = style::window::font::large; + inline constexpr auto width = center_box::width; + inline constexpr auto height = 56U; + inline constexpr auto margin_top = 16U; + } // namespace title + + namespace description + { + inline constexpr auto font = style::window::font::verybiglight; + inline constexpr auto width = center_box::width; + inline constexpr auto height = 168U; + inline constexpr auto margin_top = 40U; + } // namespace description + } // namespace features_window +} // namespace gui::whats_new_style diff --git a/products/BellHybrid/apps/application-bell-whats-new/include/application-bell-whats-new/ApplicationWhatsNew.hpp b/products/BellHybrid/apps/application-bell-whats-new/include/application-bell-whats-new/ApplicationWhatsNew.hpp index 82c77cb3e..5ec90e808 100644 --- a/products/BellHybrid/apps/application-bell-whats-new/include/application-bell-whats-new/ApplicationWhatsNew.hpp +++ b/products/BellHybrid/apps/application-bell-whats-new/include/application-bell-whats-new/ApplicationWhatsNew.hpp @@ -7,25 +7,26 @@ #include #include -namespace app::whatsNew::models +namespace app::whatsnew::models { - class WhatsNewModel; -} // namespace app::whatsNew::models + class WhatsNewFeaturesModel; +} namespace app { inline constexpr auto applicationWhatsNewName = "ApplicationWhatsNew"; - inline constexpr auto applicationWhatsNewStackSize = 1024 * 8; + inline constexpr auto applicationWhatsNewStackSize = 1024 * 10; class ApplicationWhatsNew : public Application { public: - ApplicationWhatsNew(std::string name = applicationWhatsNewName, - std::string parent = "", - StatusIndicators statusIndicators = StatusIndicators{}, - StartInBackground startInBackground = false, - std::uint32_t stackDepth = applicationWhatsNewStackSize); - ~ApplicationWhatsNew(); + explicit ApplicationWhatsNew(std::string name = applicationWhatsNewName, + std::string parent = "", + StatusIndicators statusIndicators = StatusIndicators{}, + StartInBackground startInBackground = false, + std::uint32_t stackDepth = applicationWhatsNewStackSize); + ~ApplicationWhatsNew() override; + sys::ReturnCodes InitHandler() override; void createUserInterface() override; @@ -40,7 +41,7 @@ namespace app } private: - std::unique_ptr whatsNewModel; + std::unique_ptr whatsNewModel; std::unique_ptr batteryModel; std::unique_ptr lowBatteryInfoModel; diff --git a/products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewFeaturesModel.cpp b/products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewFeaturesModel.cpp new file mode 100644 index 000000000..244cd791b --- /dev/null +++ b/products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewFeaturesModel.cpp @@ -0,0 +1,79 @@ +// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "WhatsNewFeaturesModel.hpp" +#include +#include +#include +#include +#include +#include + +namespace +{ + using namespace service::db::whatsnew; + + auto getVersionNumber(const std::string &version) -> std::optional + { + constexpr auto versionSize{3U}; + + std::vector strVector{utils::split(version, '.')}; + if (strVector.size() != versionSize) { + return {}; + } + + std::vector uintVector{}; + uintVector.reserve(versionSize); + + for (const auto &str : strVector) { + if (!utils::is_number(str)) { + return {}; + } + uintVector.push_back(utils::getNumericValue(str)); + } + return VersionNumber{uintVector[0], uintVector[1], uintVector[2]}; + } + + auto sendDBRequest(sys::Service *serv, std::shared_ptr &&msg) -> std::optional + { + const auto ret = serv->bus.sendUnicastSync(std::move(msg), service::name::db, sys::BusProxy::defaultTimeout); + if (ret.first == sys::ReturnCodes::Success) { + if (auto resp = std::dynamic_pointer_cast(ret.second)) { + return *resp; + } + } + return {}; + } +} // namespace + +namespace app::whatsnew::models +{ + WhatsNewFeaturesModel::WhatsNewFeaturesModel(app::ApplicationCommon *app, settings::Settings *settings) + : settings{settings} + { + const auto &lastVersion = + this->settings->getValue(settings::SystemProperties::osCurrentVersion, settings::SettingsScope::Global); + const auto &version = getVersionNumber(lastVersion); + if (!version.has_value()) { + LOG_ERROR("Failed to parse last version string!"); + return; + } + + const auto &result = sendDBRequest(app, std::make_shared(version.value())); + if (result.has_value()) { + for (const auto &record : result->records) { + features.push_back(Feature{record.title, record.description, record.iconName}); + } + } + } + + auto WhatsNewFeaturesModel::getFeatures() -> std::vector + { + return features; + } + + auto WhatsNewFeaturesModel::setCurrentOsVersion(const std::string &version) -> void + { + settings->setValue(settings::SystemProperties::osCurrentVersion, version, settings::SettingsScope::Global); + } +} // namespace app::whatsnew::models diff --git a/products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewFeaturesModel.hpp b/products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewFeaturesModel.hpp new file mode 100644 index 000000000..123c865ba --- /dev/null +++ b/products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewFeaturesModel.hpp @@ -0,0 +1,41 @@ +// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include +#include + +namespace app +{ + class ApplicationCommon; +} + +namespace settings +{ + class Settings; +} + +namespace app::whatsnew::models +{ + struct Feature + { + std::string title; + std::string description; + std::string iconName; + }; + + class WhatsNewFeaturesModel + { + public: + WhatsNewFeaturesModel(app::ApplicationCommon *app, settings::Settings *settings); + + auto getFeatures() -> std::vector; + auto setCurrentOsVersion(const std::string &version) -> void; + + private: + app::ApplicationCommon *app{nullptr}; + settings::Settings *settings{nullptr}; + std::vector features; + }; +} // namespace app::whatsnew::models diff --git a/products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewModel.cpp b/products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewModel.cpp deleted file mode 100644 index cdd4a8849..000000000 --- a/products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewModel.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. -// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md - -#include "WhatsNewModel.hpp" -#include -#include -#include -#include -#include - -namespace -{ - using namespace service::db::whatsNew; - constexpr auto versionSize{3U}; - - std::optional getVersionNumber(std::string version) - { - std::vector strVector{utils::split(version, '.')}; - if (strVector.size() != versionSize) { - return std::nullopt; - } - - std::vector uintVector{}; - uintVector.reserve(versionSize); - - for (auto &str : strVector) { - if (!utils::is_number(str)) { - return std::nullopt; - } - uintVector.push_back(utils::getNumericValue(str)); - } - return VersionNumber{.major{uintVector[0]}, .minor{uintVector[1]}, .patch{uintVector[2]}}; - } - - std::optional sendDBRequest(sys::Service *serv, std::shared_ptr &&msg) - { - const auto ret = serv->bus.sendUnicastSync(std::move(msg), service::name::db, sys::BusProxy::defaultTimeout); - if (ret.first == sys::ReturnCodes::Success) { - if (auto resp = std::dynamic_pointer_cast(ret.second)) { - return *resp; - } - } - return std::nullopt; - } -} // namespace - -namespace app::whatsNew::models -{ - WhatsNewModel::WhatsNewModel(app::ApplicationCommon *app) : app{app} - { - const auto version = getVersionNumber(VERSION); - if (!version.has_value()) { - return; - } - const auto result = sendDBRequest(app, std::make_shared(version.value())); - if (result.has_value()) { - for (auto &record : result->records) { - LOG_ERROR("*** changes: %s iconName: %s ***", record.description.c_str(), record.iconName.c_str()); - features.push_back({.description = record.description, .iconName = record.iconName}); - } - } - } - -} // namespace app::whatsNew::models diff --git a/products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewModel.hpp b/products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewModel.hpp deleted file mode 100644 index eb6a847a6..000000000 --- a/products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewModel.hpp +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. -// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md - -#pragma once - -#include -#include - -namespace app -{ - class ApplicationCommon; -} - -namespace app::whatsNew::models -{ - struct Feature - { - const std::string description; - const std::string iconName; - }; - - class WhatsNewModel - { - public: - explicit WhatsNewModel(app::ApplicationCommon *app); - - private: - app::ApplicationCommon *app{nullptr}; - std::vector features; - }; -} // namespace app::whatsNew::models diff --git a/products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewFeaturesPresenter.cpp b/products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewFeaturesPresenter.cpp new file mode 100644 index 000000000..7d733c9b2 --- /dev/null +++ b/products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewFeaturesPresenter.cpp @@ -0,0 +1,49 @@ +// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "WhatsNewFeaturesPresenter.hpp" +#include "WhatsNewFeaturesLayout.hpp" +#include + +namespace app::whatsnew +{ + WhatsNewFeaturesPresenter::WhatsNewFeaturesPresenter(std::unique_ptr &&model) + : model{std::move(model)} + { + createLayouts(); + } + + auto WhatsNewFeaturesPresenter::getLayouts() const -> std::vector + { + return layouts; + } + + auto WhatsNewFeaturesPresenter::isLastLayout(const gui::Item *layout) const -> bool + { + return !layouts.empty() && (layouts.back() == layout); + } + + auto WhatsNewFeaturesPresenter::getFirstLayout() const -> gui::Item * + { + return layouts.empty() ? nullptr : layouts.front(); + } + + auto WhatsNewFeaturesPresenter::createLayouts() -> void + { + const auto &features = model->getFeatures(); + layouts.reserve(features.size()); + + for (auto it = features.begin(); it != features.end(); ++it) { + const auto isFirst = (it == features.begin()); + const auto isLast = (it == std::prev(features.end())); + + auto layout = new gui::WhatsNewFeaturesLayout(it->title, it->description, it->iconName, !isFirst, !isLast); + layouts.emplace_back(layout); + } + } + + auto WhatsNewFeaturesPresenter::setCurrentOsVersion() -> void + { + model->setCurrentOsVersion(VERSION); + } +} // namespace app::whatsnew diff --git a/products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewFeaturesPresenter.hpp b/products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewFeaturesPresenter.hpp new file mode 100644 index 000000000..29d22fcc0 --- /dev/null +++ b/products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewFeaturesPresenter.hpp @@ -0,0 +1,61 @@ +// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include "WhatsNewFeaturesModel.hpp" +#include +#include + +namespace app +{ + class ApplicationCommon; +} + +namespace gui +{ + class Item; +} + +namespace app::whatsnew +{ + class WhatsNewFeaturesContract + { + public: + class View + { + public: + virtual ~View() = default; + }; + + class Presenter : public BasePresenter + { + public: + virtual ~Presenter() = default; + + [[nodiscard]] virtual auto getLayouts() const -> std::vector = 0; + [[nodiscard]] virtual auto isLastLayout(const gui::Item *layout) const -> bool = 0; + [[nodiscard]] virtual auto getFirstLayout() const -> gui::Item * = 0; + + virtual auto setCurrentOsVersion() -> void = 0; + }; + }; + + class WhatsNewFeaturesPresenter : public WhatsNewFeaturesContract::Presenter + { + public: + explicit WhatsNewFeaturesPresenter(std::unique_ptr &&model); + + [[nodiscard]] auto getLayouts() const -> std::vector override; + [[nodiscard]] auto isLastLayout(const gui::Item *layout) const -> bool override; + [[nodiscard]] auto getFirstLayout() const -> gui::Item * override; + + auto setCurrentOsVersion() -> void override; + + private: + auto createLayouts() -> void; + + std::vector layouts; + std::unique_ptr model; + }; +} // namespace app::whatsnew diff --git a/products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewMainPresenter.cpp b/products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewMainPresenter.cpp new file mode 100644 index 000000000..a644a3d35 --- /dev/null +++ b/products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewMainPresenter.cpp @@ -0,0 +1,18 @@ +// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "WhatsNewMainPresenter.hpp" +#include +#include +#include + +namespace app::whatsnew +{ + WhatsNewMainPresenter::WhatsNewMainPresenter(settings::Settings *settings) : settings{settings} + {} + + auto WhatsNewMainPresenter::setCurrentOsVersion() -> void + { + settings->setValue(settings::SystemProperties::osCurrentVersion, VERSION, settings::SettingsScope::Global); + } +} // namespace app::whatsnew diff --git a/products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewMainPresenter.hpp b/products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewMainPresenter.hpp new file mode 100644 index 000000000..04ee183dc --- /dev/null +++ b/products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewMainPresenter.hpp @@ -0,0 +1,42 @@ +// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include +#include + +namespace settings +{ + class Settings; +} + +namespace app::whatsnew +{ + class WhatsNewMainContract + { + public: + class View + { + public: + virtual ~View() = default; + }; + + class Presenter : public BasePresenter + { + public: + virtual ~Presenter() = default; + virtual auto setCurrentOsVersion() -> void = 0; + }; + }; + + class WhatsNewMainPresenter : public WhatsNewMainContract::Presenter + { + public: + explicit WhatsNewMainPresenter(settings::Settings *settings); + auto setCurrentOsVersion() -> void override; + + private: + settings::Settings *settings{nullptr}; + }; +} // namespace app::whatsnew diff --git a/products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewPresenter.cpp b/products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewPresenter.cpp deleted file mode 100644 index 45255b1c6..000000000 --- a/products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewPresenter.cpp +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. -// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md - -#include "WhatsNewPresenter.hpp" - -namespace app::whatsNew -{ - WhatsNewPresenter::WhatsNewPresenter(AbstractBatteryModel &batteryModel, - AbstractLowBatteryInfoModel &lowBatteryInfoModel) - : batteryModel{batteryModel}, lowBatteryInfoModel{lowBatteryInfoModel} - {} - - Store::Battery WhatsNewPresenter::getBatteryState() - { - return batteryModel.getLevelState(); - } - - bool WhatsNewPresenter::isBatteryCharging(Store::Battery::State state) const - { - return batteryModel.isBatteryCharging(state); - } - - bool WhatsNewPresenter::isBatteryBelowLowLevelThreshold(units::SOC soc) const - { - return soc < constants::lowBatteryInfoThreshold; - } - - bool WhatsNewPresenter::isLowBatteryWindowHandled() const - { - return lowBatteryInfoModel.isInfoHandled(); - } - - void WhatsNewPresenter::handleLowBatteryWindow() - { - lowBatteryInfoModel.handleInfo(); - } -} // namespace app::whatsNew diff --git a/products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewPresenter.hpp b/products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewPresenter.hpp deleted file mode 100644 index 660091b77..000000000 --- a/products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewPresenter.hpp +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. -// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md - -#pragma once - -#include -#include -#include - -namespace app -{ - class ApplicationCommon; -} - -namespace app::whatsNew -{ - class WhatsNewContract - { - public: - class View - { - public: - virtual ~View() = default; - }; - - class Presenter : public BasePresenter - { - public: - virtual ~Presenter() = default; - virtual Store::Battery getBatteryState() = 0; - virtual bool isBatteryCharging(Store::Battery::State state) const = 0; - virtual bool isBatteryBelowLowLevelThreshold(units::SOC soc) const = 0; - [[nodiscard]] virtual bool isLowBatteryWindowHandled() const = 0; - virtual void handleLowBatteryWindow() = 0; - }; - }; - - class WhatsNewPresenter : public WhatsNewContract::Presenter - { - AbstractBatteryModel &batteryModel; - AbstractLowBatteryInfoModel &lowBatteryInfoModel; - - Store::Battery getBatteryState() override; - [[nodiscard]] bool isBatteryCharging(Store::Battery::State state) const override; - [[nodiscard]] bool isBatteryBelowLowLevelThreshold(units::SOC soc) const override; - [[nodiscard]] bool isLowBatteryWindowHandled() const override; - void handleLowBatteryWindow() override; - - public: - WhatsNewPresenter(AbstractBatteryModel &batteryModel, AbstractLowBatteryInfoModel &lowBatteryInfoModel); - }; -} // namespace app::whatsNew diff --git a/products/BellHybrid/apps/application-bell-whats-new/widgets/WhatsNewFeaturesLayout.cpp b/products/BellHybrid/apps/application-bell-whats-new/widgets/WhatsNewFeaturesLayout.cpp new file mode 100644 index 000000000..0ee3bd15e --- /dev/null +++ b/products/BellHybrid/apps/application-bell-whats-new/widgets/WhatsNewFeaturesLayout.cpp @@ -0,0 +1,111 @@ +// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "WhatsNewFeaturesLayout.hpp" +#include "WhatsNewStyle.hpp" +#include + +namespace gui +{ + WhatsNewFeaturesLayout::WhatsNewFeaturesLayout(const std::string &title, + const std::string &description, + const std::string &iconName, + bool leftArrowState, + bool rightArrowState) + : VBox(nullptr, + 0, + 0, + whats_new_style::features_window::layout::width, + whats_new_style::features_window::layout::height) + { + buildInterface(title, description, iconName, leftArrowState, rightArrowState); + } + + auto WhatsNewFeaturesLayout::buildInterface(const std::string &title, + const std::string &description, + const std::string &iconName, + bool leftArrowState, + bool rightArrowState) -> void + { + setAlignment(Alignment::Horizontal::Center); + setEdges(rectangle_enums::RectangleEdge::None); + + /* Main container */ + auto mainContainer = new HThreeBox(this); + mainContainer->setMinimumSize(whats_new_style::features_window::container::width, + whats_new_style::features_window::container::height); + mainContainer->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center)); + mainContainer->setMargins(Margins(0, whats_new_style::features_window::container::margin_top, 0, 0)); + mainContainer->setEdges(RectangleEdge::None); + + /* Left box - with arrow */ + mainContainer->firstBox = new HBox(mainContainer); + mainContainer->firstBox->setAlignment(Alignment(Alignment::Vertical::Center)); + mainContainer->firstBox->setEdges(RectangleEdge::None); + mainContainer->firstBox->activeItem = false; + + auto leftArrow = new ImageBox(nullptr, new Image("bell_arrow_left_W_M")); + leftArrow->setAlignment(Alignment(Alignment::Horizontal::Right, Alignment::Vertical::Center)); + leftArrow->setMinimumSizeToFitImage(); + leftArrow->setVisible(leftArrowState); + leftArrow->setEdges(RectangleEdge::None); + mainContainer->firstBox->setMinimumSize(leftArrow->widgetMinimumArea.w, leftArrow->widgetMinimumArea.h); + mainContainer->firstBox->addWidget(leftArrow); + + /* Center box - icon, title and description */ + mainContainer->centerBox = new VBox(mainContainer); + mainContainer->centerBox->setEdges(RectangleEdge::None); + mainContainer->centerBox->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top)); + mainContainer->centerBox->setMinimumSize(whats_new_style::features_window::center_box::width, + whats_new_style::features_window::center_box::height); + mainContainer->centerBox->setMaximumSize(whats_new_style::features_window::center_box::width, + whats_new_style::features_window::center_box::height); + + auto iconImage = new ImageBox(nullptr, new Image(iconName)); + iconImage->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top)); + iconImage->setMinimumSizeToFitImage(); + iconImage->setMaximumSize(whats_new_style::features_window::icon::width, + whats_new_style::features_window::icon::height); + + auto titleText = new Text(nullptr, + 0, + 0, + whats_new_style::features_window::title::width, + whats_new_style::features_window::title::height); + titleText->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top)); + titleText->setMargins(Margins(0, whats_new_style::features_window::title::margin_top, 0, 0)); + titleText->setTextType(TextType::SingleLine); + titleText->setFont(whats_new_style::features_window::title::font); + titleText->setText(title); + + auto descriptionText = new Text(nullptr, + 0, + 0, + whats_new_style::features_window::description::width, + whats_new_style::features_window::description::height); + descriptionText->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top)); + descriptionText->setMargins(Margins(0, whats_new_style::features_window::description::margin_top, 0, 0)); + descriptionText->setFont(whats_new_style::features_window::description::font); + descriptionText->setText(description); + + mainContainer->centerBox->addWidget(iconImage); + mainContainer->centerBox->addWidget(titleText); + mainContainer->centerBox->addWidget(descriptionText); + + /* Right box */ + mainContainer->lastBox = new HBox(mainContainer); + mainContainer->lastBox->setAlignment(Alignment(Alignment::Vertical::Center)); + mainContainer->lastBox->setEdges(RectangleEdge::None); + mainContainer->lastBox->activeItem = false; + + auto rightArrow = new ImageBox(nullptr, new Image("bell_arrow_right_W_M")); + rightArrow->setAlignment(Alignment(Alignment::Horizontal::Left, Alignment::Vertical::Center)); + rightArrow->setMinimumSizeToFitImage(); + rightArrow->setVisible(rightArrowState); + rightArrow->setEdges(RectangleEdge::None); + mainContainer->lastBox->setMinimumSize(rightArrow->widgetMinimumArea.w, rightArrow->widgetMinimumArea.h); + mainContainer->lastBox->addWidget(rightArrow); + + resizeItems(); + } +} // namespace gui diff --git a/products/BellHybrid/apps/application-bell-whats-new/widgets/WhatsNewFeaturesLayout.hpp b/products/BellHybrid/apps/application-bell-whats-new/widgets/WhatsNewFeaturesLayout.hpp new file mode 100644 index 000000000..cd9a6a33f --- /dev/null +++ b/products/BellHybrid/apps/application-bell-whats-new/widgets/WhatsNewFeaturesLayout.hpp @@ -0,0 +1,26 @@ +// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include + +namespace gui +{ + class WhatsNewFeaturesLayout : public VBox + { + public: + WhatsNewFeaturesLayout(const std::string &title, + const std::string &description, + const std::string &iconName, + bool leftArrowState = true, + bool rightArrowState = true); + + private: + auto buildInterface(const std::string &title, + const std::string &description, + const std::string &iconName, + bool leftArrowState, + bool rightArrowState) -> void; + }; +} // namespace gui diff --git a/products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewFeaturesWindow.cpp b/products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewFeaturesWindow.cpp new file mode 100644 index 000000000..af5755e72 --- /dev/null +++ b/products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewFeaturesWindow.cpp @@ -0,0 +1,85 @@ +// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "WhatsNewFeaturesWindow.hpp" + +#include +#include +#include +#include + +namespace +{ + constexpr auto endWindowTimeout = std::chrono::seconds{5}; +} + +namespace app::whatsnew +{ + using namespace gui; + + WhatsNewFeaturesWindow::WhatsNewFeaturesWindow(app::ApplicationCommon *app, + std::unique_ptr &&presenter, + const std::string &name) + : AppWindow(app, name), presenter{std::move(presenter)} + { + buildInterface(); + } + + auto WhatsNewFeaturesWindow::buildInterface() -> void + { + AppWindow::buildInterface(); + + statusBar->setVisible(false); + header->setTitleVisibility(false); + navBar->setVisible(false); + + layouts = presenter->getLayouts(); + + itemSpinner = new WidgetSpinner(this, {layouts.begin(), layouts.end()}, Boundaries::Fixed); + itemSpinner->setSize(style::window_width, style::window_height); + itemSpinner->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center)); + itemSpinner->setFocusEdges(RectangleEdge::None); + itemSpinner->setCurrentValue(presenter->getFirstLayout()); + + itemSpinner->onValueChanged = [this]([[maybe_unused]] const auto &value) { + getApplication()->render(gui::RefreshModes::GUI_REFRESH_DEEP); + }; + + setFocusItem(itemSpinner); + } + + auto WhatsNewFeaturesWindow::onInput(const gui::InputEvent &inputEvent) -> bool + { + /* Prevent leaving by long-pressing back */ + if (inputEvent.isLongRelease(gui::KeyCode::KEY_RF)) { + return true; + } + if (inputEvent.isShortRelease(gui::KeyCode::KEY_RF) || + (inputEvent.isShortRelease(gui::KeyCode::KEY_ENTER) && isLastLayout())) { + presenter->setCurrentOsVersion(); + switchToEndWindow(); + return true; + } + if (itemSpinner->onInput(inputEvent)) { + return true; + } + return AppWindow::onInput(inputEvent); + } + + auto WhatsNewFeaturesWindow::isLastLayout() -> bool + { + return itemSpinner->getCurrentValue() == layouts.back(); + } + + auto WhatsNewFeaturesWindow::switchToEndWindow() -> void + { + using ExitBehaviour = gui::BellFinishedWindowData::ExitBehaviour; + application->switchWindow( + gui::window::bell_finished::defaultName, + gui::BellFinishedWindowData::Factory::create("big_namaste_W_G", + "", + utils::translate("app_bell_whatsnew_end_screen_text"), + ExitBehaviour::ReturnToHomescreen, + endWindowTimeout)); + } +} // namespace app::whatsnew diff --git a/products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewFeaturesWindow.hpp b/products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewFeaturesWindow.hpp new file mode 100644 index 000000000..8c1cb2867 --- /dev/null +++ b/products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewFeaturesWindow.hpp @@ -0,0 +1,31 @@ +// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#pragma once + +#include "WhatsNewCommon.hpp" +#include +#include +#include + +namespace app::whatsnew +{ + class WhatsNewFeaturesWindow : public gui::AppWindow, public WhatsNewFeaturesContract::View + { + public: + WhatsNewFeaturesWindow(app::ApplicationCommon *app, + std::unique_ptr &&presenter, + const std::string &name = window::name::features); + + auto buildInterface() -> void override; + auto onInput(const gui::InputEvent &inputEvent) -> bool override; + + private: + std::unique_ptr presenter; + gui::WidgetSpinner *itemSpinner{nullptr}; + std::vector layouts; + + auto isLastLayout() -> bool; + auto switchToEndWindow() -> void; + }; +} // namespace app::whatsnew diff --git a/products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewMainWindow.cpp b/products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewMainWindow.cpp new file mode 100644 index 000000000..41fe5795d --- /dev/null +++ b/products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewMainWindow.cpp @@ -0,0 +1,51 @@ +// Copyright (c) 2017-2024, Mudita Sp. z.o.o. All rights reserved. +// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md + +#include "WhatsNewMainWindow.hpp" +#include "WhatsNewStyle.hpp" +#include +#include +#include + +namespace app::whatsnew +{ + using namespace gui; + + WhatsNewMainWindow::WhatsNewMainWindow(app::ApplicationCommon *app, + std::unique_ptr &&presenter, + const std::string &name) + : BellOptionWithDescriptionWindow(app, name), presenter{std::move(presenter)} + { + addOptions(settingsOptionsList()); + setListTitle(utils::translate("app_bell_whatsnew_title"), whats_new_style::main_window::list_title_font); + setListDescription(utils::translate("app_bell_whatsnew_version"), + gui::BellOptionWithDescriptionWindow::TokenMap({{"$VERSION", std::string(VERSION)}}), + whats_new_style::main_window::description_font, + whats_new_style::main_window::description_height); + } + + auto WhatsNewMainWindow::settingsOptionsList() -> std::list