feat: add DiscordApp for voice control integration with UDP communication
This commit is contained in:
123
main/ui/apps/discord_app.h
Normal file
123
main/ui/apps/discord_app.h
Normal file
@@ -0,0 +1,123 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui/ui_app.h"
|
||||
#include "ui/page_stack.h"
|
||||
#include "ui/app_registry.h"
|
||||
#include "network/udp_client.h"
|
||||
#include "io/nvs_handler.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* @brief Discord voice control app
|
||||
*
|
||||
* Allows control of Discord voice settings (mute/unmute) via UDP communication
|
||||
* with the IotDis Node.js bridge. Features:
|
||||
* - Main page: Status icon + mute button
|
||||
* - Settings page: IP/port configuration with connection test
|
||||
* - Periodic status polling with automatic retry
|
||||
* - Error notification when remote is unreachable
|
||||
*/
|
||||
class DiscordApp : public UIApp {
|
||||
public:
|
||||
DiscordApp();
|
||||
~DiscordApp() override;
|
||||
|
||||
// UIApp interface
|
||||
esp_err_t init(lv_obj_t* container) override;
|
||||
esp_err_t deinit() override;
|
||||
std::string get_name() const override { return "Discord"; }
|
||||
void handle_event(uint32_t event_type, void* event_data = nullptr) override;
|
||||
bool on_back_button_pressed() override;
|
||||
|
||||
private:
|
||||
// Voice state enum
|
||||
enum class VoiceState {
|
||||
UNKNOWN,
|
||||
MUTED,
|
||||
UNMUTED,
|
||||
ERROR
|
||||
};
|
||||
|
||||
// Page management
|
||||
PageStack* page_stack_;
|
||||
void build_main_page(lv_obj_t* page);
|
||||
void build_settings_page(lv_obj_t* page);
|
||||
void show_settings_page();
|
||||
|
||||
// Main page widgets
|
||||
lv_obj_t* status_icon_label_;
|
||||
lv_obj_t* status_text_label_;
|
||||
lv_obj_t* mute_button_;
|
||||
lv_obj_t* error_notification_;
|
||||
|
||||
// Settings page widgets
|
||||
lv_obj_t* ip_textarea_;
|
||||
lv_obj_t* port_textarea_;
|
||||
lv_obj_t* test_result_label_;
|
||||
|
||||
// UDP client and configuration
|
||||
UDPClient udp_client_;
|
||||
std::string remote_ip_;
|
||||
uint16_t remote_port_;
|
||||
bool settings_configured_;
|
||||
|
||||
// Voice state
|
||||
VoiceState current_state_;
|
||||
SemaphoreHandle_t state_mutex_;
|
||||
|
||||
// Polling task
|
||||
TaskHandle_t poll_task_handle_;
|
||||
bool stop_polling_;
|
||||
int consecutive_failures_;
|
||||
static constexpr int MAX_FAILURES_BEFORE_ERROR = 3;
|
||||
static constexpr int POLL_INTERVAL_MS = 5000;
|
||||
static constexpr int ERROR_POLL_INTERVAL_MS = 15000;
|
||||
static constexpr int RESPONSE_TIMEOUT_MS = 2000;
|
||||
|
||||
// NVS storage
|
||||
NVSStorageHandler* storage_;
|
||||
static constexpr const char* NVS_NAMESPACE = "discord";
|
||||
static constexpr const char* NVS_KEY_IP = "remote_ip";
|
||||
static constexpr const char* NVS_KEY_PORT = "remote_port";
|
||||
|
||||
// Event callbacks
|
||||
static void on_mute_button_clicked(lv_event_t* e);
|
||||
static void on_settings_button_clicked(lv_event_t* e);
|
||||
static void on_save_settings_clicked(lv_event_t* e);
|
||||
static void on_test_connection_clicked(lv_event_t* e);
|
||||
|
||||
// UDP communication
|
||||
void send_mute_command();
|
||||
bool test_connection();
|
||||
void update_status_display();
|
||||
void show_error_notification(bool show);
|
||||
|
||||
// Settings management
|
||||
void load_settings();
|
||||
void save_settings();
|
||||
|
||||
// Polling task
|
||||
static void poll_task(void* param);
|
||||
void start_polling_task();
|
||||
void stop_polling_task();
|
||||
void poll_status();
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Discord app descriptor for registration
|
||||
*/
|
||||
class DiscordAppDescriptor : public AppDescriptor {
|
||||
public:
|
||||
static DiscordAppDescriptor& instance() {
|
||||
static DiscordAppDescriptor instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
void draw_icon(lv_obj_t* parent) override;
|
||||
|
||||
private:
|
||||
DiscordAppDescriptor();
|
||||
};
|
||||
Reference in New Issue
Block a user