mirror of
https://github.com/torlando-tech/pyxis.git
synced 2026-07-09 15:51:53 +00:00
70d4aa6be9
Repins microReticulum + microLXMF onto the upstream-0.4.1 graft and adapts pyxis to the new src/microReticulum/ layout and 0.4.x APIs. The far-diverged 0.3.0 fork's Resource/Transport/Identity work is subsumed by upstream's reimplementation; only the still-needed fixes ride on the pinned branches (PKCS7/HMAC/X25519 crypto -- proven byte-identical to python RNS 1.3.1 -- Packet link-proof callback, Identity short-sig guard, and the bz2 layer + decompress-on-receive in Resource::assemble()). Consumer-side changes: - platformio.ini: pin microReticulum @2f21fee (pyxis-fixes-on-0.4.1) and microLXMF @33760d0 (chore/microreticulum-0.4.1-layout); bump microStore ceea8f5 -> c5fb69d (0.4.x requires the new BasicFileStore::init API); -std=gnu++11 -> gnu++17 (upstream requires C++17). - Namespace all microReticulum includes (angle + quote) to <microReticulum/...> for the relocated layout; shim-local Utilities/Stream.h|Print.h preserved. - Interface::send_outgoing now returns bool: update TCP/BLE/SX1262/Auto overrides with correct success/failure returns. - SDArchiveFileSystem::init(bool reformatOnFail=true) to match new microStore. - Static Transport::get_path_table() -> path_table(); instance getter unchanged. - Remove duplicate shim Cryptography/BZ2 (microReticulum provides it now; keep lib/libbz2 as the ESP32 bzlib provider). - patch_littlefs_paths.py: normalize microStore's LittleFS adapter paths to a leading "/" -- ESP32 Arduino LittleFS rejects "./"-prefixed paths, which silently broke the path store (no peer paths learned, all messaging blocked). Validated on T-Deck Plus: builds (RAM 27.5% / Flash 77.7%), boots stable (no WDT/panic), and a full on-device LXMF e2e (DIRECT + OPPORTUNISTIC + bz2-compressed-Resource receive) passes 5/5. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UWZuYkHBRqNb6BZHV8sTG5
181 lines
5.3 KiB
C++
181 lines
5.3 KiB
C++
// Copyright (c) 2024 microReticulum contributors
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
#include "QRScreen.h"
|
|
|
|
#ifdef ARDUINO
|
|
|
|
#include <microReticulum/Log.h>
|
|
#include "../LVGL/LVGLInit.h"
|
|
#include "../LVGL/LVGLLock.h"
|
|
|
|
using namespace RNS;
|
|
|
|
namespace UI {
|
|
namespace LXMF {
|
|
|
|
QRScreen::QRScreen(lv_obj_t* parent)
|
|
: _screen(nullptr), _header(nullptr), _content(nullptr), _btn_back(nullptr),
|
|
_qr_code(nullptr), _label_hint(nullptr) {
|
|
|
|
// Create screen object
|
|
if (parent) {
|
|
_screen = lv_obj_create(parent);
|
|
} else {
|
|
_screen = lv_obj_create(lv_scr_act());
|
|
}
|
|
|
|
lv_obj_set_size(_screen, LV_PCT(100), LV_PCT(100));
|
|
lv_obj_clear_flag(_screen, LV_OBJ_FLAG_SCROLLABLE);
|
|
lv_obj_set_style_bg_color(_screen, lv_color_hex(0x121212), 0);
|
|
lv_obj_set_style_bg_opa(_screen, LV_OPA_COVER, 0);
|
|
lv_obj_set_style_pad_all(_screen, 0, 0);
|
|
lv_obj_set_style_border_width(_screen, 0, 0);
|
|
lv_obj_set_style_radius(_screen, 0, 0);
|
|
|
|
// Create UI components
|
|
create_header();
|
|
create_content();
|
|
|
|
// Hide by default
|
|
hide();
|
|
|
|
TRACE("QRScreen created");
|
|
}
|
|
|
|
QRScreen::~QRScreen() {
|
|
LVGL_LOCK();
|
|
if (_screen) {
|
|
lv_obj_del(_screen);
|
|
}
|
|
}
|
|
|
|
void QRScreen::create_header() {
|
|
_header = lv_obj_create(_screen);
|
|
lv_obj_set_size(_header, LV_PCT(100), 36);
|
|
lv_obj_align(_header, LV_ALIGN_TOP_MID, 0, 0);
|
|
lv_obj_set_style_bg_color(_header, lv_color_hex(0x1a1a1a), 0);
|
|
lv_obj_set_style_border_width(_header, 0, 0);
|
|
lv_obj_set_style_radius(_header, 0, 0);
|
|
lv_obj_set_style_pad_all(_header, 0, 0);
|
|
|
|
// Back button
|
|
_btn_back = lv_btn_create(_header);
|
|
lv_obj_set_size(_btn_back, 50, 28);
|
|
lv_obj_align(_btn_back, LV_ALIGN_LEFT_MID, 2, 0);
|
|
lv_obj_set_style_bg_color(_btn_back, lv_color_hex(0x333333), 0);
|
|
lv_obj_set_style_bg_color(_btn_back, lv_color_hex(0x444444), LV_STATE_PRESSED);
|
|
lv_obj_add_event_cb(_btn_back, on_back_clicked, LV_EVENT_CLICKED, this);
|
|
|
|
lv_obj_t* label_back = lv_label_create(_btn_back);
|
|
lv_label_set_text(label_back, LV_SYMBOL_LEFT);
|
|
lv_obj_center(label_back);
|
|
lv_obj_set_style_text_color(label_back, lv_color_hex(0xe0e0e0), 0);
|
|
|
|
// Title
|
|
lv_obj_t* title = lv_label_create(_header);
|
|
lv_label_set_text(title, "Share Identity");
|
|
lv_obj_align(title, LV_ALIGN_LEFT_MID, 60, 0);
|
|
lv_obj_set_style_text_color(title, lv_color_hex(0xffffff), 0);
|
|
lv_obj_set_style_text_font(title, &lv_font_montserrat_16, 0);
|
|
}
|
|
|
|
void QRScreen::create_content() {
|
|
_content = lv_obj_create(_screen);
|
|
lv_obj_set_size(_content, LV_PCT(100), 204); // 240 - 36 header
|
|
lv_obj_align(_content, LV_ALIGN_TOP_MID, 0, 36);
|
|
lv_obj_set_style_pad_all(_content, 8, 0);
|
|
lv_obj_set_style_bg_color(_content, lv_color_hex(0x121212), 0);
|
|
lv_obj_set_style_border_width(_content, 0, 0);
|
|
lv_obj_set_style_radius(_content, 0, 0);
|
|
lv_obj_clear_flag(_content, LV_OBJ_FLAG_SCROLLABLE);
|
|
|
|
// QR code - centered, large for easy scanning
|
|
// 180px gives ~3.4px per module for 53-module QR (Version 9)
|
|
_qr_code = lv_qrcode_create(_content, 180, lv_color_hex(0x000000), lv_color_hex(0xffffff));
|
|
lv_obj_align(_qr_code, LV_ALIGN_TOP_MID, 0, 0);
|
|
|
|
// Hint text below QR
|
|
_label_hint = lv_label_create(_content);
|
|
lv_label_set_text(_label_hint, "Scan with Columba to add contact");
|
|
lv_obj_align(_label_hint, LV_ALIGN_TOP_MID, 0, 183); // Below 180px QR + 3px gap
|
|
lv_obj_set_style_text_color(_label_hint, lv_color_hex(0x808080), 0);
|
|
lv_obj_set_style_text_font(_label_hint, &lv_font_montserrat_12, 0);
|
|
}
|
|
|
|
void QRScreen::set_identity(const Identity& identity) {
|
|
LVGL_LOCK();
|
|
_identity = identity;
|
|
update_qr_code();
|
|
}
|
|
|
|
void QRScreen::set_lxmf_address(const Bytes& hash) {
|
|
LVGL_LOCK();
|
|
_lxmf_address = hash;
|
|
update_qr_code();
|
|
}
|
|
|
|
void QRScreen::update_qr_code() {
|
|
if (!_identity || !_qr_code || _lxmf_address.size() == 0) {
|
|
return;
|
|
}
|
|
|
|
// Format: lxma://<dest_hash>:<public_key>
|
|
// Columba-compatible format for contact sharing
|
|
String dest_hash = String(_lxmf_address.toHex().c_str());
|
|
String pub_key = String(_identity.get_public_key().toHex().c_str());
|
|
|
|
String qr_data = "lxma://";
|
|
qr_data += dest_hash;
|
|
qr_data += ":";
|
|
qr_data += pub_key;
|
|
|
|
lv_qrcode_update(_qr_code, qr_data.c_str(), qr_data.length());
|
|
}
|
|
|
|
void QRScreen::set_back_callback(BackCallback callback) {
|
|
_back_callback = callback;
|
|
}
|
|
|
|
void QRScreen::show() {
|
|
LVGL_LOCK();
|
|
update_qr_code(); // Refresh QR when shown
|
|
lv_obj_clear_flag(_screen, LV_OBJ_FLAG_HIDDEN);
|
|
lv_obj_move_foreground(_screen);
|
|
|
|
// Add back button to focus group for trackball navigation
|
|
lv_group_t* group = LVGL::LVGLInit::get_default_group();
|
|
if (group && _btn_back) {
|
|
lv_group_add_obj(group, _btn_back);
|
|
lv_group_focus_obj(_btn_back);
|
|
}
|
|
}
|
|
|
|
void QRScreen::hide() {
|
|
LVGL_LOCK();
|
|
// Remove from focus group when hiding
|
|
lv_group_t* group = LVGL::LVGLInit::get_default_group();
|
|
if (group && _btn_back) {
|
|
lv_group_remove_obj(_btn_back);
|
|
}
|
|
|
|
lv_obj_add_flag(_screen, LV_OBJ_FLAG_HIDDEN);
|
|
}
|
|
|
|
lv_obj_t* QRScreen::get_object() {
|
|
return _screen;
|
|
}
|
|
|
|
void QRScreen::on_back_clicked(lv_event_t* event) {
|
|
QRScreen* screen = (QRScreen*)lv_event_get_user_data(event);
|
|
|
|
if (screen->_back_callback) {
|
|
screen->_back_callback();
|
|
}
|
|
}
|
|
|
|
} // namespace LXMF
|
|
} // namespace UI
|
|
|
|
#endif // ARDUINO
|