diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9f8570d --- /dev/null +++ b/Makefile @@ -0,0 +1,3 @@ +proto: + protoc -I protobuf/ --dart_out=lib/pb protobuf/stillbox.proto google/protobuf/timestamp.proto + diff --git a/lib/main.dart b/lib/main.dart index b09a876..46e3626 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; -import 'lcd.dart'; -import 'keypad.dart'; +import 'views/radio.dart'; void main() { runApp(const MyApp()); @@ -25,62 +24,3 @@ class MyApp extends StatelessWidget { ); } } - -class MainRadio extends StatefulWidget { - const MainRadio({super.key, required this.title}); - - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - - final String title; - - @override - State createState() => _MainRadioState(); -} - -class _MainRadioState extends State { - @override - Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. - return Scaffold( - body: const Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. - child: SizedBox( - width: 500.0, - child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). - // - // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint" - // action in the IDE, or press "p" in the console), to see the - // wireframe for each widget. - mainAxisAlignment: MainAxisAlignment.start, - children: [ - ScannerLabel(), - LCD(), - Keypad(), - ], - )), - ), - ); - } -} diff --git a/lib/pb/google/protobuf/timestamp.pb.dart b/lib/pb/google/protobuf/timestamp.pb.dart new file mode 100644 index 0000000..ea44b44 --- /dev/null +++ b/lib/pb/google/protobuf/timestamp.pb.dart @@ -0,0 +1,188 @@ +// +// Generated code. Do not modify. +// source: google/protobuf/timestamp.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:core' as $core; + +import 'package:fixnum/fixnum.dart' as $fixnum; +import 'package:protobuf/protobuf.dart' as $pb; +import 'package:protobuf/src/protobuf/mixins/well_known.dart' as $mixin; + +/// A Timestamp represents a point in time independent of any time zone or local +/// calendar, encoded as a count of seconds and fractions of seconds at +/// nanosecond resolution. The count is relative to an epoch at UTC midnight on +/// January 1, 1970, in the proleptic Gregorian calendar which extends the +/// Gregorian calendar backwards to year one. +/// +/// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap +/// second table is needed for interpretation, using a [24-hour linear +/// smear](https://developers.google.com/time/smear). +/// +/// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By +/// restricting to that range, we ensure that we can convert to and from [RFC +/// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings. +/// +/// # Examples +/// +/// Example 1: Compute Timestamp from POSIX `time()`. +/// +/// Timestamp timestamp; +/// timestamp.set_seconds(time(NULL)); +/// timestamp.set_nanos(0); +/// +/// Example 2: Compute Timestamp from POSIX `gettimeofday()`. +/// +/// struct timeval tv; +/// gettimeofday(&tv, NULL); +/// +/// Timestamp timestamp; +/// timestamp.set_seconds(tv.tv_sec); +/// timestamp.set_nanos(tv.tv_usec * 1000); +/// +/// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. +/// +/// FILETIME ft; +/// GetSystemTimeAsFileTime(&ft); +/// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; +/// +/// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z +/// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. +/// Timestamp timestamp; +/// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); +/// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); +/// +/// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. +/// +/// long millis = System.currentTimeMillis(); +/// +/// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) +/// .setNanos((int) ((millis % 1000) * 1000000)).build(); +/// +/// Example 5: Compute Timestamp from Java `Instant.now()`. +/// +/// Instant now = Instant.now(); +/// +/// Timestamp timestamp = +/// Timestamp.newBuilder().setSeconds(now.getEpochSecond()) +/// .setNanos(now.getNano()).build(); +/// +/// Example 6: Compute Timestamp from current time in Python. +/// +/// timestamp = Timestamp() +/// timestamp.GetCurrentTime() +/// +/// # JSON Mapping +/// +/// In JSON format, the Timestamp type is encoded as a string in the +/// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the +/// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" +/// where {year} is always expressed using four digits while {month}, {day}, +/// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional +/// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), +/// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone +/// is required. A proto3 JSON serializer should always use UTC (as indicated by +/// "Z") when printing the Timestamp type and a proto3 JSON parser should be +/// able to accept both UTC and other timezones (as indicated by an offset). +/// +/// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past +/// 01:30 UTC on January 15, 2017. +/// +/// In JavaScript, one can convert a Date object to this format using the +/// standard +/// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString) +/// method. In Python, a standard `datetime.datetime` object can be converted +/// to this format using +/// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with +/// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use +/// the Joda Time's [`ISODateTimeFormat.dateTime()`]( +/// http://joda-time.sourceforge.net/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime() +/// ) to obtain a formatter capable of generating timestamps in this format. +class Timestamp extends $pb.GeneratedMessage with $mixin.TimestampMixin { + factory Timestamp({ + $fixnum.Int64? seconds, + $core.int? nanos, + }) { + final $result = create(); + if (seconds != null) { + $result.seconds = seconds; + } + if (nanos != null) { + $result.nanos = nanos; + } + return $result; + } + Timestamp._() : super(); + factory Timestamp.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Timestamp.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Timestamp', package: const $pb.PackageName(_omitMessageNames ? '' : 'google.protobuf'), createEmptyInstance: create, toProto3Json: $mixin.TimestampMixin.toProto3JsonHelper, fromProto3Json: $mixin.TimestampMixin.fromProto3JsonHelper) + ..aInt64(1, _omitFieldNames ? '' : 'seconds') + ..a<$core.int>(2, _omitFieldNames ? '' : 'nanos', $pb.PbFieldType.O3) + ..hasRequiredFields = false + ; + + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Timestamp clone() => Timestamp()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Timestamp copyWith(void Function(Timestamp) updates) => super.copyWith((message) => updates(message as Timestamp)) as Timestamp; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static Timestamp create() => Timestamp._(); + Timestamp createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Timestamp getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Timestamp? _defaultInstance; + + /// Represents seconds of UTC time since Unix epoch + /// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + /// 9999-12-31T23:59:59Z inclusive. + @$pb.TagNumber(1) + $fixnum.Int64 get seconds => $_getI64(0); + @$pb.TagNumber(1) + set seconds($fixnum.Int64 v) { $_setInt64(0, v); } + @$pb.TagNumber(1) + $core.bool hasSeconds() => $_has(0); + @$pb.TagNumber(1) + void clearSeconds() => clearField(1); + + /// Non-negative fractions of a second at nanosecond resolution. Negative + /// second values with fractions must still have non-negative nanos values + /// that count forward in time. Must be from 0 to 999,999,999 + /// inclusive. + @$pb.TagNumber(2) + $core.int get nanos => $_getIZ(1); + @$pb.TagNumber(2) + set nanos($core.int v) { $_setSignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasNanos() => $_has(1); + @$pb.TagNumber(2) + void clearNanos() => clearField(2); + /// Creates a new instance from [dateTime]. + /// + /// Time zone information will not be preserved. + static Timestamp fromDateTime($core.DateTime dateTime) { + final result = create(); + $mixin.TimestampMixin.setFromDateTime(result, dateTime); + return result; + } +} + + +const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names'); +const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names'); diff --git a/lib/pb/google/protobuf/timestamp.pbenum.dart b/lib/pb/google/protobuf/timestamp.pbenum.dart new file mode 100644 index 0000000..30275f6 --- /dev/null +++ b/lib/pb/google/protobuf/timestamp.pbenum.dart @@ -0,0 +1,11 @@ +// +// Generated code. Do not modify. +// source: google/protobuf/timestamp.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + diff --git a/lib/pb/google/protobuf/timestamp.pbjson.dart b/lib/pb/google/protobuf/timestamp.pbjson.dart new file mode 100644 index 0000000..3dfd63b --- /dev/null +++ b/lib/pb/google/protobuf/timestamp.pbjson.dart @@ -0,0 +1,29 @@ +// +// Generated code. Do not modify. +// source: google/protobuf/timestamp.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:convert' as $convert; +import 'dart:core' as $core; +import 'dart:typed_data' as $typed_data; + +@$core.Deprecated('Use timestampDescriptor instead') +const Timestamp$json = { + '1': 'Timestamp', + '2': [ + {'1': 'seconds', '3': 1, '4': 1, '5': 3, '10': 'seconds'}, + {'1': 'nanos', '3': 2, '4': 1, '5': 5, '10': 'nanos'}, + ], +}; + +/// Descriptor for `Timestamp`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List timestampDescriptor = $convert.base64Decode( + 'CglUaW1lc3RhbXASGAoHc2Vjb25kcxgBIAEoA1IHc2Vjb25kcxIUCgVuYW5vcxgCIAEoBVIFbm' + 'Fub3M='); + diff --git a/lib/pb/google/protobuf/timestamp.pbserver.dart b/lib/pb/google/protobuf/timestamp.pbserver.dart new file mode 100644 index 0000000..6580f16 --- /dev/null +++ b/lib/pb/google/protobuf/timestamp.pbserver.dart @@ -0,0 +1,14 @@ +// +// Generated code. Do not modify. +// source: google/protobuf/timestamp.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names +// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +export 'timestamp.pb.dart'; + diff --git a/lib/pb/stillbox.pb.dart b/lib/pb/stillbox.pb.dart new file mode 100644 index 0000000..fb3bc72 --- /dev/null +++ b/lib/pb/stillbox.pb.dart @@ -0,0 +1,818 @@ +// +// Generated code. Do not modify. +// source: stillbox.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:core' as $core; + +import 'package:fixnum/fixnum.dart' as $fixnum; +import 'package:protobuf/protobuf.dart' as $pb; + +import 'google/protobuf/timestamp.pb.dart' as $0; +import 'stillbox.pbenum.dart'; + +export 'stillbox.pbenum.dart'; + +enum Message_ToClientMessage { + call, + notification, + popup, + error, + notSet +} + +class Message extends $pb.GeneratedMessage { + factory Message({ + Call? call, + Notification? notification, + UserPopup? popup, + Error? error, + }) { + final $result = create(); + if (call != null) { + $result.call = call; + } + if (notification != null) { + $result.notification = notification; + } + if (popup != null) { + $result.popup = popup; + } + if (error != null) { + $result.error = error; + } + return $result; + } + Message._() : super(); + factory Message.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Message.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static const $core.Map<$core.int, Message_ToClientMessage> _Message_ToClientMessageByTag = { + 1 : Message_ToClientMessage.call, + 2 : Message_ToClientMessage.notification, + 3 : Message_ToClientMessage.popup, + 4 : Message_ToClientMessage.error, + 0 : Message_ToClientMessage.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Message', package: const $pb.PackageName(_omitMessageNames ? '' : 'stillbox'), createEmptyInstance: create) + ..oo(0, [1, 2, 3, 4]) + ..aOM(1, _omitFieldNames ? '' : 'call', subBuilder: Call.create) + ..aOM(2, _omitFieldNames ? '' : 'notification', subBuilder: Notification.create) + ..aOM(3, _omitFieldNames ? '' : 'popup', subBuilder: UserPopup.create) + ..aOM(4, _omitFieldNames ? '' : 'error', subBuilder: Error.create) + ..hasRequiredFields = false + ; + + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Message clone() => Message()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Message copyWith(void Function(Message) updates) => super.copyWith((message) => updates(message as Message)) as Message; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static Message create() => Message._(); + Message createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Message getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Message? _defaultInstance; + + Message_ToClientMessage whichToClientMessage() => _Message_ToClientMessageByTag[$_whichOneof(0)]!; + void clearToClientMessage() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + Call get call => $_getN(0); + @$pb.TagNumber(1) + set call(Call v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasCall() => $_has(0); + @$pb.TagNumber(1) + void clearCall() => clearField(1); + @$pb.TagNumber(1) + Call ensureCall() => $_ensure(0); + + @$pb.TagNumber(2) + Notification get notification => $_getN(1); + @$pb.TagNumber(2) + set notification(Notification v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasNotification() => $_has(1); + @$pb.TagNumber(2) + void clearNotification() => clearField(2); + @$pb.TagNumber(2) + Notification ensureNotification() => $_ensure(1); + + @$pb.TagNumber(3) + UserPopup get popup => $_getN(2); + @$pb.TagNumber(3) + set popup(UserPopup v) { setField(3, v); } + @$pb.TagNumber(3) + $core.bool hasPopup() => $_has(2); + @$pb.TagNumber(3) + void clearPopup() => clearField(3); + @$pb.TagNumber(3) + UserPopup ensurePopup() => $_ensure(2); + + @$pb.TagNumber(4) + Error get error => $_getN(3); + @$pb.TagNumber(4) + set error(Error v) { setField(4, v); } + @$pb.TagNumber(4) + $core.bool hasError() => $_has(3); + @$pb.TagNumber(4) + void clearError() => clearField(4); + @$pb.TagNumber(4) + Error ensureError() => $_ensure(3); +} + +class Call extends $pb.GeneratedMessage { + factory Call({ + $core.String? audioName, + $core.String? audioType, + $0.Timestamp? dateTime, + $core.int? system, + $core.int? talkgroup, + $core.int? source, + $fixnum.Int64? frequency, + $core.Iterable<$fixnum.Int64>? frequencies, + $core.Iterable<$core.int>? patches, + $core.Iterable<$core.int>? sources, + $core.List<$core.int>? audio, + }) { + final $result = create(); + if (audioName != null) { + $result.audioName = audioName; + } + if (audioType != null) { + $result.audioType = audioType; + } + if (dateTime != null) { + $result.dateTime = dateTime; + } + if (system != null) { + $result.system = system; + } + if (talkgroup != null) { + $result.talkgroup = talkgroup; + } + if (source != null) { + $result.source = source; + } + if (frequency != null) { + $result.frequency = frequency; + } + if (frequencies != null) { + $result.frequencies.addAll(frequencies); + } + if (patches != null) { + $result.patches.addAll(patches); + } + if (sources != null) { + $result.sources.addAll(sources); + } + if (audio != null) { + $result.audio = audio; + } + return $result; + } + Call._() : super(); + factory Call.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Call.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Call', package: const $pb.PackageName(_omitMessageNames ? '' : 'stillbox'), createEmptyInstance: create) + ..aOS(1, _omitFieldNames ? '' : 'audioName', protoName: 'audioName') + ..aOS(2, _omitFieldNames ? '' : 'audioType', protoName: 'audioType') + ..aOM<$0.Timestamp>(3, _omitFieldNames ? '' : 'dateTime', protoName: 'dateTime', subBuilder: $0.Timestamp.create) + ..a<$core.int>(4, _omitFieldNames ? '' : 'system', $pb.PbFieldType.O3) + ..a<$core.int>(5, _omitFieldNames ? '' : 'talkgroup', $pb.PbFieldType.O3) + ..a<$core.int>(6, _omitFieldNames ? '' : 'source', $pb.PbFieldType.O3) + ..aInt64(7, _omitFieldNames ? '' : 'frequency') + ..p<$fixnum.Int64>(8, _omitFieldNames ? '' : 'frequencies', $pb.PbFieldType.K6) + ..p<$core.int>(9, _omitFieldNames ? '' : 'patches', $pb.PbFieldType.K3) + ..p<$core.int>(10, _omitFieldNames ? '' : 'sources', $pb.PbFieldType.K3) + ..a<$core.List<$core.int>>(11, _omitFieldNames ? '' : 'audio', $pb.PbFieldType.OY) + ..hasRequiredFields = false + ; + + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Call clone() => Call()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Call copyWith(void Function(Call) updates) => super.copyWith((message) => updates(message as Call)) as Call; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static Call create() => Call._(); + Call createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Call getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Call? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get audioName => $_getSZ(0); + @$pb.TagNumber(1) + set audioName($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasAudioName() => $_has(0); + @$pb.TagNumber(1) + void clearAudioName() => clearField(1); + + @$pb.TagNumber(2) + $core.String get audioType => $_getSZ(1); + @$pb.TagNumber(2) + set audioType($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasAudioType() => $_has(1); + @$pb.TagNumber(2) + void clearAudioType() => clearField(2); + + @$pb.TagNumber(3) + $0.Timestamp get dateTime => $_getN(2); + @$pb.TagNumber(3) + set dateTime($0.Timestamp v) { setField(3, v); } + @$pb.TagNumber(3) + $core.bool hasDateTime() => $_has(2); + @$pb.TagNumber(3) + void clearDateTime() => clearField(3); + @$pb.TagNumber(3) + $0.Timestamp ensureDateTime() => $_ensure(2); + + @$pb.TagNumber(4) + $core.int get system => $_getIZ(3); + @$pb.TagNumber(4) + set system($core.int v) { $_setSignedInt32(3, v); } + @$pb.TagNumber(4) + $core.bool hasSystem() => $_has(3); + @$pb.TagNumber(4) + void clearSystem() => clearField(4); + + @$pb.TagNumber(5) + $core.int get talkgroup => $_getIZ(4); + @$pb.TagNumber(5) + set talkgroup($core.int v) { $_setSignedInt32(4, v); } + @$pb.TagNumber(5) + $core.bool hasTalkgroup() => $_has(4); + @$pb.TagNumber(5) + void clearTalkgroup() => clearField(5); + + @$pb.TagNumber(6) + $core.int get source => $_getIZ(5); + @$pb.TagNumber(6) + set source($core.int v) { $_setSignedInt32(5, v); } + @$pb.TagNumber(6) + $core.bool hasSource() => $_has(5); + @$pb.TagNumber(6) + void clearSource() => clearField(6); + + @$pb.TagNumber(7) + $fixnum.Int64 get frequency => $_getI64(6); + @$pb.TagNumber(7) + set frequency($fixnum.Int64 v) { $_setInt64(6, v); } + @$pb.TagNumber(7) + $core.bool hasFrequency() => $_has(6); + @$pb.TagNumber(7) + void clearFrequency() => clearField(7); + + @$pb.TagNumber(8) + $core.List<$fixnum.Int64> get frequencies => $_getList(7); + + @$pb.TagNumber(9) + $core.List<$core.int> get patches => $_getList(8); + + @$pb.TagNumber(10) + $core.List<$core.int> get sources => $_getList(9); + + @$pb.TagNumber(11) + $core.List<$core.int> get audio => $_getN(10); + @$pb.TagNumber(11) + set audio($core.List<$core.int> v) { $_setBytes(10, v); } + @$pb.TagNumber(11) + $core.bool hasAudio() => $_has(10); + @$pb.TagNumber(11) + void clearAudio() => clearField(11); +} + +class UserPopup extends $pb.GeneratedMessage { + factory UserPopup({ + $core.String? msg, + }) { + final $result = create(); + if (msg != null) { + $result.msg = msg; + } + return $result; + } + UserPopup._() : super(); + factory UserPopup.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory UserPopup.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'UserPopup', package: const $pb.PackageName(_omitMessageNames ? '' : 'stillbox'), createEmptyInstance: create) + ..aOS(1, _omitFieldNames ? '' : 'msg') + ..hasRequiredFields = false + ; + + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + UserPopup clone() => UserPopup()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + UserPopup copyWith(void Function(UserPopup) updates) => super.copyWith((message) => updates(message as UserPopup)) as UserPopup; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static UserPopup create() => UserPopup._(); + UserPopup createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static UserPopup getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static UserPopup? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get msg => $_getSZ(0); + @$pb.TagNumber(1) + set msg($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasMsg() => $_has(0); + @$pb.TagNumber(1) + void clearMsg() => clearField(1); +} + +class Error extends $pb.GeneratedMessage { + factory Error({ + $core.String? error, + }) { + final $result = create(); + if (error != null) { + $result.error = error; + } + return $result; + } + Error._() : super(); + factory Error.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Error.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Error', package: const $pb.PackageName(_omitMessageNames ? '' : 'stillbox'), createEmptyInstance: create) + ..aOS(1, _omitFieldNames ? '' : 'error') + ..hasRequiredFields = false + ; + + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Error clone() => Error()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Error copyWith(void Function(Error) updates) => super.copyWith((message) => updates(message as Error)) as Error; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static Error create() => Error._(); + Error createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Error getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Error? _defaultInstance; + + @$pb.TagNumber(1) + $core.String get error => $_getSZ(0); + @$pb.TagNumber(1) + set error($core.String v) { $_setString(0, v); } + @$pb.TagNumber(1) + $core.bool hasError() => $_has(0); + @$pb.TagNumber(1) + void clearError() => clearField(1); +} + +class Notification extends $pb.GeneratedMessage { + factory Notification({ + $0.Timestamp? dateTime, + $core.String? msg, + $core.String? actionUrl, + }) { + final $result = create(); + if (dateTime != null) { + $result.dateTime = dateTime; + } + if (msg != null) { + $result.msg = msg; + } + if (actionUrl != null) { + $result.actionUrl = actionUrl; + } + return $result; + } + Notification._() : super(); + factory Notification.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Notification.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Notification', package: const $pb.PackageName(_omitMessageNames ? '' : 'stillbox'), createEmptyInstance: create) + ..aOM<$0.Timestamp>(1, _omitFieldNames ? '' : 'dateTime', protoName: 'dateTime', subBuilder: $0.Timestamp.create) + ..aOS(2, _omitFieldNames ? '' : 'msg') + ..aOS(3, _omitFieldNames ? '' : 'actionUrl', protoName: 'actionUrl') + ..hasRequiredFields = false + ; + + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Notification clone() => Notification()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Notification copyWith(void Function(Notification) updates) => super.copyWith((message) => updates(message as Notification)) as Notification; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static Notification create() => Notification._(); + Notification createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Notification getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Notification? _defaultInstance; + + @$pb.TagNumber(1) + $0.Timestamp get dateTime => $_getN(0); + @$pb.TagNumber(1) + set dateTime($0.Timestamp v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasDateTime() => $_has(0); + @$pb.TagNumber(1) + void clearDateTime() => clearField(1); + @$pb.TagNumber(1) + $0.Timestamp ensureDateTime() => $_ensure(0); + + @$pb.TagNumber(2) + $core.String get msg => $_getSZ(1); + @$pb.TagNumber(2) + set msg($core.String v) { $_setString(1, v); } + @$pb.TagNumber(2) + $core.bool hasMsg() => $_has(1); + @$pb.TagNumber(2) + void clearMsg() => clearField(2); + + @$pb.TagNumber(3) + $core.String get actionUrl => $_getSZ(2); + @$pb.TagNumber(3) + set actionUrl($core.String v) { $_setString(2, v); } + @$pb.TagNumber(3) + $core.bool hasActionUrl() => $_has(2); + @$pb.TagNumber(3) + void clearActionUrl() => clearField(3); +} + +enum Command_Command { + liveCommand, + searchCommand, + notSet +} + +class Command extends $pb.GeneratedMessage { + factory Command({ + Live? liveCommand, + Search? searchCommand, + }) { + final $result = create(); + if (liveCommand != null) { + $result.liveCommand = liveCommand; + } + if (searchCommand != null) { + $result.searchCommand = searchCommand; + } + return $result; + } + Command._() : super(); + factory Command.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Command.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static const $core.Map<$core.int, Command_Command> _Command_CommandByTag = { + 1 : Command_Command.liveCommand, + 2 : Command_Command.searchCommand, + 0 : Command_Command.notSet + }; + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Command', package: const $pb.PackageName(_omitMessageNames ? '' : 'stillbox'), createEmptyInstance: create) + ..oo(0, [1, 2]) + ..aOM(1, _omitFieldNames ? '' : 'liveCommand', protoName: 'liveCommand', subBuilder: Live.create) + ..aOM(2, _omitFieldNames ? '' : 'searchCommand', protoName: 'searchCommand', subBuilder: Search.create) + ..hasRequiredFields = false + ; + + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Command clone() => Command()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Command copyWith(void Function(Command) updates) => super.copyWith((message) => updates(message as Command)) as Command; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static Command create() => Command._(); + Command createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Command getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Command? _defaultInstance; + + Command_Command whichCommand() => _Command_CommandByTag[$_whichOneof(0)]!; + void clearCommand() => clearField($_whichOneof(0)); + + @$pb.TagNumber(1) + Live get liveCommand => $_getN(0); + @$pb.TagNumber(1) + set liveCommand(Live v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasLiveCommand() => $_has(0); + @$pb.TagNumber(1) + void clearLiveCommand() => clearField(1); + @$pb.TagNumber(1) + Live ensureLiveCommand() => $_ensure(0); + + @$pb.TagNumber(2) + Search get searchCommand => $_getN(1); + @$pb.TagNumber(2) + set searchCommand(Search v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasSearchCommand() => $_has(1); + @$pb.TagNumber(2) + void clearSearchCommand() => clearField(2); + @$pb.TagNumber(2) + Search ensureSearchCommand() => $_ensure(1); +} + +class Live extends $pb.GeneratedMessage { + factory Live({ + LiveState? state, + Filter? filter, + }) { + final $result = create(); + if (state != null) { + $result.state = state; + } + if (filter != null) { + $result.filter = filter; + } + return $result; + } + Live._() : super(); + factory Live.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Live.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Live', package: const $pb.PackageName(_omitMessageNames ? '' : 'stillbox'), createEmptyInstance: create) + ..e(1, _omitFieldNames ? '' : 'state', $pb.PbFieldType.OE, defaultOrMaker: LiveState.LS_STOPPED, valueOf: LiveState.valueOf, enumValues: LiveState.values) + ..aOM(2, _omitFieldNames ? '' : 'filter', subBuilder: Filter.create) + ..hasRequiredFields = false + ; + + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Live clone() => Live()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Live copyWith(void Function(Live) updates) => super.copyWith((message) => updates(message as Live)) as Live; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static Live create() => Live._(); + Live createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Live getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Live? _defaultInstance; + + @$pb.TagNumber(1) + LiveState get state => $_getN(0); + @$pb.TagNumber(1) + set state(LiveState v) { setField(1, v); } + @$pb.TagNumber(1) + $core.bool hasState() => $_has(0); + @$pb.TagNumber(1) + void clearState() => clearField(1); + + @$pb.TagNumber(2) + Filter get filter => $_getN(1); + @$pb.TagNumber(2) + set filter(Filter v) { setField(2, v); } + @$pb.TagNumber(2) + $core.bool hasFilter() => $_has(1); + @$pb.TagNumber(2) + void clearFilter() => clearField(2); + @$pb.TagNumber(2) + Filter ensureFilter() => $_ensure(1); +} + +class Talkgroup extends $pb.GeneratedMessage { + factory Talkgroup({ + $core.int? system, + $core.int? talkgroup, + }) { + final $result = create(); + if (system != null) { + $result.system = system; + } + if (talkgroup != null) { + $result.talkgroup = talkgroup; + } + return $result; + } + Talkgroup._() : super(); + factory Talkgroup.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Talkgroup.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Talkgroup', package: const $pb.PackageName(_omitMessageNames ? '' : 'stillbox'), createEmptyInstance: create) + ..a<$core.int>(1, _omitFieldNames ? '' : 'system', $pb.PbFieldType.O3) + ..a<$core.int>(2, _omitFieldNames ? '' : 'talkgroup', $pb.PbFieldType.O3) + ..hasRequiredFields = false + ; + + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Talkgroup clone() => Talkgroup()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Talkgroup copyWith(void Function(Talkgroup) updates) => super.copyWith((message) => updates(message as Talkgroup)) as Talkgroup; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static Talkgroup create() => Talkgroup._(); + Talkgroup createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Talkgroup getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Talkgroup? _defaultInstance; + + @$pb.TagNumber(1) + $core.int get system => $_getIZ(0); + @$pb.TagNumber(1) + set system($core.int v) { $_setSignedInt32(0, v); } + @$pb.TagNumber(1) + $core.bool hasSystem() => $_has(0); + @$pb.TagNumber(1) + void clearSystem() => clearField(1); + + @$pb.TagNumber(2) + $core.int get talkgroup => $_getIZ(1); + @$pb.TagNumber(2) + set talkgroup($core.int v) { $_setSignedInt32(1, v); } + @$pb.TagNumber(2) + $core.bool hasTalkgroup() => $_has(1); + @$pb.TagNumber(2) + void clearTalkgroup() => clearField(2); +} + +class Filter extends $pb.GeneratedMessage { + factory Filter({ + $core.Iterable? talkgroups, + $core.Iterable? talkgroupsNot, + $core.Iterable<$core.String>? talkgroupTagsAll, + $core.Iterable<$core.String>? talkgroupTagsAny, + $core.Iterable<$core.String>? talkgroupTagsNot, + }) { + final $result = create(); + if (talkgroups != null) { + $result.talkgroups.addAll(talkgroups); + } + if (talkgroupsNot != null) { + $result.talkgroupsNot.addAll(talkgroupsNot); + } + if (talkgroupTagsAll != null) { + $result.talkgroupTagsAll.addAll(talkgroupTagsAll); + } + if (talkgroupTagsAny != null) { + $result.talkgroupTagsAny.addAll(talkgroupTagsAny); + } + if (talkgroupTagsNot != null) { + $result.talkgroupTagsNot.addAll(talkgroupTagsNot); + } + return $result; + } + Filter._() : super(); + factory Filter.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Filter.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Filter', package: const $pb.PackageName(_omitMessageNames ? '' : 'stillbox'), createEmptyInstance: create) + ..pc(1, _omitFieldNames ? '' : 'talkgroups', $pb.PbFieldType.PM, subBuilder: Talkgroup.create) + ..pc(2, _omitFieldNames ? '' : 'talkgroupsNot', $pb.PbFieldType.PM, subBuilder: Talkgroup.create) + ..pPS(3, _omitFieldNames ? '' : 'talkgroupTagsAll') + ..pPS(4, _omitFieldNames ? '' : 'talkgroupTagsAny') + ..pPS(5, _omitFieldNames ? '' : 'talkgroupTagsNot') + ..hasRequiredFields = false + ; + + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Filter clone() => Filter()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Filter copyWith(void Function(Filter) updates) => super.copyWith((message) => updates(message as Filter)) as Filter; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static Filter create() => Filter._(); + Filter createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Filter getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Filter? _defaultInstance; + + @$pb.TagNumber(1) + $core.List get talkgroups => $_getList(0); + + @$pb.TagNumber(2) + $core.List get talkgroupsNot => $_getList(1); + + @$pb.TagNumber(3) + $core.List<$core.String> get talkgroupTagsAll => $_getList(2); + + @$pb.TagNumber(4) + $core.List<$core.String> get talkgroupTagsAny => $_getList(3); + + @$pb.TagNumber(5) + $core.List<$core.String> get talkgroupTagsNot => $_getList(4); +} + +class Search extends $pb.GeneratedMessage { + factory Search() => create(); + Search._() : super(); + factory Search.fromBuffer($core.List<$core.int> i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromBuffer(i, r); + factory Search.fromJson($core.String i, [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) => create()..mergeFromJson(i, r); + + static final $pb.BuilderInfo _i = $pb.BuilderInfo(_omitMessageNames ? '' : 'Search', package: const $pb.PackageName(_omitMessageNames ? '' : 'stillbox'), createEmptyInstance: create) + ..hasRequiredFields = false + ; + + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.deepCopy] instead. ' + 'Will be removed in next major version') + Search clone() => Search()..mergeFromMessage(this); + @$core.Deprecated( + 'Using this can add significant overhead to your binary. ' + 'Use [GeneratedMessageGenericExtensions.rebuild] instead. ' + 'Will be removed in next major version') + Search copyWith(void Function(Search) updates) => super.copyWith((message) => updates(message as Search)) as Search; + + $pb.BuilderInfo get info_ => _i; + + @$core.pragma('dart2js:noInline') + static Search create() => Search._(); + Search createEmptyInstance() => create(); + static $pb.PbList createRepeated() => $pb.PbList(); + @$core.pragma('dart2js:noInline') + static Search getDefault() => _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor(create); + static Search? _defaultInstance; +} + + +const _omitFieldNames = $core.bool.fromEnvironment('protobuf.omit_field_names'); +const _omitMessageNames = $core.bool.fromEnvironment('protobuf.omit_message_names'); diff --git a/lib/pb/stillbox.pbenum.dart b/lib/pb/stillbox.pbenum.dart new file mode 100644 index 0000000..02f5b7f --- /dev/null +++ b/lib/pb/stillbox.pbenum.dart @@ -0,0 +1,34 @@ +// +// Generated code. Do not modify. +// source: stillbox.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:core' as $core; + +import 'package:protobuf/protobuf.dart' as $pb; + +class LiveState extends $pb.ProtobufEnum { + static const LiveState LS_STOPPED = LiveState._(0, _omitEnumNames ? '' : 'LS_STOPPED'); + static const LiveState LS_LIVE = LiveState._(1, _omitEnumNames ? '' : 'LS_LIVE'); + static const LiveState LS_PAUSED = LiveState._(2, _omitEnumNames ? '' : 'LS_PAUSED'); + + static const $core.List values = [ + LS_STOPPED, + LS_LIVE, + LS_PAUSED, + ]; + + static final $core.Map<$core.int, LiveState> _byValue = $pb.ProtobufEnum.initByValue(values); + static LiveState? valueOf($core.int value) => _byValue[value]; + + const LiveState._($core.int v, $core.String n) : super(v, n); +} + + +const _omitEnumNames = $core.bool.fromEnvironment('protobuf.omit_enum_names'); diff --git a/lib/pb/stillbox.pbjson.dart b/lib/pb/stillbox.pbjson.dart new file mode 100644 index 0000000..f5cf222 --- /dev/null +++ b/lib/pb/stillbox.pbjson.dart @@ -0,0 +1,199 @@ +// +// Generated code. Do not modify. +// source: stillbox.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +import 'dart:convert' as $convert; +import 'dart:core' as $core; +import 'dart:typed_data' as $typed_data; + +@$core.Deprecated('Use liveStateDescriptor instead') +const LiveState$json = { + '1': 'LiveState', + '2': [ + {'1': 'LS_STOPPED', '2': 0}, + {'1': 'LS_LIVE', '2': 1}, + {'1': 'LS_PAUSED', '2': 2}, + ], +}; + +/// Descriptor for `LiveState`. Decode as a `google.protobuf.EnumDescriptorProto`. +final $typed_data.Uint8List liveStateDescriptor = $convert.base64Decode( + 'CglMaXZlU3RhdGUSDgoKTFNfU1RPUFBFRBAAEgsKB0xTX0xJVkUQARINCglMU19QQVVTRUQQAg' + '=='); + +@$core.Deprecated('Use messageDescriptor instead') +const Message$json = { + '1': 'Message', + '2': [ + {'1': 'call', '3': 1, '4': 1, '5': 11, '6': '.stillbox.Call', '9': 0, '10': 'call'}, + {'1': 'notification', '3': 2, '4': 1, '5': 11, '6': '.stillbox.Notification', '9': 0, '10': 'notification'}, + {'1': 'popup', '3': 3, '4': 1, '5': 11, '6': '.stillbox.UserPopup', '9': 0, '10': 'popup'}, + {'1': 'error', '3': 4, '4': 1, '5': 11, '6': '.stillbox.Error', '9': 0, '10': 'error'}, + ], + '8': [ + {'1': 'toClient_message'}, + ], +}; + +/// Descriptor for `Message`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List messageDescriptor = $convert.base64Decode( + 'CgdNZXNzYWdlEiQKBGNhbGwYASABKAsyDi5zdGlsbGJveC5DYWxsSABSBGNhbGwSPAoMbm90aW' + 'ZpY2F0aW9uGAIgASgLMhYuc3RpbGxib3guTm90aWZpY2F0aW9uSABSDG5vdGlmaWNhdGlvbhIr' + 'CgVwb3B1cBgDIAEoCzITLnN0aWxsYm94LlVzZXJQb3B1cEgAUgVwb3B1cBInCgVlcnJvchgEIA' + 'EoCzIPLnN0aWxsYm94LkVycm9ySABSBWVycm9yQhIKEHRvQ2xpZW50X21lc3NhZ2U='); + +@$core.Deprecated('Use callDescriptor instead') +const Call$json = { + '1': 'Call', + '2': [ + {'1': 'audioName', '3': 1, '4': 1, '5': 9, '10': 'audioName'}, + {'1': 'audioType', '3': 2, '4': 1, '5': 9, '10': 'audioType'}, + {'1': 'dateTime', '3': 3, '4': 1, '5': 11, '6': '.google.protobuf.Timestamp', '10': 'dateTime'}, + {'1': 'system', '3': 4, '4': 1, '5': 5, '10': 'system'}, + {'1': 'talkgroup', '3': 5, '4': 1, '5': 5, '10': 'talkgroup'}, + {'1': 'source', '3': 6, '4': 1, '5': 5, '10': 'source'}, + {'1': 'frequency', '3': 7, '4': 1, '5': 3, '10': 'frequency'}, + {'1': 'frequencies', '3': 8, '4': 3, '5': 3, '10': 'frequencies'}, + {'1': 'patches', '3': 9, '4': 3, '5': 5, '10': 'patches'}, + {'1': 'sources', '3': 10, '4': 3, '5': 5, '10': 'sources'}, + {'1': 'audio', '3': 11, '4': 1, '5': 12, '10': 'audio'}, + ], +}; + +/// Descriptor for `Call`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List callDescriptor = $convert.base64Decode( + 'CgRDYWxsEhwKCWF1ZGlvTmFtZRgBIAEoCVIJYXVkaW9OYW1lEhwKCWF1ZGlvVHlwZRgCIAEoCV' + 'IJYXVkaW9UeXBlEjYKCGRhdGVUaW1lGAMgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFt' + 'cFIIZGF0ZVRpbWUSFgoGc3lzdGVtGAQgASgFUgZzeXN0ZW0SHAoJdGFsa2dyb3VwGAUgASgFUg' + 'l0YWxrZ3JvdXASFgoGc291cmNlGAYgASgFUgZzb3VyY2USHAoJZnJlcXVlbmN5GAcgASgDUglm' + 'cmVxdWVuY3kSIAoLZnJlcXVlbmNpZXMYCCADKANSC2ZyZXF1ZW5jaWVzEhgKB3BhdGNoZXMYCS' + 'ADKAVSB3BhdGNoZXMSGAoHc291cmNlcxgKIAMoBVIHc291cmNlcxIUCgVhdWRpbxgLIAEoDFIF' + 'YXVkaW8='); + +@$core.Deprecated('Use userPopupDescriptor instead') +const UserPopup$json = { + '1': 'UserPopup', + '2': [ + {'1': 'msg', '3': 1, '4': 1, '5': 9, '10': 'msg'}, + ], +}; + +/// Descriptor for `UserPopup`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List userPopupDescriptor = $convert.base64Decode( + 'CglVc2VyUG9wdXASEAoDbXNnGAEgASgJUgNtc2c='); + +@$core.Deprecated('Use errorDescriptor instead') +const Error$json = { + '1': 'Error', + '2': [ + {'1': 'error', '3': 1, '4': 1, '5': 9, '10': 'error'}, + ], +}; + +/// Descriptor for `Error`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List errorDescriptor = $convert.base64Decode( + 'CgVFcnJvchIUCgVlcnJvchgBIAEoCVIFZXJyb3I='); + +@$core.Deprecated('Use notificationDescriptor instead') +const Notification$json = { + '1': 'Notification', + '2': [ + {'1': 'dateTime', '3': 1, '4': 1, '5': 11, '6': '.google.protobuf.Timestamp', '10': 'dateTime'}, + {'1': 'msg', '3': 2, '4': 1, '5': 9, '10': 'msg'}, + {'1': 'actionUrl', '3': 3, '4': 1, '5': 9, '10': 'actionUrl'}, + ], +}; + +/// Descriptor for `Notification`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List notificationDescriptor = $convert.base64Decode( + 'CgxOb3RpZmljYXRpb24SNgoIZGF0ZVRpbWUYASABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZX' + 'N0YW1wUghkYXRlVGltZRIQCgNtc2cYAiABKAlSA21zZxIcCglhY3Rpb25VcmwYAyABKAlSCWFj' + 'dGlvblVybA=='); + +@$core.Deprecated('Use commandDescriptor instead') +const Command$json = { + '1': 'Command', + '2': [ + {'1': 'liveCommand', '3': 1, '4': 1, '5': 11, '6': '.stillbox.Live', '9': 0, '10': 'liveCommand'}, + {'1': 'searchCommand', '3': 2, '4': 1, '5': 11, '6': '.stillbox.Search', '9': 0, '10': 'searchCommand'}, + ], + '8': [ + {'1': 'command'}, + ], +}; + +/// Descriptor for `Command`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List commandDescriptor = $convert.base64Decode( + 'CgdDb21tYW5kEjIKC2xpdmVDb21tYW5kGAEgASgLMg4uc3RpbGxib3guTGl2ZUgAUgtsaXZlQ2' + '9tbWFuZBI4Cg1zZWFyY2hDb21tYW5kGAIgASgLMhAuc3RpbGxib3guU2VhcmNoSABSDXNlYXJj' + 'aENvbW1hbmRCCQoHY29tbWFuZA=='); + +@$core.Deprecated('Use liveDescriptor instead') +const Live$json = { + '1': 'Live', + '2': [ + {'1': 'state', '3': 1, '4': 1, '5': 14, '6': '.stillbox.LiveState', '9': 0, '10': 'state', '17': true}, + {'1': 'filter', '3': 2, '4': 1, '5': 11, '6': '.stillbox.Filter', '9': 1, '10': 'filter', '17': true}, + ], + '8': [ + {'1': '_state'}, + {'1': '_filter'}, + ], +}; + +/// Descriptor for `Live`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List liveDescriptor = $convert.base64Decode( + 'CgRMaXZlEi4KBXN0YXRlGAEgASgOMhMuc3RpbGxib3guTGl2ZVN0YXRlSABSBXN0YXRliAEBEi' + '0KBmZpbHRlchgCIAEoCzIQLnN0aWxsYm94LkZpbHRlckgBUgZmaWx0ZXKIAQFCCAoGX3N0YXRl' + 'QgkKB19maWx0ZXI='); + +@$core.Deprecated('Use talkgroupDescriptor instead') +const Talkgroup$json = { + '1': 'Talkgroup', + '2': [ + {'1': 'system', '3': 1, '4': 1, '5': 5, '10': 'system'}, + {'1': 'talkgroup', '3': 2, '4': 1, '5': 5, '10': 'talkgroup'}, + ], +}; + +/// Descriptor for `Talkgroup`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List talkgroupDescriptor = $convert.base64Decode( + 'CglUYWxrZ3JvdXASFgoGc3lzdGVtGAEgASgFUgZzeXN0ZW0SHAoJdGFsa2dyb3VwGAIgASgFUg' + 'l0YWxrZ3JvdXA='); + +@$core.Deprecated('Use filterDescriptor instead') +const Filter$json = { + '1': 'Filter', + '2': [ + {'1': 'talkgroups', '3': 1, '4': 3, '5': 11, '6': '.stillbox.Talkgroup', '10': 'talkgroups'}, + {'1': 'talkgroups_not', '3': 2, '4': 3, '5': 11, '6': '.stillbox.Talkgroup', '10': 'talkgroupsNot'}, + {'1': 'talkgroup_tags_all', '3': 3, '4': 3, '5': 9, '10': 'talkgroupTagsAll'}, + {'1': 'talkgroup_tags_any', '3': 4, '4': 3, '5': 9, '10': 'talkgroupTagsAny'}, + {'1': 'talkgroup_tags_not', '3': 5, '4': 3, '5': 9, '10': 'talkgroupTagsNot'}, + ], +}; + +/// Descriptor for `Filter`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List filterDescriptor = $convert.base64Decode( + 'CgZGaWx0ZXISMwoKdGFsa2dyb3VwcxgBIAMoCzITLnN0aWxsYm94LlRhbGtncm91cFIKdGFsa2' + 'dyb3VwcxI6Cg50YWxrZ3JvdXBzX25vdBgCIAMoCzITLnN0aWxsYm94LlRhbGtncm91cFINdGFs' + 'a2dyb3Vwc05vdBIsChJ0YWxrZ3JvdXBfdGFnc19hbGwYAyADKAlSEHRhbGtncm91cFRhZ3NBbG' + 'wSLAoSdGFsa2dyb3VwX3RhZ3NfYW55GAQgAygJUhB0YWxrZ3JvdXBUYWdzQW55EiwKEnRhbGtn' + 'cm91cF90YWdzX25vdBgFIAMoCVIQdGFsa2dyb3VwVGFnc05vdA=='); + +@$core.Deprecated('Use searchDescriptor instead') +const Search$json = { + '1': 'Search', +}; + +/// Descriptor for `Search`. Decode as a `google.protobuf.DescriptorProto`. +final $typed_data.Uint8List searchDescriptor = $convert.base64Decode( + 'CgZTZWFyY2g='); + diff --git a/lib/pb/stillbox.pbserver.dart b/lib/pb/stillbox.pbserver.dart new file mode 100644 index 0000000..e247f7d --- /dev/null +++ b/lib/pb/stillbox.pbserver.dart @@ -0,0 +1,14 @@ +// +// Generated code. Do not modify. +// source: stillbox.proto +// +// @dart = 2.12 + +// ignore_for_file: annotate_overrides, camel_case_types, comment_references +// ignore_for_file: constant_identifier_names +// ignore_for_file: deprecated_member_use_from_same_package, library_prefixes +// ignore_for_file: non_constant_identifier_names, prefer_final_fields +// ignore_for_file: unnecessary_import, unnecessary_this, unused_import + +export 'stillbox.pb.dart'; + diff --git a/lib/keypad.dart b/lib/views/keypad.dart similarity index 100% rename from lib/keypad.dart rename to lib/views/keypad.dart diff --git a/lib/lcd.dart b/lib/views/lcd.dart similarity index 100% rename from lib/lcd.dart rename to lib/views/lcd.dart diff --git a/lib/views/radio.dart b/lib/views/radio.dart new file mode 100644 index 0000000..97922db --- /dev/null +++ b/lib/views/radio.dart @@ -0,0 +1,62 @@ +import 'package:flutter/material.dart'; +import 'lcd.dart'; +import 'keypad.dart'; + +class MainRadio extends StatefulWidget { + const MainRadio({super.key, required this.title}); + + // This widget is the home page of your application. It is stateful, meaning + // that it has a State object (defined below) that contains fields that affect + // how it looks. + + // This class is the configuration for the state. It holds the values (in this + // case the title) provided by the parent (in this case the App widget) and + // used by the build method of the State. Fields in a Widget subclass are + // always marked "final". + + final String title; + + @override + State createState() => _MainRadioState(); +} + +class _MainRadioState extends State { + @override + Widget build(BuildContext context) { + // This method is rerun every time setState is called, for instance as done + // by the _incrementCounter method above. + // + // The Flutter framework has been optimized to make rerunning build methods + // fast, so that you can just rebuild anything that needs updating rather + // than having to individually change instances of widgets. + return Scaffold( + body: const Center( + // Center is a layout widget. It takes a single child and positions it + // in the middle of the parent. + child: SizedBox( + width: 500.0, + child: Column( + // Column is also a layout widget. It takes a list of children and + // arranges them vertically. By default, it sizes itself to fit its + // children horizontally, and tries to be as tall as its parent. + // + // Column has various properties to control how it sizes itself and + // how it positions its children. Here we use mainAxisAlignment to + // center the children vertically; the main axis here is the vertical + // axis because Columns are vertical (the cross axis would be + // horizontal). + // + // TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint" + // action in the IDE, or press "p" in the console), to see the + // wireframe for each widget. + mainAxisAlignment: MainAxisAlignment.start, + children: [ + ScannerLabel(), + LCD(), + Keypad(), + ], + )), + ), + ); + } +} diff --git a/protobuf/stillbox.proto b/protobuf/stillbox.proto new file mode 100644 index 0000000..ccaf9ca --- /dev/null +++ b/protobuf/stillbox.proto @@ -0,0 +1,76 @@ +syntax = "proto3"; +package stillbox; +option go_package = "./pb"; + +import "google/protobuf/timestamp.proto"; + +message Message { + oneof toClient_message { + Call call = 1; + Notification notification = 2; + UserPopup popup = 3; + Error error = 4; + } +} + +message Call { + string audioName = 1; + string audioType = 2; + google.protobuf.Timestamp dateTime = 3; + int32 system = 4; + int32 talkgroup = 5; + int32 source = 6; + int64 frequency = 7; + repeated int64 frequencies = 8; + repeated int32 patches = 9; + repeated int32 sources = 10; + bytes audio = 11; +} + +message UserPopup { + string msg = 1; +} + +message Error { + string error = 1; +} + +message Notification { + google.protobuf.Timestamp dateTime = 1; + string msg = 2; + string actionUrl = 3; +} + +message Command { + oneof command { + Live liveCommand = 1; + Search searchCommand = 2; + } +} + +enum LiveState { + LS_STOPPED = 0; + LS_LIVE = 1; + LS_PAUSED = 2; +} + +message Live { + optional LiveState state = 1; + optional Filter filter = 2; +} + +message Talkgroup { + int32 system = 1; + int32 talkgroup = 2; +} + +message Filter { + repeated Talkgroup talkgroups = 1; + repeated Talkgroup talkgroups_not = 2; + repeated string talkgroup_tags_all = 3; + repeated string talkgroup_tags_any = 4; + repeated string talkgroup_tags_not = 5; +} + +message Search { +} diff --git a/pubspec.lock b/pubspec.lock index 1302698..4c6d22a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -73,6 +73,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" + fixnum: + dependency: "direct main" + description: + name: fixnum + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + url: "https://pub.dev" + source: hosted + version: "1.1.0" flutter: dependency: "direct main" description: flutter @@ -243,6 +251,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + protobuf: + dependency: "direct main" + description: + name: protobuf + sha256: "68645b24e0716782e58948f8467fd42a880f255096a821f9e7d0ec625b00c84d" + url: "https://pub.dev" + source: hosted + version: "3.1.0" sky_engine: dependency: transitive description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 73a2655..75aa45d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -36,6 +36,8 @@ dependencies: # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.8 google_fonts: ^6.2.1 + fixnum: ^1.1.0 + protobuf: ^3.1.0 dev_dependencies: flutter_test: