Only show own activity in last activity
This commit is contained in:
@@ -15,8 +15,14 @@ class LastHeardWebSocketClient {
|
|||||||
static const int _maxReconnectAttempts = 5;
|
static const int _maxReconnectAttempts = 5;
|
||||||
static const Duration _reconnectDelay = Duration(seconds: 5);
|
static const Duration _reconnectDelay = Duration(seconds: 5);
|
||||||
|
|
||||||
|
final List<int>? _radioIds;
|
||||||
|
int _receivedCount = 0;
|
||||||
|
static const int _maxItems = 200;
|
||||||
|
|
||||||
final Completer<void> _readyCompleter = Completer<void>();
|
final Completer<void> _readyCompleter = Completer<void>();
|
||||||
|
|
||||||
|
LastHeardWebSocketClient({List<int>? radioIds}) : _radioIds = radioIds;
|
||||||
|
|
||||||
// Socket.IO Engine.IO v4 WebSocket URL for Last Heard
|
// Socket.IO Engine.IO v4 WebSocket URL for Last Heard
|
||||||
static const String _wsUrl =
|
static const String _wsUrl =
|
||||||
'wss://api.brandmeister.network/lh/?EIO=4&transport=websocket';
|
'wss://api.brandmeister.network/lh/?EIO=4&transport=websocket';
|
||||||
@@ -37,7 +43,8 @@ class LastHeardWebSocketClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_isConnecting = true;
|
_isConnecting = true;
|
||||||
_shouldReconnect = true;
|
// Don't reconnect if radio IDs are supplied (one-time search query)
|
||||||
|
_shouldReconnect = _radioIds == null || _radioIds.isEmpty;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
debugPrint('LastHeard WS: Connecting to $_wsUrl');
|
debugPrint('LastHeard WS: Connecting to $_wsUrl');
|
||||||
@@ -71,7 +78,7 @@ class LastHeardWebSocketClient {
|
|||||||
_handleOpenPacket(messageStr);
|
_handleOpenPacket(messageStr);
|
||||||
} else if (messageStr.startsWith('2')) {
|
} else if (messageStr.startsWith('2')) {
|
||||||
_sendPong();
|
_sendPong();
|
||||||
} else if (messageStr == '40') {
|
} else if (messageStr.startsWith('40')) {
|
||||||
_handleNamespaceConnect();
|
_handleNamespaceConnect();
|
||||||
} else if (messageStr.startsWith('42')) {
|
} else if (messageStr.startsWith('42')) {
|
||||||
_handleDataPacket(messageStr);
|
_handleDataPacket(messageStr);
|
||||||
@@ -133,11 +140,20 @@ class LastHeardWebSocketClient {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_radioIds == null || _radioIds.isEmpty) {
|
||||||
|
debugPrint('LastHeard WS: No radio IDs provided, skipping search query');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// Build SQL query for multiple radio IDs: SourceID = 123 OR SourceID = 456
|
||||||
|
final sqlParts = _radioIds.map((id) => 'SourceID = $id').toList();
|
||||||
|
final sql = sqlParts.join(' OR ');
|
||||||
|
|
||||||
final message = '42${jsonEncode([
|
final message = '42${jsonEncode([
|
||||||
'searchMongo',
|
'searchMongo',
|
||||||
{
|
{
|
||||||
'query': {'sql': ''},
|
'query': {'sql': sql},
|
||||||
'amount': 200
|
'amount': 200
|
||||||
}
|
}
|
||||||
])}';
|
])}';
|
||||||
@@ -180,6 +196,15 @@ class LastHeardWebSocketClient {
|
|||||||
_messageController != null &&
|
_messageController != null &&
|
||||||
!_messageController!.isClosed) {
|
!_messageController!.isClosed) {
|
||||||
_messageController!.add(eventData);
|
_messageController!.add(eventData);
|
||||||
|
|
||||||
|
// Track received items and disconnect after receiving max items (for search queries)
|
||||||
|
if (_radioIds != null && _radioIds.isNotEmpty) {
|
||||||
|
_receivedCount++;
|
||||||
|
if (_receivedCount >= _maxItems) {
|
||||||
|
debugPrint('LastHeard WS: Received $_maxItems items, disconnecting');
|
||||||
|
disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('LastHeard WS: Error parsing data packet: $e');
|
debugPrint('LastHeard WS: Error parsing data packet: $e');
|
||||||
|
|||||||
@@ -500,7 +500,7 @@ class _DeviceDetailViewState extends State<DeviceDetailView> {
|
|||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'Last Heard on Talkgroup',
|
'Last Activity on Talkgroup',
|
||||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
import '../models/last_heard_item.dart';
|
import '../models/last_heard_item.dart';
|
||||||
|
import '../services/authentication_manager.dart';
|
||||||
import '../services/lastheard_websocket_client.dart';
|
import '../services/lastheard_websocket_client.dart';
|
||||||
|
|
||||||
class LastHeardView extends StatefulWidget {
|
class LastHeardView extends StatefulWidget {
|
||||||
@@ -36,7 +38,11 @@ class _LastHeardViewState extends State<LastHeardView> {
|
|||||||
_isConnecting = true;
|
_isConnecting = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
_wsClient = LastHeardWebSocketClient();
|
final authManager = context.read<AuthenticationManager>();
|
||||||
|
final devices = await authManager.getDevices();
|
||||||
|
final radioIds = devices.map((d) => d.id).toList();
|
||||||
|
|
||||||
|
_wsClient = LastHeardWebSocketClient(radioIds: radioIds);
|
||||||
await _wsClient!.connect();
|
await _wsClient!.connect();
|
||||||
|
|
||||||
_wsSubscription = _wsClient!.messageStream.listen((message) {
|
_wsSubscription = _wsClient!.messageStream.listen((message) {
|
||||||
@@ -53,7 +59,7 @@ class _LastHeardViewState extends State<LastHeardView> {
|
|||||||
void _handleMqttMessage(Map<String, dynamic> data) {
|
void _handleMqttMessage(Map<String, dynamic> data) {
|
||||||
try {
|
try {
|
||||||
final topic = data['topic'] as String?;
|
final topic = data['topic'] as String?;
|
||||||
if (topic == 'LH') {
|
if (topic == 'LH-Startup') {
|
||||||
final payloadStr = data['payload'] as String?;
|
final payloadStr = data['payload'] as String?;
|
||||||
if (payloadStr != null) {
|
if (payloadStr != null) {
|
||||||
final payload = jsonDecode(payloadStr) as Map<String, dynamic>;
|
final payload = jsonDecode(payloadStr) as Map<String, dynamic>;
|
||||||
@@ -84,21 +90,7 @@ class _LastHeardViewState extends State<LastHeardView> {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: const Text('Last Heard'),
|
title: const Text('Last Activity'),
|
||||||
actions: [
|
|
||||||
if (_items.isNotEmpty)
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.only(right: 16),
|
|
||||||
child: Center(
|
|
||||||
child: Text(
|
|
||||||
'${_items.length} ${_items.length == 1 ? "entry" : "entries"}',
|
|
||||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
|
||||||
color: Theme.of(context).colorScheme.onPrimaryContainer,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
body: _buildBody(),
|
body: _buildBody(),
|
||||||
);
|
);
|
||||||
@@ -112,7 +104,7 @@ class _LastHeardViewState extends State<LastHeardView> {
|
|||||||
children: [
|
children: [
|
||||||
CircularProgressIndicator(),
|
CircularProgressIndicator(),
|
||||||
SizedBox(height: 16),
|
SizedBox(height: 16),
|
||||||
Text('Connecting to Last Heard...'),
|
Text('Connecting to Last Activity...'),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -135,7 +127,7 @@ class _LastHeardViewState extends State<LastHeardView> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
Text(
|
Text(
|
||||||
'Waiting for Last Heard data...',
|
'Waiting for Last Activity data...',
|
||||||
style: TextStyle(color: Colors.grey[600]),
|
style: TextStyle(color: Colors.grey[600]),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class _MainViewState extends State<MainView> {
|
|||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.history),
|
icon: Icon(Icons.history),
|
||||||
label: 'Last Heard',
|
label: 'Last Activity',
|
||||||
),
|
),
|
||||||
BottomNavigationBarItem(
|
BottomNavigationBarItem(
|
||||||
icon: Icon(Icons.more_horiz),
|
icon: Icon(Icons.more_horiz),
|
||||||
|
|||||||
Reference in New Issue
Block a user