feat: Implement Discord app UI and settings management

- Added MainUI class for displaying voice state, status icon, and buttons.
- Introduced MainUIHandler to manage UI interactions and bridge communication.
- Created SettingsUI for displaying QR code and configuration instructions.
- Implemented SettingsUIHandler to manage settings and web server interactions.
- Developed WebHandler for handling HTTP requests for settings configuration.
- Updated AppRegistry to initialize with the new Discord app descriptor.
- Enhanced InteractionHandler to support keyboard interactions across app switches.
- Updated UIHandler to manage app switching and rendering of app icons.
- Enabled QR code support in LVGL configuration.
This commit is contained in:
GW_MC
2026-02-02 20:47:27 +08:00
parent 12ad5be48a
commit e467951b8c
28 changed files with 1927 additions and 24 deletions

131
main/ui/apps/iotdis/app.cpp Normal file
View File

@@ -0,0 +1,131 @@
#include "ui/apps/iotdis/app.h"
#include "ui/apps/iotdis/ui/main_handler.h"
#include "ui/apps/iotdis/ui/settings_handler.h"
#include "common/system_context.h"
#include "esp_log.h"
static const char* TAG = "IotDisApp";
// ============================================================================
// IotDisApp Implementation
// ============================================================================
IotDisApp::IotDisApp()
: main_ui_handler_(nullptr)
, settings_ui_handler_(nullptr)
, current_page_(Page::MAIN)
, setting_handler_(nullptr)
, interaction_handler_(nullptr) {
setting_handler_ = std::make_unique<SettingHandler>(
std::make_unique<NVSStorageHandler>(IotDisApp::NVS_NAMESPACE)
);
}
IotDisApp::~IotDisApp() { }
esp_err_t IotDisApp::init(lv_obj_t* container, InteractionHandler* interaction_handler) {
ESP_LOGI(TAG, "Initializing Discord app");
container_ = container;
interaction_handler_ = interaction_handler;
// Initialize storage
setting_handler_->init(nullptr);
// Load saved settings
setting_handler_->load_settings();
// Create main UI handler
main_ui_handler_ = std::make_unique<MainUIHandler>();
main_ui_handler_->init(container, interaction_handler_, setting_handler_.get());
// Register settings button callback
main_ui_handler_->register_on_settings_button_clicked(on_settings_button_clicked_static, this);
current_page_ = Page::MAIN;
return ESP_OK;
}
esp_err_t IotDisApp::deinit() {
ESP_LOGI(TAG, "Deinitializing Discord app");
// Clean up UI handlers
if (settings_ui_handler_) {
settings_ui_handler_->deinit();
settings_ui_handler_.reset();
}
if (main_ui_handler_) {
main_ui_handler_->deinit();
main_ui_handler_.reset();
}
return ESP_OK;
}
std::string IotDisApp::get_name() const {
return "Discord";
}
bool IotDisApp::on_back_button_pressed() {
// If on settings page, go back to main page
if (current_page_ == Page::SETTINGS) {
// Clean up settings handler
if (settings_ui_handler_) {
settings_ui_handler_->deinit();
settings_ui_handler_.reset();
}
// Reload settings in case they were updated
setting_handler_->load_settings();
// Recreate main UI handler with updated settings
if (!main_ui_handler_) {
main_ui_handler_ = std::make_unique<MainUIHandler>();
main_ui_handler_->init(container_, interaction_handler_, setting_handler_.get());
main_ui_handler_->register_on_settings_button_clicked(on_settings_button_clicked_static, this);
}
// Update UI with configuration status
main_ui_handler_->update_config_prompt(setting_handler_->is_configured());
current_page_ = Page::MAIN;
return true;
}
// Let system handle back (return to app icons)
return false;
}
// ============================================================================
// Private Methods
// ============================================================================
// Settings page with web server and QR code
void IotDisApp::show_settings_page() {
ESP_LOGI(TAG, "Showing settings page");
// Hide main UI handler
if (main_ui_handler_) {
main_ui_handler_->deinit();
main_ui_handler_.reset();
}
// Create settings UI handler
settings_ui_handler_ = std::make_unique<SettingsUIHandler>();
settings_ui_handler_->init(container_, interaction_handler_, setting_handler_.get());
current_page_ = Page::SETTINGS;
}
// ============================================================================
// Static Callbacks
// ============================================================================
void IotDisApp::on_settings_button_clicked_static(lv_event_t* e) {
IotDisApp* app = static_cast<IotDisApp*>(lv_event_get_user_data(e));
if (app) {
app->show_settings_page();
}
}