M image/system_a/data/lang/English.json => image/system_a/data/lang/English.json +5 -0
@@ 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": "<text>OS version: <token>$VERSION</token></text>",
+ "app_bell_whatsnew_continue": "Continue",
+ "app_bell_whatsnew_skip": "Skip",
+ "app_bell_whatsnew_end_screen_text": "<text>We'd love to hear your feedback about this update at<br/><b>mudita.com/forum</b></text>",
"app_bell_relaxation_loop": "loop",
"app_bell_relaxation_loop_description": "the song will play until you turn it off",
"app_bell_relaxation_looped": "looped",
M module-apps/apps-common/widgets/BellSideListItem.hpp => module-apps/apps-common/widgets/BellSideListItem.hpp +1 -1
@@ 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);
M module-db/Common/Types.hpp => module-db/Common/Types.hpp +2 -2
@@ 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,"
D products/BellHybrid/apps/application-bell-background-sounds/ApplicationBellBackgroundSounds.cpp => products/BellHybrid/apps/application-bell-background-sounds/ApplicationBellBackgroundSounds.cpp +0 -0
M products/BellHybrid/apps/application-bell-meditation-timer/CMakeLists.txt => products/BellHybrid/apps/application-bell-meditation-timer/CMakeLists.txt +0 -1
@@ 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
D products/BellHybrid/apps/application-bell-meditation-timer/presenter/SessionEndedPresenter.cpp => products/BellHybrid/apps/application-bell-meditation-timer/presenter/SessionEndedPresenter.cpp +0 -17
@@ 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 <service-appmgr/Controller.hpp>
-
-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
M products/BellHybrid/apps/application-bell-onboarding/ApplicationBellOnBoarding.cpp => products/BellHybrid/apps/application-bell-onboarding/ApplicationBellOnBoarding.cpp +0 -1
@@ 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<gui::BellPowerOffPresenter>(app);
return std::make_unique<gui::OnBoardingOnOffWindow>(app, std::move(powerOffPresenter), name);
M products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.hpp => products/BellHybrid/apps/application-bell-powernap/data/PowerNapListItem.hpp +2 -1
@@ 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 <apps-common/widgets/BellSideListItem.hpp>
#include <apps-common/widgets/spinners/Spinners.hpp>
M products/BellHybrid/apps/application-bell-settings/windows/AboutYourBellWindow.cpp => products/BellHybrid/apps/application-bell-settings/windows/AboutYourBellWindow.cpp +2 -2
@@ 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(
M products/BellHybrid/apps/application-bell-whats-new/ApplicationWhatsNew.cpp => products/BellHybrid/apps/application-bell-whats-new/ApplicationWhatsNew.cpp +22 -13
@@ 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 <common/windows/BellFinishedWindow.hpp>
#include <common/windows/AppsBatteryStatusWindow.hpp>
#include <system/messages/SentinelRegistrationMessage.hpp>
@@ 33,10 35,6 @@ namespace app
return ret;
}
- whatsNewModel = std::make_unique<whatsNew::models::WhatsNewModel>(this);
-
- batteryModel = std::make_unique<app::BatteryModel>(this);
- lowBatteryInfoModel = std::make_unique<app::LowBatteryInfoModel>();
cpuSentinel = std::make_shared<sys::CpuSentinel>(applicationWhatsNewName, this);
auto sentinelRegistrationMsg = std::make_shared<sys::SentinelRegistrationMessage>(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<app::whatsNew::WhatsNewPresenter>(*batteryModel, *lowBatteryInfoModel);
- return std::make_unique<whatsNew::WhatsNewWindow>(app, std::move(presenter));
+ windowsFactory.attach(whatsnew::window::name::main, [this](ApplicationCommon *app, const std::string &name) {
+ auto presenter = std::make_unique<whatsnew::WhatsNewMainPresenter>(settings.get());
+ return std::make_unique<whatsnew::WhatsNewMainWindow>(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<whatsnew::models::WhatsNewFeaturesModel>(this, settings.get());
+ auto presenter = std::make_unique<whatsnew::WhatsNewFeaturesPresenter>(std::move(model));
+ return std::make_unique<whatsnew::WhatsNewFeaturesWindow>(app, std::move(presenter), name);
+ });
+ windowsFactory.attach(gui::window::bell_finished::defaultName,
[](ApplicationCommon *app, const std::string &name) {
- return std::make_unique<gui::AppsBatteryStatusWindow>(app, name);
+ return std::make_unique<gui::BellFinishedWindow>(app, name);
});
+ // windowsFactory.attach(whatsnew::window::name::whatsNewLowBattery,
+ // [](ApplicationCommon *app, const std::string &name) {
+ // return std::make_unique<gui::AppsBatteryStatusWindow>(app, name);
+ // });
+
attachPopups({gui::popup::ID::AlarmActivated,
gui::popup::ID::AlarmDeactivated,
gui::popup::ID::PowerOff,
M products/BellHybrid/apps/application-bell-whats-new/CMakeLists.txt => products/BellHybrid/apps/application-bell-whats-new/CMakeLists.txt +11 -4
@@ 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
M products/BellHybrid/apps/application-bell-whats-new/data/WhatsNewCommon.hpp => products/BellHybrid/apps/application-bell-whats-new/data/WhatsNewCommon.hpp +4 -4
@@ 5,12 5,12 @@
#include <AppWindowConstants.hpp>
-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
M products/BellHybrid/apps/application-bell-whats-new/data/WhatsNewStyle.hpp => products/BellHybrid/apps/application-bell-whats-new/data/WhatsNewStyle.hpp +53 -2
@@ 6,5 6,56 @@
#include <Style.hpp>
#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
M products/BellHybrid/apps/application-bell-whats-new/include/application-bell-whats-new/ApplicationWhatsNew.hpp => products/BellHybrid/apps/application-bell-whats-new/include/application-bell-whats-new/ApplicationWhatsNew.hpp +12 -11
@@ 7,25 7,26 @@
#include <common/models/BatteryModel.hpp>
#include <common/models/LowBatteryInfoModel.hpp>
-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<whatsNew::models::WhatsNewModel> whatsNewModel;
+ std::unique_ptr<whatsnew::models::WhatsNewFeaturesModel> whatsNewModel;
std::unique_ptr<AbstractBatteryModel> batteryModel;
std::unique_ptr<AbstractLowBatteryInfoModel> lowBatteryInfoModel;
R products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewModel.cpp => products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewFeaturesModel.cpp +34 -19
@@ 1,38 1,40 @@
// 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 "WhatsNewFeaturesModel.hpp"
#include <ApplicationCommon.hpp>
#include <db/ServiceDB.hpp>
#include <db/WhatsNewMessages.hpp>
-#include <product/version.hpp>
+#include <service-db/Settings.hpp>
+#include <service-db/agents/settings/SystemSettings.hpp>
#include <Utils.hpp>
namespace
{
- using namespace service::db::whatsNew;
- constexpr auto versionSize{3U};
+ using namespace service::db::whatsnew;
- std::optional<VersionNumber> getVersionNumber(std::string version)
+ auto getVersionNumber(const std::string &version) -> std::optional<VersionNumber>
{
+ constexpr auto versionSize{3U};
+
std::vector<std::string> strVector{utils::split(version, '.')};
if (strVector.size() != versionSize) {
- return std::nullopt;
+ return {};
}
std::vector<std::uint16_t> uintVector{};
uintVector.reserve(versionSize);
- for (auto &str : strVector) {
+ for (const auto &str : strVector) {
if (!utils::is_number(str)) {
- return std::nullopt;
+ return {};
}
uintVector.push_back(utils::getNumericValue<std::uint16_t>(str));
}
- return VersionNumber{.major{uintVector[0]}, .minor{uintVector[1]}, .patch{uintVector[2]}};
+ return VersionNumber{uintVector[0], uintVector[1], uintVector[2]};
}
- std::optional<messages::Response> sendDBRequest(sys::Service *serv, std::shared_ptr<sys::Message> &&msg)
+ auto sendDBRequest(sys::Service *serv, std::shared_ptr<sys::Message> &&msg) -> std::optional<messages::Response>
{
const auto ret = serv->bus.sendUnicastSync(std::move(msg), service::name::db, sys::BusProxy::defaultTimeout);
if (ret.first == sys::ReturnCodes::Success) {
@@ 40,25 42,38 @@ namespace
return *resp;
}
}
- return std::nullopt;
+ return {};
}
} // namespace
-namespace app::whatsNew::models
+namespace app::whatsnew::models
{
- WhatsNewModel::WhatsNewModel(app::ApplicationCommon *app) : app{app}
+ WhatsNewFeaturesModel::WhatsNewFeaturesModel(app::ApplicationCommon *app, settings::Settings *settings)
+ : settings{settings}
{
- const auto version = getVersionNumber(VERSION);
+ 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<messages::GetByVersion>(version.value()));
+
+ const auto &result = sendDBRequest(app, std::make_shared<messages::GetByVersion>(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});
+ for (const auto &record : result->records) {
+ features.push_back(Feature{record.title, record.description, record.iconName});
}
}
}
-} // namespace app::whatsNew::models
+ auto WhatsNewFeaturesModel::getFeatures() -> std::vector<Feature>
+ {
+ return features;
+ }
+
+ auto WhatsNewFeaturesModel::setCurrentOsVersion(const std::string &version) -> void
+ {
+ settings->setValue(settings::SystemProperties::osCurrentVersion, version, settings::SettingsScope::Global);
+ }
+} // namespace app::whatsnew::models
R products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewModel.hpp => products/BellHybrid/apps/application-bell-whats-new/models/WhatsNewFeaturesModel.hpp +16 -6
@@ 11,21 11,31 @@ namespace app
class ApplicationCommon;
}
-namespace app::whatsNew::models
+namespace settings
+{
+ class Settings;
+}
+
+namespace app::whatsnew::models
{
struct Feature
{
- const std::string description;
- const std::string iconName;
+ std::string title;
+ std::string description;
+ std::string iconName;
};
- class WhatsNewModel
+ class WhatsNewFeaturesModel
{
public:
- explicit WhatsNewModel(app::ApplicationCommon *app);
+ WhatsNewFeaturesModel(app::ApplicationCommon *app, settings::Settings *settings);
+
+ auto getFeatures() -> std::vector<Feature>;
+ auto setCurrentOsVersion(const std::string &version) -> void;
private:
app::ApplicationCommon *app{nullptr};
+ settings::Settings *settings{nullptr};
std::vector<Feature> features;
};
-} // namespace app::whatsNew::models
+} // namespace app::whatsnew::models
A products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewFeaturesPresenter.cpp => products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewFeaturesPresenter.cpp +49 -0
@@ 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 <product/version.hpp>
+
+namespace app::whatsnew
+{
+ WhatsNewFeaturesPresenter::WhatsNewFeaturesPresenter(std::unique_ptr<models::WhatsNewFeaturesModel> &&model)
+ : model{std::move(model)}
+ {
+ createLayouts();
+ }
+
+ auto WhatsNewFeaturesPresenter::getLayouts() const -> std::vector<gui::Item *>
+ {
+ 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
A products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewFeaturesPresenter.hpp => products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewFeaturesPresenter.hpp +61 -0
@@ 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 <apps-common/BasePresenter.hpp>
+#include <memory>
+
+namespace app
+{
+ class ApplicationCommon;
+}
+
+namespace gui
+{
+ class Item;
+}
+
+namespace app::whatsnew
+{
+ class WhatsNewFeaturesContract
+ {
+ public:
+ class View
+ {
+ public:
+ virtual ~View() = default;
+ };
+
+ class Presenter : public BasePresenter<WhatsNewFeaturesContract::View>
+ {
+ public:
+ virtual ~Presenter() = default;
+
+ [[nodiscard]] virtual auto getLayouts() const -> std::vector<gui::Item *> = 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<models::WhatsNewFeaturesModel> &&model);
+
+ [[nodiscard]] auto getLayouts() const -> std::vector<gui::Item *> 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<gui::Item *> layouts;
+ std::unique_ptr<models::WhatsNewFeaturesModel> model;
+ };
+} // namespace app::whatsnew
A products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewMainPresenter.cpp => products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewMainPresenter.cpp +18 -0
@@ 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 <service-db/Settings.hpp>
+#include <service-db/agents/settings/SystemSettings.hpp>
+#include <product/version.hpp>
+
+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
R products/BellHybrid/apps/application-bell-meditation-timer/presenter/SessionEndedPresenter.hpp => products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewMainPresenter.hpp +17 -14
@@ 1,19 1,19 @@
-// 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 <Application.hpp>
#include <apps-common/BasePresenter.hpp>
+#include <string>
-namespace app
+namespace settings
{
- class ApplicationCommon;
+ class Settings;
}
-namespace app::meditation
+namespace app::whatsnew
{
- class SessionEndedPresenterContract
+ class WhatsNewMainContract
{
public:
class View
@@ 21,19 21,22 @@ namespace app::meditation
public:
virtual ~View() = default;
};
- class Presenter : public BasePresenter<SessionEndedPresenterContract::View>
+
+ class Presenter : public BasePresenter<WhatsNewMainContract::View>
{
public:
- virtual void activate() = 0;
+ virtual ~Presenter() = default;
+ virtual auto setCurrentOsVersion() -> void = 0;
};
};
- class SessionEndedPresenter : public SessionEndedPresenterContract::Presenter
+ class WhatsNewMainPresenter : public WhatsNewMainContract::Presenter
{
- app::ApplicationCommon *app{};
- void activate() override;
-
public:
- explicit SessionEndedPresenter(app::ApplicationCommon *app);
+ explicit WhatsNewMainPresenter(settings::Settings *settings);
+ auto setCurrentOsVersion() -> void override;
+
+ private:
+ settings::Settings *settings{nullptr};
};
-} // namespace app::meditation
+} // namespace app::whatsnew
D products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewPresenter.cpp => products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewPresenter.cpp +0 -37
@@ 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
D products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewPresenter.hpp => products/BellHybrid/apps/application-bell-whats-new/presenter/WhatsNewPresenter.hpp +0 -52
@@ 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 <apps-common/BasePresenter.hpp>
-#include <common/models/BatteryModel.hpp>
-#include <common/models/LowBatteryInfoModel.hpp>
-
-namespace app
-{
- class ApplicationCommon;
-}
-
-namespace app::whatsNew
-{
- class WhatsNewContract
- {
- public:
- class View
- {
- public:
- virtual ~View() = default;
- };
-
- class Presenter : public BasePresenter<WhatsNewContract::View>
- {
- 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
A products/BellHybrid/apps/application-bell-whats-new/widgets/WhatsNewFeaturesLayout.cpp => products/BellHybrid/apps/application-bell-whats-new/widgets/WhatsNewFeaturesLayout.cpp +111 -0
@@ 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 <TextFixedSize.hpp>
+
+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<HBox, VBox, HBox>(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
A products/BellHybrid/apps/application-bell-whats-new/widgets/WhatsNewFeaturesLayout.hpp => products/BellHybrid/apps/application-bell-whats-new/widgets/WhatsNewFeaturesLayout.hpp +26 -0
@@ 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 <ThreeBox.hpp>
+
+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
A products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewFeaturesWindow.cpp => products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewFeaturesWindow.cpp +85 -0
@@ 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 <SideListView.hpp>
+#include <common/options/OptionBellMenu.hpp>
+#include <common/data/BatteryStatusSwitchData.hpp>
+#include <common/windows/BellFinishedWindow.hpp>
+
+namespace
+{
+ constexpr auto endWindowTimeout = std::chrono::seconds{5};
+}
+
+namespace app::whatsnew
+{
+ using namespace gui;
+
+ WhatsNewFeaturesWindow::WhatsNewFeaturesWindow(app::ApplicationCommon *app,
+ std::unique_ptr<WhatsNewFeaturesContract::Presenter> &&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
A products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewFeaturesWindow.hpp => products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewFeaturesWindow.hpp +31 -0
@@ 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 <presenter/WhatsNewFeaturesPresenter.hpp>
+#include <apps-common/windows/AppWindow.hpp>
+#include <widgets/spinners/Spinners.hpp>
+
+namespace app::whatsnew
+{
+ class WhatsNewFeaturesWindow : public gui::AppWindow, public WhatsNewFeaturesContract::View
+ {
+ public:
+ WhatsNewFeaturesWindow(app::ApplicationCommon *app,
+ std::unique_ptr<WhatsNewFeaturesContract::Presenter> &&presenter,
+ const std::string &name = window::name::features);
+
+ auto buildInterface() -> void override;
+ auto onInput(const gui::InputEvent &inputEvent) -> bool override;
+
+ private:
+ std::unique_ptr<WhatsNewFeaturesContract::Presenter> presenter;
+ gui::WidgetSpinner *itemSpinner{nullptr};
+ std::vector<gui::Item *> layouts;
+
+ auto isLastLayout() -> bool;
+ auto switchToEndWindow() -> void;
+ };
+} // namespace app::whatsnew
A products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewMainWindow.cpp => products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewMainWindow.cpp +51 -0
@@ 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 <common/options/OptionBellMenu.hpp>
+#include <service-appmgr/Controller.hpp>
+#include <product/version.hpp>
+
+namespace app::whatsnew
+{
+ using namespace gui;
+
+ WhatsNewMainWindow::WhatsNewMainWindow(app::ApplicationCommon *app,
+ std::unique_ptr<WhatsNewMainContract::Presenter> &&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<Option>
+ {
+ std::list<Option> settingsOptionList;
+
+ auto addWinSettings = [&](const UTF8 &name, const std::function<bool(Item &)> &activatedCallback) {
+ settingsOptionList.emplace_back(std::make_unique<option::OptionBellMenu>(
+ name, activatedCallback, []([[maybe_unused]] Item &item) { return true; }, this));
+ };
+
+ addWinSettings(utils::translate("app_bell_whatsnew_continue"), [this]([[maybe_unused]] Item &item) {
+ application->switchWindow(window::name::features);
+ return true;
+ });
+ addWinSettings(utils::translate("app_bell_whatsnew_skip"), [this]([[maybe_unused]] Item &item) {
+ presenter->setCurrentOsVersion();
+ app::manager::Controller::sendAction(application, app::manager::actions::Home);
+ return true;
+ });
+
+ return settingsOptionList;
+ }
+
+ auto WhatsNewMainWindow::onBeforeShow([[maybe_unused]] ShowMode mode, [[maybe_unused]] SwitchData *data) -> void
+ {}
+} // namespace app::whatsnew
R products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewWindow.hpp => products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewMainWindow.hpp +12 -14
@@ 4,26 4,24 @@
#pragma once
#include "WhatsNewCommon.hpp"
-#include <presenter/WhatsNewPresenter.hpp>
+#include "WhatsNewMainPresenter.hpp"
+#include <common/options/BellOptionWithDescriptionWindow.hpp>
-#include <apps-common/windows/AppWindow.hpp>
-
-namespace app::whatsNew
+namespace app::whatsnew
{
using namespace gui;
- class WhatsNewWindow : public gui::AppWindow, public WhatsNewContract::View
+ class WhatsNewMainWindow : public BellOptionWithDescriptionWindow
{
public:
- WhatsNewWindow(app::ApplicationCommon *app,
- std::unique_ptr<WhatsNewContract::Presenter> &&presenter,
- const std::string &name = window::name::main);
-
- void buildInterface() override;
- void onBeforeShow(gui::ShowMode mode, gui::SwitchData *data) override;
- bool onInput(const gui::InputEvent &inputEvent) override;
+ WhatsNewMainWindow(app::ApplicationCommon *app,
+ std::unique_ptr<WhatsNewMainContract::Presenter> &&presenter,
+ const std::string &name = window::name::main);
+ auto onBeforeShow(ShowMode mode, SwitchData *data) -> void override;
private:
- std::unique_ptr<WhatsNewContract::Presenter> presenter;
+ std::unique_ptr<WhatsNewMainContract::Presenter> presenter;
+
+ auto settingsOptionsList() -> std::list<Option>;
};
-} // namespace app::whatsNew
+} // namespace app::whatsnew
D products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewWindow.cpp => products/BellHybrid/apps/application-bell-whats-new/windows/WhatsNewWindow.cpp +0 -35
@@ 1,35 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 "WhatsNewWindow.hpp"
-
-#include <common/options/OptionBellMenu.hpp>
-#include <common/data/BatteryStatusSwitchData.hpp>
-
-namespace app::whatsNew
-{
- using namespace gui;
-
- WhatsNewWindow::WhatsNewWindow(app::ApplicationCommon *app,
- std::unique_ptr<WhatsNewContract::Presenter> &&presenter,
- const std::string &name)
- : AppWindow(app, name), presenter{std::move(presenter)}
- {
- buildInterface();
- }
-
- void WhatsNewWindow::buildInterface()
- {
- AppWindow::buildInterface();
- }
-
- void WhatsNewWindow::onBeforeShow(gui::ShowMode mode, gui::SwitchData *data)
- {
- AppWindow::onBeforeShow(mode, data);
- }
-
- bool WhatsNewWindow::onInput(const gui::InputEvent &inputEvent)
- {
- return AppWindow::onInput(inputEvent);
- }
-} // namespace app::whatsNew
M products/BellHybrid/apps/common/include/common/layouts/UpdateInstructionLayoutClassic.hpp => products/BellHybrid/apps/common/include/common/layouts/UpdateInstructionLayoutClassic.hpp +0 -2
@@ 10,8 10,6 @@
namespace gui
{
- class BellBaseLayout;
-
using Instruction = std::vector<std::pair<std::string, UTF8>>;
class UpdateInstructionLayoutClassic : public UpdateInstructionLayoutProvider, VBox
M products/BellHybrid/apps/common/include/common/options/BellOptionWithDescriptionWindow.hpp => products/BellHybrid/apps/common/include/common/options/BellOptionWithDescriptionWindow.hpp +12 -6
@@ 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
#pragma once
@@ 12,17 12,23 @@ namespace gui
{
class BellOptionWithDescriptionWindow : public AppWindow, protected OptionsList<ListView>
{
- protected:
- BellBaseLayout *body{};
-
public:
+ using TokenMap = std::optional<text::RichTextParser::TokenMap>;
+ static constexpr auto defaultDescriptionHeight = 175U;
+
BellOptionWithDescriptionWindow(app::ApplicationCommon *app, const std::string &name);
- void setListTitle(const std::string &title);
- void setListDescription(const std::string &title);
+ void setListTitle(const std::string &title, const std::string &font = style::window::font::largelight);
+ void setListDescription(const std::string &title,
+ TokenMap tokenMap = {},
+ const std::string &font = style::window::font::verybiglight,
+ unsigned height = defaultDescriptionHeight);
void onBeforeShow(ShowMode mode, SwitchData *data) override;
void onClose(CloseReason reason) override;
void rebuild() override;
void buildInterface() override;
+
+ protected:
+ BellBaseLayout *body{nullptr};
};
}; // namespace gui
M products/BellHybrid/apps/common/include/common/windows/UpdateInstructionWindow.hpp => products/BellHybrid/apps/common/include/common/windows/UpdateInstructionWindow.hpp +1 -5
@@ 10,23 10,19 @@
namespace gui
{
- class SideListView;
class UpdateInstructionWindow : public AppWindow, public UpdateInstructionWindowContract::View
{
std::unique_ptr<UpdateInstructionWindowContract::Presenter> presenter;
- SideListView *sideListView = nullptr;
WidgetSpinner *spinner = nullptr;
bool onInput(const gui::InputEvent &inputEvent) override;
void buildInterface() override;
- void onValueChanged(const std::uint32_t currentValue);
-
public:
UpdateInstructionWindow(app::ApplicationCommon *app,
std::unique_ptr<UpdateInstructionWindowContract::Presenter> &&presenter,
const std::string &name);
- bool isLastLayout() const;
+ [[nodiscard]] bool isLastLayout() const;
};
} // namespace gui
M products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassicWithQuotes.cpp => products/BellHybrid/apps/common/src/layouts/HomeScreenLayoutClassicWithQuotes.cpp +1 -2
@@ 148,5 148,4 @@ namespace gui
connectionBox->setVisible(connectionStatus->isVisible());
widgetBox->informContentChanged();
}
-
-}; // namespace gui
+} // namespace gui
M products/BellHybrid/apps/common/src/options/BellOptionWithDescriptionWindow.cpp => products/BellHybrid/apps/common/src/options/BellOptionWithDescriptionWindow.cpp +17 -10
@@ 14,8 14,7 @@ namespace gui
{
constexpr auto one_option_height = style::bell_options::h + 2U * style::bell_options::option_margin;
constexpr auto option_layout_height = 2U * one_option_height;
- constexpr auto description_height = 175U;
- constexpr auto max_description_height = description_height + 16U;
+ constexpr auto max_to_min_difference = 16U;
constexpr auto top_center_margin = -14;
} // namespace
@@ 62,12 61,12 @@ namespace gui
setFocusItem(optionsList);
}
- void BellOptionWithDescriptionWindow::setListTitle(const std::string &title)
+ void BellOptionWithDescriptionWindow::setListTitle(const std::string &title, const std::string &font)
{
auto titleBody = new TextFixedSize(body->firstBox);
titleBody->drawUnderline(false);
titleBody->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Top));
- titleBody->setFont(style::window::font::largelight);
+ titleBody->setFont(font);
titleBody->setMinimumWidth(style::bell_base_layout::outer_layouts_w);
titleBody->setEdges(RectangleEdge::None);
titleBody->setEditMode(EditMode::Browse);
@@ 80,19 79,27 @@ namespace gui
body->resizeItems();
}
- void BellOptionWithDescriptionWindow::setListDescription(const std::string &title)
+ void BellOptionWithDescriptionWindow::setListDescription(const std::string &title,
+ TokenMap tokenMap,
+ const std::string &font,
+ const unsigned height)
{
auto descriptionBody = new TextFixedSize(body->centerBox);
descriptionBody->drawUnderline(false);
descriptionBody->setAlignment(Alignment(Alignment::Horizontal::Center, Alignment::Vertical::Center));
- descriptionBody->setFont(style::window::font::verybiglight);
- descriptionBody->setMinimumSize(style::window_width, description_height);
+ descriptionBody->setFont(font);
+ descriptionBody->setMinimumSize(style::window_width, height);
descriptionBody->setEditMode(EditMode::Browse);
- descriptionBody->setRichText(title);
+ if (tokenMap.has_value()) {
+ descriptionBody->setRichText(title, std::move(tokenMap.value()));
+ }
+ else {
+ descriptionBody->setText(title);
+ }
body->centerBox->setMargins(gui::Margins{0, top_center_margin, 0, 0});
- body->centerBox->setMaximumHeight(max_description_height);
- body->centerBox->setMinimumHeight(description_height);
+ body->centerBox->setMaximumHeight(height + max_to_min_difference);
+ body->centerBox->setMinimumHeight(height);
body->centerBox->resizeItems();
body->resizeItems();
}
M products/BellHybrid/services/appmgr/ApplicationManager.cpp => products/BellHybrid/services/appmgr/ApplicationManager.cpp +1 -2
@@ 127,9 127,8 @@ namespace app::manager
auto ApplicationManager::isWhatsNewAvailable() -> bool
{
- const auto lastVersionNumber =
+ const auto &lastVersionNumber =
settings->getValue(settings::SystemProperties::osCurrentVersion, settings::SettingsScope::Global);
return lastVersionNumber != VERSION;
}
-
} // namespace app::manager
M products/BellHybrid/services/db/ServiceDB.cpp => products/BellHybrid/services/db/ServiceDB.cpp +1 -1
@@ 29,7 29,7 @@ namespace
constexpr auto multimediaDatabaseName{"multimedia.db"};
constexpr auto settingsDatabaseName{"settings_bell.db"};
constexpr auto meditationStatsDatabaseName{"meditation_stats.db"};
- constexpr auto whatsNewDatabaseName{"whats-new.db"};
+ constexpr auto whatsNewDatabaseName{"whats_new.db"};
} // namespace
ServiceDB::~ServiceDB()
M products/BellHybrid/services/db/agents/ShuffleQuoteModel.cpp => products/BellHybrid/services/db/agents/ShuffleQuoteModel.cpp +6 -5
@@ 14,14 14,15 @@
namespace
{
using namespace std::chrono;
- static constexpr auto zeroOffset = 0;
- static constexpr auto maxLimit = std::numeric_limits<unsigned>::max();
- static constexpr auto dayInSec = duration_cast<seconds>(24h).count();
+
+ constexpr auto zeroOffset = 0;
+ constexpr auto maxLimit = std::numeric_limits<unsigned>::max();
+ constexpr auto dayInSec = duration_cast<seconds>(24h).count();
bool hasCrossedMidnight(std::time_t current, std::time_t last)
{
- const std::tm lastTime = *std::localtime(&last);
- const std::tm currentTime = *std::localtime(¤t);
+ const auto lastTime = *std::localtime(&last);
+ const auto currentTime = *std::localtime(¤t);
if (currentTime.tm_mday != lastTime.tm_mday) {
return true;
}
M products/BellHybrid/services/db/agents/WhatsNewAgent.cpp => products/BellHybrid/services/db/agents/WhatsNewAgent.cpp +37 -21
@@ 4,27 4,43 @@
#include "WhatsNewAgent.hpp"
#include "db/WhatsNewMessages.hpp"
+#include <i18n/i18n.hpp>
#include <Service/Service.hpp>
#include <purefs/filesystem_paths.hpp>
-#include <i18n/i18n.hpp>
namespace
{
- using namespace service::db::whatsNew;
+ using namespace service::db::whatsnew;
+
+ inline std::string createTitleColumnName(const std::string &language)
+ {
+ constexpr auto titleSuffix = "_title";
+ return language + titleSuffix;
+ }
- constexpr auto query = "SELECT %s, Icon FROM WhatsNew WHERE Major > %d OR (Major = %d AND Minor > %d) OR (Major = "
- "%d AND Minor = %d AND Patch > %d)";
+ inline std::string createDescriptionColumnName(const std::string &language)
+ {
+ constexpr auto descriptionSuffix = "_desc";
+ return language + descriptionSuffix;
+ }
- std::vector<Record> getRecordsByVersion(Database *db, VersionNumber version)
+ std::vector<Record> getRecordsByVersion(Database &db, const VersionNumber &version)
{
- const auto retQuery = db->query(query,
- utils::getDisplayLanguage().c_str(),
- version.major,
- version.major,
- version.minor,
- version.major,
- version.minor,
- version.patch);
+ constexpr auto query = "SELECT %s, %s, Icon FROM whats_new "
+ "WHERE Major > %u OR "
+ "(Major = %u AND Minor > %u) OR "
+ "(Major = %u AND Minor = %u AND Patch > %u) "
+ "ORDER BY Major ASC, Minor ASC, Patch ASC;";
+
+ const auto retQuery = db.query(query,
+ createTitleColumnName(utils::getDisplayLanguage()).c_str(),
+ createDescriptionColumnName(utils::getDisplayLanguage()).c_str(),
+ version.major,
+ version.major,
+ version.minor,
+ version.major,
+ version.minor,
+ version.patch);
if ((retQuery == nullptr) || (retQuery->getRowCount() == 0)) {
return {};
@@ 34,7 50,7 @@ namespace
ret.reserve(retQuery->getRowCount());
do {
- ret.push_back({.description{(*retQuery)[0].getString()}, .iconName{(*retQuery)[1].getString()}});
+ ret.push_back(Record{(*retQuery)[0].getString(), (*retQuery)[1].getString(), (*retQuery)[2].getString()});
} while (retQuery->nextRow());
return ret;
@@ 43,19 59,19 @@ namespace
namespace service::db::agents
{
- WhatsNew::WhatsNew(sys::Service *parentService, const std::string dbName)
+ WhatsNew::WhatsNew(sys::Service *parentService, const std::string &dbName)
: DatabaseAgent{parentService}, dbName{dbName}, db{(purefs::dir::getDatabasesPath() / dbName).c_str()}
{}
void WhatsNew::registerMessages()
{
- parentService->connect(whatsNew::messages::GetByVersion({}),
+ parentService->connect(whatsnew::messages::GetByVersion({}),
[this](const auto &req) { return handleGetRecordsByVersion(req); });
}
void WhatsNew::unRegisterMessages()
{
- parentService->disconnect(typeid(whatsNew::messages::GetByVersion));
+ parentService->disconnect(typeid(whatsnew::messages::GetByVersion));
}
auto WhatsNew::getAgentName() -> const std::string
@@ 65,10 81,10 @@ namespace service::db::agents
sys::MessagePointer WhatsNew::handleGetRecordsByVersion(const sys::Message *req)
{
- if (auto msg = dynamic_cast<const whatsNew::messages::GetByVersion *>(req)) {
- const auto records = getRecordsByVersion(&db, msg->version);
- return std::make_shared<whatsNew::messages::Response>(records);
+ if (const auto msg = dynamic_cast<const whatsnew::messages::GetByVersion *>(req)) {
+ const auto &records = getRecordsByVersion(db, msg->version);
+ return std::make_shared<whatsnew::messages::Response>(records);
}
return std::make_shared<sys::ResponseMessage>();
}
-} // namespace service::db::agents>
\ No newline at end of file
+} // namespace service::db::agents
M products/BellHybrid/services/db/agents/WhatsNewAgent.hpp => products/BellHybrid/services/db/agents/WhatsNewAgent.hpp +1 -1
@@ 19,7 19,7 @@ namespace service::db::agents
class WhatsNew : public DatabaseAgent
{
public:
- WhatsNew(sys::Service *parentService, std::string dbName);
+ WhatsNew(sys::Service *parentService, const std::string &dbName);
void registerMessages() override;
void unRegisterMessages() override;
M products/BellHybrid/services/db/include/db/WhatsNewMessages.hpp => products/BellHybrid/services/db/include/db/WhatsNewMessages.hpp +3 -3
@@ 7,10 7,11 @@
#include <Service/Message.hpp>
#include <vector>
-namespace service::db::whatsNew
+namespace service::db::whatsnew
{
struct Record
{
+ std::string title;
std::string description;
std::string iconName;
};
@@ 39,6 40,5 @@ namespace service::db::whatsNew
std::vector<Record> records{};
};
-
} // namespace messages
-} // namespace service::db::whatsNew>
\ No newline at end of file
+} // namespace service::db::whatsnew