mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-04-20 22:13:48 +00:00
🔄 Changes
Core Features Unread Message Tracking: Added persistent unread counts for contacts and channels with visual badges Message Deletion: Users can now long-press to delete individual messages in chats and channels SMAZ Compression: Added per-contact compression settings (previously only channels) UTF-8 Length Limiting: Text inputs now enforce protocol byte limits correctly Channel Message Paths: New screen to visualize packet routing through repeater network with map view Protocol Updates Added maxContactMessageBytes() and maxChannelMessageBytes() helpers for message length validation Changed channel PSK format from Base64 to Hexadecimal (breaking change) Added app version field to connection handshake frame UI Improvements Unread badges on all contact and channel list items Enhanced message bubbles with path visualization for channel messages Character count displays in message input fields Improved repeater CLI screen functionality New Files lib/storage/unread_store.dart - Unread tracking persistence lib/storage/contact_settings_store.dart - Per-contact SMAZ settings lib/widgets/unread_badge.dart - Unread count indicator lib/helpers/utf8_length_limiter.dart - Byte-aware text input formatter lib/screens/channel_message_path_screen.dart - Packet path visualization
This commit is contained in:
parent
e7a5b9e209
commit
02ca7801ea
25 changed files with 1656 additions and 259 deletions
|
|
@ -1,4 +1,3 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import '../connector/meshcore_protocol.dart';
|
||||
|
|
@ -14,11 +13,11 @@ class Channel {
|
|||
required this.psk,
|
||||
});
|
||||
|
||||
String get pskBase64 => base64Encode(psk);
|
||||
String get pskHex => _bytesToHex(psk);
|
||||
|
||||
bool get isEmpty => name.isEmpty && psk.every((b) => b == 0);
|
||||
|
||||
bool get isPublicChannel => pskBase64 == publicChannelPsk;
|
||||
bool get isPublicChannel => pskHex == publicChannelPsk;
|
||||
|
||||
static Channel? fromFrame(Uint8List data) {
|
||||
// CHANNEL_INFO format:
|
||||
|
|
@ -44,14 +43,31 @@ class Channel {
|
|||
);
|
||||
}
|
||||
|
||||
static Channel fromPsk(int index, String name, String pskBase64) {
|
||||
final pskBytes = base64Decode(pskBase64);
|
||||
final psk = Uint8List(16);
|
||||
for (int i = 0; i < pskBytes.length && i < 16; i++) {
|
||||
psk[i] = pskBytes[i];
|
||||
}
|
||||
static Channel fromHex(int index, String name, String pskHex) {
|
||||
final psk = parsePskHex(pskHex);
|
||||
return Channel(index: index, name: name, psk: psk);
|
||||
}
|
||||
|
||||
static const String publicChannelPsk = 'izOH6cXN6mrJ5e26oRXNcg==';
|
||||
static Uint8List parsePskHex(String hex) {
|
||||
final cleaned = hex.replaceAll(RegExp(r'[^0-9a-fA-F]'), '');
|
||||
if (cleaned.length != 32) {
|
||||
throw const FormatException('PSK must be 32 hex characters');
|
||||
}
|
||||
final bytes = Uint8List(16);
|
||||
for (int i = 0; i < 16; i++) {
|
||||
final start = i * 2;
|
||||
bytes[i] = int.parse(cleaned.substring(start, start + 2), radix: 16);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static String formatPskHex(Uint8List psk) {
|
||||
return _bytesToHex(psk);
|
||||
}
|
||||
|
||||
static String _bytesToHex(Uint8List bytes) {
|
||||
return bytes.map((b) => b.toRadixString(16).padLeft(2, '0')).join();
|
||||
}
|
||||
|
||||
static const String publicChannelPsk = '8b3387e9c5cdea6ac9e5edbaa115cd72';
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue