diff --git a/lib/pb/stillbox.pb.dart b/lib/pb/stillbox.pb.dart index 12bb708..785128e 100644 --- a/lib/pb/stillbox.pb.dart +++ b/lib/pb/stillbox.pb.dart @@ -645,6 +645,7 @@ class Command extends $pb.GeneratedMessage { class TalkgroupInfo extends $pb.GeneratedMessage { factory TalkgroupInfo({ Talkgroup? tg, + $core.String? systemName, $core.String? name, $core.String? group, $core.int? frequency, @@ -656,6 +657,9 @@ class TalkgroupInfo extends $pb.GeneratedMessage { if (tg != null) { $result.tg = tg; } + if (systemName != null) { + $result.systemName = systemName; + } if (name != null) { $result.name = name; } @@ -682,12 +686,13 @@ class TalkgroupInfo extends $pb.GeneratedMessage { static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'TalkgroupInfo', package: const $pb.PackageName(_omitMessageNames ? '' : 'stillbox'), createEmptyInstance: create) ..aOM(1, _omitFieldNames ? '' : 'tg', subBuilder: Talkgroup.create) - ..aOS(2, _omitFieldNames ? '' : 'name') - ..aOS(3, _omitFieldNames ? '' : 'group') - ..a<$core.int>(4, _omitFieldNames ? '' : 'frequency', $pb.PbFieldType.O3) - ..pPS(5, _omitFieldNames ? '' : 'tags') - ..aOM<$1.Struct>(6, _omitFieldNames ? '' : 'metadata', subBuilder: $1.Struct.create) - ..aOB(7, _omitFieldNames ? '' : 'learned') + ..aOS(2, _omitFieldNames ? '' : 'systemName') + ..aOS(3, _omitFieldNames ? '' : 'name') + ..aOS(4, _omitFieldNames ? '' : 'group') + ..a<$core.int>(5, _omitFieldNames ? '' : 'frequency', $pb.PbFieldType.O3) + ..pPS(6, _omitFieldNames ? '' : 'tags') + ..aOM<$1.Struct>(7, _omitFieldNames ? '' : 'metadata', subBuilder: $1.Struct.create) + ..aOB(8, _omitFieldNames ? '' : 'learned') ..hasRequiredFields = false ; @@ -724,54 +729,63 @@ class TalkgroupInfo extends $pb.GeneratedMessage { Talkgroup ensureTg() => $_ensure(0); @$pb.TagNumber(2) - $core.String get name => $_getSZ(1); + $core.String get systemName => $_getSZ(1); @$pb.TagNumber(2) - set name($core.String v) { $_setString(1, v); } + set systemName($core.String v) { $_setString(1, v); } @$pb.TagNumber(2) - $core.bool hasName() => $_has(1); + $core.bool hasSystemName() => $_has(1); @$pb.TagNumber(2) - void clearName() => clearField(2); + void clearSystemName() => clearField(2); @$pb.TagNumber(3) - $core.String get group => $_getSZ(2); + $core.String get name => $_getSZ(2); @$pb.TagNumber(3) - set group($core.String v) { $_setString(2, v); } + set name($core.String v) { $_setString(2, v); } @$pb.TagNumber(3) - $core.bool hasGroup() => $_has(2); + $core.bool hasName() => $_has(2); @$pb.TagNumber(3) - void clearGroup() => clearField(3); + void clearName() => clearField(3); @$pb.TagNumber(4) - $core.int get frequency => $_getIZ(3); + $core.String get group => $_getSZ(3); @$pb.TagNumber(4) - set frequency($core.int v) { $_setSignedInt32(3, v); } + set group($core.String v) { $_setString(3, v); } @$pb.TagNumber(4) - $core.bool hasFrequency() => $_has(3); + $core.bool hasGroup() => $_has(3); @$pb.TagNumber(4) - void clearFrequency() => clearField(4); + void clearGroup() => clearField(4); @$pb.TagNumber(5) - $core.List<$core.String> get tags => $_getList(4); + $core.int get frequency => $_getIZ(4); + @$pb.TagNumber(5) + set frequency($core.int v) { $_setSignedInt32(4, v); } + @$pb.TagNumber(5) + $core.bool hasFrequency() => $_has(4); + @$pb.TagNumber(5) + void clearFrequency() => clearField(5); @$pb.TagNumber(6) - $1.Struct get metadata => $_getN(5); - @$pb.TagNumber(6) - set metadata($1.Struct v) { setField(6, v); } - @$pb.TagNumber(6) - $core.bool hasMetadata() => $_has(5); - @$pb.TagNumber(6) - void clearMetadata() => clearField(6); - @$pb.TagNumber(6) - $1.Struct ensureMetadata() => $_ensure(5); + $core.List<$core.String> get tags => $_getList(5); @$pb.TagNumber(7) - $core.bool get learned => $_getBF(6); + $1.Struct get metadata => $_getN(6); @$pb.TagNumber(7) - set learned($core.bool v) { $_setBool(6, v); } + set metadata($1.Struct v) { setField(7, v); } @$pb.TagNumber(7) - $core.bool hasLearned() => $_has(6); + $core.bool hasMetadata() => $_has(6); @$pb.TagNumber(7) - void clearLearned() => clearField(7); + void clearMetadata() => clearField(7); + @$pb.TagNumber(7) + $1.Struct ensureMetadata() => $_ensure(6); + + @$pb.TagNumber(8) + $core.bool get learned => $_getBF(7); + @$pb.TagNumber(8) + set learned($core.bool v) { $_setBool(7, v); } + @$pb.TagNumber(8) + $core.bool hasLearned() => $_has(7); + @$pb.TagNumber(8) + void clearLearned() => clearField(8); } class Live extends $pb.GeneratedMessage { diff --git a/lib/pb/stillbox.pbjson.dart b/lib/pb/stillbox.pbjson.dart index 437c1aa..5f5ca3c 100644 --- a/lib/pb/stillbox.pbjson.dart +++ b/lib/pb/stillbox.pbjson.dart @@ -150,12 +150,13 @@ const TalkgroupInfo$json = { '1': 'TalkgroupInfo', '2': [ {'1': 'tg', '3': 1, '4': 1, '5': 11, '6': '.stillbox.Talkgroup', '10': 'tg'}, - {'1': 'name', '3': 2, '4': 1, '5': 9, '9': 0, '10': 'name', '17': true}, - {'1': 'group', '3': 3, '4': 1, '5': 9, '9': 1, '10': 'group', '17': true}, - {'1': 'frequency', '3': 4, '4': 1, '5': 5, '9': 2, '10': 'frequency', '17': true}, - {'1': 'tags', '3': 5, '4': 3, '5': 9, '10': 'tags'}, - {'1': 'metadata', '3': 6, '4': 1, '5': 11, '6': '.google.protobuf.Struct', '9': 3, '10': 'metadata', '17': true}, - {'1': 'learned', '3': 7, '4': 1, '5': 8, '10': 'learned'}, + {'1': 'system_name', '3': 2, '4': 1, '5': 9, '10': 'systemName'}, + {'1': 'name', '3': 3, '4': 1, '5': 9, '9': 0, '10': 'name', '17': true}, + {'1': 'group', '3': 4, '4': 1, '5': 9, '9': 1, '10': 'group', '17': true}, + {'1': 'frequency', '3': 5, '4': 1, '5': 5, '9': 2, '10': 'frequency', '17': true}, + {'1': 'tags', '3': 6, '4': 3, '5': 9, '10': 'tags'}, + {'1': 'metadata', '3': 7, '4': 1, '5': 11, '6': '.google.protobuf.Struct', '9': 3, '10': 'metadata', '17': true}, + {'1': 'learned', '3': 8, '4': 1, '5': 8, '10': 'learned'}, ], '8': [ {'1': '_name'}, @@ -167,12 +168,12 @@ const TalkgroupInfo$json = { /// Descriptor for `TalkgroupInfo`. Decode as a `google.protobuf.DescriptorProto`. final $typed_data.Uint8List talkgroupInfoDescriptor = $convert.base64Decode( - 'Cg1UYWxrZ3JvdXBJbmZvEiMKAnRnGAEgASgLMhMuc3RpbGxib3guVGFsa2dyb3VwUgJ0ZxIXCg' - 'RuYW1lGAIgASgJSABSBG5hbWWIAQESGQoFZ3JvdXAYAyABKAlIAVIFZ3JvdXCIAQESIQoJZnJl' - 'cXVlbmN5GAQgASgFSAJSCWZyZXF1ZW5jeYgBARISCgR0YWdzGAUgAygJUgR0YWdzEjgKCG1ldG' - 'FkYXRhGAYgASgLMhcuZ29vZ2xlLnByb3RvYnVmLlN0cnVjdEgDUghtZXRhZGF0YYgBARIYCgds' - 'ZWFybmVkGAcgASgIUgdsZWFybmVkQgcKBV9uYW1lQggKBl9ncm91cEIMCgpfZnJlcXVlbmN5Qg' - 'sKCV9tZXRhZGF0YQ=='); + 'Cg1UYWxrZ3JvdXBJbmZvEiMKAnRnGAEgASgLMhMuc3RpbGxib3guVGFsa2dyb3VwUgJ0ZxIfCg' + 'tzeXN0ZW1fbmFtZRgCIAEoCVIKc3lzdGVtTmFtZRIXCgRuYW1lGAMgASgJSABSBG5hbWWIAQES' + 'GQoFZ3JvdXAYBCABKAlIAVIFZ3JvdXCIAQESIQoJZnJlcXVlbmN5GAUgASgFSAJSCWZyZXF1ZW' + '5jeYgBARISCgR0YWdzGAYgAygJUgR0YWdzEjgKCG1ldGFkYXRhGAcgASgLMhcuZ29vZ2xlLnBy' + 'b3RvYnVmLlN0cnVjdEgDUghtZXRhZGF0YYgBARIYCgdsZWFybmVkGAggASgIUgdsZWFybmVkQg' + 'cKBV9uYW1lQggKBl9ncm91cEIMCgpfZnJlcXVlbmN5QgsKCV9tZXRhZGF0YQ=='); @$core.Deprecated('Use liveDescriptor instead') const Live$json = { diff --git a/lib/views/lcd.dart b/lib/views/lcd.dart index 3d631f4..d575feb 100644 --- a/lib/views/lcd.dart +++ b/lib/views/lcd.dart @@ -1,4 +1,4 @@ -import 'package:provider/provider.dart'; +import 'package:intl/intl.dart'; import 'package:flutter/material.dart'; import '../controller/stillbox.dart'; import '../pb/stillbox.pb.dart'; @@ -7,7 +7,9 @@ class LCD extends StatelessWidget { final Color _lcdColor; final SBCall? _call; final int queueLen; - const LCD(this._call, this._lcdColor, this.queueLen, {super.key}); + final DateFormat timeFormat; + const LCD(this._call, this._lcdColor, this.queueLen, this.timeFormat, + {super.key}); @override Widget build(BuildContext context) { @@ -40,18 +42,32 @@ class LCD extends StatelessWidget { } Widget lcdContents() { - return Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - FutureBuilder( - future: _call?.tg, - builder: - (BuildContext context, AsyncSnapshot tgi) { - return Text( - '${tgi.data?.name ?? (_call?.call.talkgroup ?? '')}${tgi.data?.learned ?? false ? ' 📓' : ''}'); - }), - Text('Q: $queueLen'), - ]); + String callTime = ''; + if (_call != null) { + callTime = timeFormat.format(_call.call.dateTime.toDateTime()); + } + return FutureBuilder( + future: _call?.tg, + builder: (BuildContext context, AsyncSnapshot tgi) { + return Column(mainAxisAlignment: MainAxisAlignment.start, children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(callTime), + Text('${tgi.data?.systemName ?? (_call?.call.system ?? '')}'), + Text('Q: $queueLen'), + ]), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '${tgi.data?.name ?? (_call?.call.talkgroup ?? '')}${tgi.data?.learned ?? false ? ' 📓' : ''}'), + Text(_call != null ? 'TG: ${_call.call.talkgroup}' : ''), + ]) + ]); + }); } } diff --git a/lib/views/radio.dart b/lib/views/radio.dart index cfdf9b0..cab6db7 100644 --- a/lib/views/radio.dart +++ b/lib/views/radio.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:just_audio/just_audio.dart'; import '../../views/lcd.dart'; @@ -28,6 +29,7 @@ class _MainRadioState extends State { SBCall? _call; Completer _completer = Completer(); int queueLen = 0; + DateFormat timeFormat = DateFormat('HH:mm'); @override void initState() { @@ -104,7 +106,7 @@ class _MainRadioState extends State { const ScannerLabel('Stillbox'), LED(_ledColor), ]), - LCD(_call, _lcdColor, queueLen), + LCD(_call, _lcdColor, queueLen, timeFormat), const Keypad(), ], )), diff --git a/protobuf/stillbox.proto b/protobuf/stillbox.proto index 34de81f..6c6829e 100644 --- a/protobuf/stillbox.proto +++ b/protobuf/stillbox.proto @@ -55,12 +55,13 @@ message Command { message TalkgroupInfo { Talkgroup tg = 1; - optional string name = 2; - optional string group = 3; - optional int32 frequency = 4; - repeated string tags = 5; - optional google.protobuf.Struct metadata = 6; - bool learned = 7; + string system_name = 2; + optional string name = 3; + optional string group = 4; + optional int32 frequency = 5; + repeated string tags = 6; + optional google.protobuf.Struct metadata = 7; + bool learned = 8; } enum LiveState { diff --git a/pubspec.lock b/pubspec.lock index 24d194f..8f7ca63 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -200,6 +200,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.2.0" + intl: + dependency: "direct main" + description: + name: intl + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + url: "https://pub.dev" + source: hosted + version: "0.19.0" js: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index fdb44b4..9cad697 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -49,6 +49,7 @@ dependencies: media_kit_libs_linux: ^1.1.3 media_kit_native_event_loop: ^1.0.8 media_kit_libs_windows_audio: ^1.0.9 + intl: ^0.19.0 dev_dependencies: flutter_test: