Files
tactility/Tactility/Source/app/appdetails/AppDetails.cpp
T
Ken Van Hoeylandt f660550f86 App hub and more (#383)
- Added `AppHub` app
- Added `AppHubDetails` app
- Added `cJSON` dependency
- Renamed `AppSim` module to `FirmwareSim`
- Added extra `tt::app::alertdialg::start()`
- Renamed `addApp()`, `removeApp()`, `findAppById()` and `getApps()` to `addAppManifest()`, `removeAppManifest()`, `findAppManifestById()` and `getAppManifests()`
- Added `tt::lvgl::toolbar_clear_actions()`
- Added `tt::network::EspHttpClient` as a thread-safe wrapper around `esp_http_client`
- Added `tt::network::http::download()` to download files
- Added `tt::network::ntp::isSynced()`
- When time is synced, the timestamp is stored in NVS flash. On boot, it is restored. This helps SSL connections when doing a quick reset: when WiFi reconnects, the user doesn't have to wait for NTP sync before SSL works.
- Added `tt::json::Reader` as a `cJSON` wrapper
- Added `int64_t` support for `Preferences`
- Added `int64_t` support for `Bundle`
- Added dependencies: `cJSON`, `esp-tls`
- When time is synced via NTP, disable time sync.
- Added docs to 'tt::file::` functions
- Added `tt::string::join()` that works with `std::vector<const char*>`
- Fixed `tt::file::getLastPathSegment()` for the scenario when a path was passed with only a single segment
- Set `CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120` (from about 3k) for all boards
- Set `CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y` for all boards
2025-10-25 00:20:48 +02:00

115 lines
3.8 KiB
C++

#include "Tactility/lvgl/LvglSync.h"
#include <Tactility/app/App.h>
#include <Tactility/app/AppContext.h>
#include <Tactility/app/AppManifest.h>
#include <Tactility/app/alertdialog/AlertDialog.h>
#include <Tactility/lvgl/Style.h>
#include <Tactility/lvgl/Toolbar.h>
#include <Tactility/TactilityCore.h>
#include <lvgl.h>
#include <format>
#include <Tactility/StringUtils.h>
#include <Tactility/file/File.h>
namespace tt::app::appdetails {
extern const AppManifest manifest;
void start(const std::string& appId) {
auto bundle = std::make_shared<Bundle>();
bundle->putString("appId", appId);
app::start(manifest.appId, bundle);
}
class AppDetailsApp : public App {
std::shared_ptr<AppManifest> manifest;
static void onPressUninstall(TT_UNUSED lv_event_t* event) {
auto* self = static_cast<AppDetailsApp*>(lv_event_get_user_data(event));
std::vector<std::string> choices = {
"Yes",
"No"
};
alertdialog::start("Confirmation", std::format("Uninstall {}?", self->manifest->appName), choices);
}
public:
void onCreate(AppContext& app) override {
const auto parameters = app.getParameters();
tt_check(parameters != nullptr, "Parameters missing");
auto app_id = parameters->getString("appId");
manifest = findAppManifestById(app_id);
assert(manifest != nullptr);
}
void onShow(AppContext& app, lv_obj_t* parent) override {
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN);
lv_obj_set_style_pad_row(parent, 0, LV_STATE_DEFAULT);
auto title = std::format("{} details", manifest->appName);
lvgl::toolbar_create(parent, title);
auto* wrapper = lv_obj_create(parent);
lv_obj_set_width(wrapper, LV_PCT(100));
lv_obj_set_flex_grow(wrapper, 1);
lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN);
lv_obj_set_style_border_width(wrapper, 0, LV_STATE_DEFAULT);
lvgl::obj_set_style_bg_invisible(wrapper);
auto identifier = std::format("Identifier: {}", manifest->appId);
auto* identifier_label = lv_label_create(wrapper);
lv_label_set_text(identifier_label, identifier.c_str());
auto* location_label = lv_label_create(wrapper);
std::string location;
if (manifest->appLocation.isInternal()) {
location = "internal";
} else {
if (!string::getPathParent(manifest->appLocation.getPath(), location)) {
location = "external";
}
}
std::string location_label_text = std::format("Location: {}", location);
lv_label_set_text(location_label, location_label_text.c_str());
if (manifest->appLocation.isExternal()) {
auto* uninstall_button = lv_button_create(wrapper);
lv_obj_set_width(uninstall_button, LV_PCT(100));
lv_obj_add_event_cb(uninstall_button, onPressUninstall, LV_EVENT_SHORT_CLICKED, this);
auto* uninstall_label = lv_label_create(uninstall_button);
lv_obj_align(uninstall_label, LV_ALIGN_CENTER, 0, 0);
lv_label_set_text(uninstall_label, "Uninstall");
}
}
void onResult(TT_UNUSED AppContext& appContext, TT_UNUSED LaunchId launchId, TT_UNUSED Result result, std::unique_ptr<Bundle> bundle) override {
if (result != Result::Ok || bundle == nullptr) {
return;
}
if (alertdialog::getResultIndex(*bundle) != 0) { // 0 = Yes
return;
}
uninstall(manifest->appId);
// Stop app
stop();
}
};
extern const AppManifest manifest = {
.appId = "AppDetails",
.appName = "App Details",
.appCategory = Category::System,
.appFlags = AppManifest::Flags::Hidden,
.createApp = create<AppDetailsApp>
};
} // namespace