mirror of
https://github.com/dz0ny/meshcore-sar.git
synced 2026-08-11 16:30:28 +00:00
Remove gates and sync pubspec
This commit is contained in:
@@ -5,22 +5,22 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000239">
|
<testcase classname="fastlane.lanes" name="0: default_platform" time="0.000273">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="1: increment_build_number" time="0.427601">
|
<testcase classname="fastlane.lanes" name="1: increment_build_number" time="0.453879">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="2: build_app" time="110.117264">
|
<testcase classname="fastlane.lanes" name="2: build_app" time="117.623994">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|
||||||
<testcase classname="fastlane.lanes" name="3: upload_to_app_store" time="269.473315">
|
<testcase classname="fastlane.lanes" name="3: upload_to_app_store" time="209.300865">
|
||||||
|
|
||||||
</testcase>
|
</testcase>
|
||||||
|
|
||||||
|
|||||||
@@ -202,6 +202,21 @@ class AppProvider with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String? _resolveContactNameForNotification(Uint8List? publicKey) {
|
||||||
|
if (publicKey == null || publicKey.isEmpty) return null;
|
||||||
|
|
||||||
|
Contact? contact;
|
||||||
|
if (publicKey.length >= 32) {
|
||||||
|
contact = contactsProvider.findContactByKey(publicKey);
|
||||||
|
}
|
||||||
|
contact ??= publicKey.length >= 6
|
||||||
|
? contactsProvider.findContactByPrefix(
|
||||||
|
Uint8List.fromList(publicKey.sublist(0, 6)),
|
||||||
|
)
|
||||||
|
: null;
|
||||||
|
return contact?.advName;
|
||||||
|
}
|
||||||
|
|
||||||
/// Load simple mode setting from shared preferences
|
/// Load simple mode setting from shared preferences
|
||||||
Future<void> _loadSimpleMode() async {
|
Future<void> _loadSimpleMode() async {
|
||||||
try {
|
try {
|
||||||
@@ -437,6 +452,10 @@ class AppProvider with ChangeNotifier {
|
|||||||
void _setupCallbacks() {
|
void _setupCallbacks() {
|
||||||
// Monitor connection state changes to start/stop location tracking
|
// Monitor connection state changes to start/stop location tracking
|
||||||
connectionProvider.addListener(_handleConnectionStateChange);
|
connectionProvider.addListener(_handleConnectionStateChange);
|
||||||
|
messagesProvider.resolveContactNameCallback =
|
||||||
|
_resolveContactNameForNotification;
|
||||||
|
messagesProvider.resolveChannelNameCallback =
|
||||||
|
channelsProvider.getChannelDisplayName;
|
||||||
|
|
||||||
voiceProvider.sendRawPacketCallback =
|
voiceProvider.sendRawPacketCallback =
|
||||||
({
|
({
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import '../services/notification_service.dart';
|
|||||||
import '../utils/sar_message_parser.dart';
|
import '../utils/sar_message_parser.dart';
|
||||||
import '../utils/drawing_message_parser.dart';
|
import '../utils/drawing_message_parser.dart';
|
||||||
import '../utils/voice_message_parser.dart';
|
import '../utils/voice_message_parser.dart';
|
||||||
|
import '../utils/image_message_parser.dart';
|
||||||
import '../l10n/app_localizations.dart';
|
import '../l10n/app_localizations.dart';
|
||||||
import 'helpers/message_retry_manager.dart';
|
import 'helpers/message_retry_manager.dart';
|
||||||
|
|
||||||
@@ -79,6 +80,9 @@ class MessagesProvider with ChangeNotifier {
|
|||||||
Future<void> Function({required Contact contact, required int failureStreak})?
|
Future<void> Function({required Contact contact, required int failureStreak})?
|
||||||
onDirectPathFailedCallback;
|
onDirectPathFailedCallback;
|
||||||
|
|
||||||
|
String? Function(Uint8List? publicKey)? resolveContactNameCallback;
|
||||||
|
String Function(int channelIdx)? resolveChannelNameCallback;
|
||||||
|
|
||||||
List<Message> get messages => List.unmodifiable(_messages);
|
List<Message> get messages => List.unmodifiable(_messages);
|
||||||
|
|
||||||
List<Message> get contactMessages =>
|
List<Message> get contactMessages =>
|
||||||
@@ -576,33 +580,31 @@ class MessagesProvider with ChangeNotifier {
|
|||||||
/// Trigger notification for regular message
|
/// Trigger notification for regular message
|
||||||
Future<void> _triggerMessageNotification(Message message) async {
|
Future<void> _triggerMessageNotification(Message message) async {
|
||||||
try {
|
try {
|
||||||
// Get sender name from message
|
final senderName = _resolveParticipantName(
|
||||||
final senderName =
|
publicKey: message.senderPublicKeyPrefix,
|
||||||
message.senderName ?? message.senderKeyShort ?? 'Unknown';
|
fallback: message.senderName ?? message.senderKeyShort,
|
||||||
|
);
|
||||||
// Determine if it's a channel message
|
|
||||||
final isChannelMessage = message.isChannelMessage;
|
final isChannelMessage = message.isChannelMessage;
|
||||||
|
final channelName = isChannelMessage
|
||||||
// Get channel name if available
|
? _resolveChannelName(message.channelIdx)
|
||||||
String? channelName;
|
: null;
|
||||||
if (isChannelMessage) {
|
final messageText = _buildNotificationMessageText(
|
||||||
// You could map channelIdx to channel name here if needed
|
message,
|
||||||
// For now, use "Public" for channel 0
|
senderName: senderName,
|
||||||
channelName = message.channelIdx == 0
|
isChannelMessage: isChannelMessage,
|
||||||
? 'Public'
|
channelName: channelName,
|
||||||
: 'Channel ${message.channelIdx}';
|
);
|
||||||
}
|
|
||||||
|
|
||||||
debugPrint('🔔 [MessagesProvider] Triggering message notification');
|
debugPrint('🔔 [MessagesProvider] Triggering message notification');
|
||||||
debugPrint(' Sender: $senderName');
|
debugPrint(' Sender: $senderName');
|
||||||
debugPrint(' Type: ${isChannelMessage ? "Channel" : "Direct"}');
|
debugPrint(' Type: ${isChannelMessage ? "Channel" : "Direct"}');
|
||||||
debugPrint(
|
debugPrint(
|
||||||
' Message: ${message.text.substring(0, message.text.length > 50 ? 50 : message.text.length)}...',
|
' Message: ${messageText.substring(0, messageText.length > 50 ? 50 : messageText.length)}...',
|
||||||
);
|
);
|
||||||
|
|
||||||
await _notificationService.showMessageNotification(
|
await _notificationService.showMessageNotification(
|
||||||
senderName: senderName,
|
senderName: senderName,
|
||||||
messageText: message.text,
|
messageText: messageText,
|
||||||
isChannelMessage: isChannelMessage,
|
isChannelMessage: isChannelMessage,
|
||||||
channelName: channelName,
|
channelName: channelName,
|
||||||
localizations: _localizations,
|
localizations: _localizations,
|
||||||
@@ -614,6 +616,78 @@ class MessagesProvider with ChangeNotifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String _resolveParticipantName({
|
||||||
|
required Uint8List? publicKey,
|
||||||
|
String? fallback,
|
||||||
|
}) {
|
||||||
|
final resolved = resolveContactNameCallback?.call(publicKey)?.trim();
|
||||||
|
if (resolved != null && resolved.isNotEmpty) {
|
||||||
|
return resolved;
|
||||||
|
}
|
||||||
|
final normalizedFallback = fallback?.trim();
|
||||||
|
if (normalizedFallback != null && normalizedFallback.isNotEmpty) {
|
||||||
|
return normalizedFallback;
|
||||||
|
}
|
||||||
|
return 'Unknown';
|
||||||
|
}
|
||||||
|
|
||||||
|
String _resolveChannelName(int? channelIdx) {
|
||||||
|
final idx = channelIdx ?? 0;
|
||||||
|
final resolved = resolveChannelNameCallback?.call(idx).trim();
|
||||||
|
if (resolved != null && resolved.isNotEmpty) {
|
||||||
|
return resolved;
|
||||||
|
}
|
||||||
|
return idx == 0 ? 'Public' : 'Channel $idx';
|
||||||
|
}
|
||||||
|
|
||||||
|
String _buildNotificationMessageText(
|
||||||
|
Message message, {
|
||||||
|
required String senderName,
|
||||||
|
required bool isChannelMessage,
|
||||||
|
String? channelName,
|
||||||
|
}) {
|
||||||
|
final voiceEnvelope = VoiceEnvelope.tryParseText(message.text);
|
||||||
|
if (voiceEnvelope != null) {
|
||||||
|
final seconds = (voiceEnvelope.durationMs / 1000).ceil();
|
||||||
|
final route = isChannelMessage
|
||||||
|
? 'Channel: ${channelName ?? _resolveChannelName(message.channelIdx)}'
|
||||||
|
: 'From: $senderName';
|
||||||
|
return '$route\nVoice message - ${voiceEnvelope.mode.label} - ${seconds}s - ${voiceEnvelope.total} packets';
|
||||||
|
}
|
||||||
|
|
||||||
|
final imageEnvelope = ImageEnvelope.tryParse(message.text);
|
||||||
|
if (imageEnvelope != null) {
|
||||||
|
final route = isChannelMessage
|
||||||
|
? 'Channel: ${channelName ?? _resolveChannelName(message.channelIdx)}'
|
||||||
|
: 'From: $senderName';
|
||||||
|
return '$route\nImage - ${imageEnvelope.format.label} - ${imageEnvelope.width}x${imageEnvelope.height} - ${_formatBytes(imageEnvelope.sizeBytes)}';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isChannelMessage && message.recipientPublicKey != null) {
|
||||||
|
final recipientName = _resolveParticipantName(
|
||||||
|
publicKey: message.recipientPublicKey,
|
||||||
|
fallback: null,
|
||||||
|
);
|
||||||
|
if (recipientName != 'Unknown') {
|
||||||
|
return 'From: $senderName\nTo: $recipientName\n${message.text}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isChannelMessage && channelName != null && channelName.isNotEmpty) {
|
||||||
|
return 'Channel: $channelName\n${message.text}';
|
||||||
|
}
|
||||||
|
|
||||||
|
return message.text;
|
||||||
|
}
|
||||||
|
|
||||||
|
String _formatBytes(int bytes) {
|
||||||
|
if (bytes < 1024) return '$bytes B';
|
||||||
|
final kib = bytes / 1024;
|
||||||
|
if (kib < 1024) return '${kib.toStringAsFixed(kib >= 10 ? 0 : 1)} KB';
|
||||||
|
final mib = kib / 1024;
|
||||||
|
return '${mib.toStringAsFixed(mib >= 10 ? 0 : 1)} MB';
|
||||||
|
}
|
||||||
|
|
||||||
/// Persist messages to storage (async, non-blocking)
|
/// Persist messages to storage (async, non-blocking)
|
||||||
Future<void> _persistMessages() async {
|
Future<void> _persistMessages() async {
|
||||||
try {
|
try {
|
||||||
|
|||||||
18
pubspec.lock
18
pubspec.lock
@@ -29,10 +29,10 @@ packages:
|
|||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: audioplayers
|
name: audioplayers
|
||||||
sha256: "5441fa0ceb8807a5ad701199806510e56afde2b4913d9d17c2f19f2902cf0ae4"
|
sha256: a72dd459d1a48f61a6fb9c0134dba26597c9236af40639ff0eb70eb4e0baab70
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.5.1"
|
version: "6.6.0"
|
||||||
audioplayers_android:
|
audioplayers_android:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -45,10 +45,10 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: audioplayers_darwin
|
name: audioplayers_darwin
|
||||||
sha256: "0811d6924904ca13f9ef90d19081e4a87f7297ddc19fc3d31f60af1aaafee333"
|
sha256: c994b3bb3a921e4904ac40e013fbc94488e824fd7c1de6326f549943b0b44a91
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.3.0"
|
version: "6.4.0"
|
||||||
audioplayers_linux:
|
audioplayers_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -69,18 +69,18 @@ packages:
|
|||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: audioplayers_web
|
name: audioplayers_web
|
||||||
sha256: "1c0f17cec68455556775f1e50ca85c40c05c714a99c5eb1d2d57cc17ba5522d7"
|
sha256: faa8fa6587f996a6f604433b53af44c57a1407d4fe8dff5766cf63d6875e8de9
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.1.1"
|
version: "5.2.0"
|
||||||
audioplayers_windows:
|
audioplayers_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: audioplayers_windows
|
name: audioplayers_windows
|
||||||
sha256: "4048797865105b26d47628e6abb49231ea5de84884160229251f37dfcbe52fd7"
|
sha256: bafff2b38b6f6d331887558ba6e0a01c9c208d9dbb3ad0005234db065122a734
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.2.1"
|
version: "4.3.0"
|
||||||
bluez:
|
bluez:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -851,7 +851,7 @@ packages:
|
|||||||
description:
|
description:
|
||||||
path: "."
|
path: "."
|
||||||
ref: main
|
ref: main
|
||||||
resolved-ref: fb0a92a53b8e1ab23ffca50c2bffe819829843e6
|
resolved-ref: cea66b5251135c7f9b84f15c0878d4c8af6e88e9
|
||||||
url: "https://github.com/dz0ny/meshcore_client.git"
|
url: "https://github.com/dz0ny/meshcore_client.git"
|
||||||
source: git
|
source: git
|
||||||
version: "0.1.0"
|
version: "0.1.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user