diff --git a/analysis_options.yaml b/analysis_options.yaml index afd09ee..e1620f7 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -2,6 +2,14 @@ include: package:lint_hard/all.yaml analyzer: errors: invalid_annotation_target: ignore + exclude: + - '**/*.g.dart' + - '**/*.freezed.dart' + - '**/*.pb.dart' + - '**/*.pbenum.dart' + - '**/*.pbjson.dart' + - '**/*.pbserver.dart' linter: rules: - - unawaited_futures \ No newline at end of file + unawaited_futures: true + avoid_positional_boolean_parameters: false \ No newline at end of file diff --git a/lib/entities/identity.dart b/lib/entities/identity.dart index db0e2f1..21a5375 100644 --- a/lib/entities/identity.dart +++ b/lib/entities/identity.dart @@ -24,7 +24,8 @@ class AccountRecordInfo with _$AccountRecordInfo { // DHT Schema: DFLT(1) // DHT Key (Private): identityRecordKey // DHT Owner Key: identityPublicKey -// DHT Secret: identitySecretKey (stored encrypted with unlock code in local table store) +// DHT Secret: identitySecretKey (stored encrypted +// with unlock code in local table store) @freezed class Identity with _$Identity { const factory Identity({ @@ -71,7 +72,9 @@ class IdentityMaster with _$IdentityMaster { } extension IdentityMasterExtension on IdentityMaster { - KeyPair identityWriter(SecretKey secret) => KeyPair(key: identityPublicKey, secret: secret); + KeyPair identityWriter(SecretKey secret) => + KeyPair(key: identityPublicKey, secret: secret); - KeyPair masterWriter(SecretKey secret) => KeyPair(key: masterPublicKey, secret: secret); + KeyPair masterWriter(SecretKey secret) => + KeyPair(key: masterPublicKey, secret: secret); } diff --git a/lib/entities/local_account.dart b/lib/entities/local_account.dart index 782c75b..51b9456 100644 --- a/lib/entities/local_account.dart +++ b/lib/entities/local_account.dart @@ -19,9 +19,10 @@ enum EncryptionKeyType { pin, password; - String toJson() => name.toPascalCase(); factory EncryptionKeyType.fromJson(dynamic j) => EncryptionKeyType.values.byName((j as String).toCamelCase()); + + String toJson() => name.toPascalCase(); } // Local Accounts are stored in a table locally and not backed by a DHT key diff --git a/lib/entities/preferences.dart b/lib/entities/preferences.dart index 3d61cd5..550cbda 100644 --- a/lib/entities/preferences.dart +++ b/lib/entities/preferences.dart @@ -11,9 +11,10 @@ enum DarkModePreference { light, dark; - String toJson() => name.toPascalCase(); factory DarkModePreference.fromJson(dynamic j) => DarkModePreference.values.byName((j as String).toCamelCase()); + + String toJson() => name.toPascalCase(); } // Lock preference changes how frequently the messenger locks its @@ -61,18 +62,18 @@ enum ColorPreference { violet, yellow; - String toJson() => name.toPascalCase(); factory ColorPreference.fromJson(dynamic j) => ColorPreference.values.byName((j as String).toCamelCase()); + String toJson() => name.toPascalCase(); } // Theme supports multiple translations enum LanguagePreference { englishUS; - String toJson() => name.toPascalCase(); factory LanguagePreference.fromJson(dynamic j) => LanguagePreference.values.byName((j as String).toCamelCase()); + String toJson() => name.toPascalCase(); } // Preferences are stored in a table locally and globally affect all diff --git a/lib/entities/proto.dart b/lib/entities/proto.dart index 2ba1051..bae4032 100644 --- a/lib/entities/proto.dart +++ b/lib/entities/proto.dart @@ -11,15 +11,15 @@ export 'proto/veilidchat.pb.dart'; extension CryptoKeyProto on CryptoKey { proto.CryptoKey toProto() { final b = decode(); - final out = proto.CryptoKey(); - out.u0 = b[0]; - out.u1 = b[1]; - out.u2 = b[2]; - out.u3 = b[3]; - out.u4 = b[4]; - out.u5 = b[5]; - out.u6 = b[6]; - out.u7 = b[7]; + final out = proto.CryptoKey() + ..u0 = b[0] + ..u1 = b[1] + ..u2 = b[2] + ..u3 = b[3] + ..u4 = b[4] + ..u5 = b[5] + ..u6 = b[6] + ..u7 = b[7]; return out; } @@ -42,23 +42,23 @@ extension CryptoKeyProto on CryptoKey { extension SignatureProto on Signature { proto.Signature toProto() { final b = decode(); - final out = proto.Signature(); - out.u0 = b[0]; - out.u1 = b[1]; - out.u2 = b[2]; - out.u3 = b[3]; - out.u4 = b[4]; - out.u5 = b[5]; - out.u6 = b[6]; - out.u7 = b[7]; - out.u8 = b[8]; - out.u9 = b[9]; - out.u10 = b[10]; - out.u11 = b[11]; - out.u12 = b[12]; - out.u13 = b[13]; - out.u14 = b[14]; - out.u15 = b[15]; + final out = proto.Signature() + ..u0 = b[0] + ..u1 = b[1] + ..u2 = b[2] + ..u3 = b[3] + ..u4 = b[4] + ..u5 = b[5] + ..u6 = b[6] + ..u7 = b[7] + ..u8 = b[8] + ..u9 = b[9] + ..u10 = b[10] + ..u11 = b[11] + ..u12 = b[12] + ..u13 = b[13] + ..u14 = b[14] + ..u15 = b[15]; return out; } @@ -89,13 +89,13 @@ extension SignatureProto on Signature { extension NonceProto on Nonce { proto.Signature toProto() { final b = decode(); - final out = proto.Signature(); - out.u0 = b[0]; - out.u1 = b[1]; - out.u2 = b[2]; - out.u3 = b[3]; - out.u4 = b[4]; - out.u5 = b[5]; + final out = proto.Signature() + ..u0 = b[0] + ..u1 = b[1] + ..u2 = b[2] + ..u3 = b[3] + ..u4 = b[4] + ..u5 = b[5]; return out; } @@ -115,11 +115,12 @@ extension NonceProto on Nonce { /// extension TypedKeyProto on TypedKey { proto.TypedKey toProto() { - final out = proto.TypedKey(); - out.kind = kind; - out.value = value.toProto(); + final out = proto.TypedKey() + ..kind = kind + ..value = value.toProto(); return out; } - static TypedKey fromProto(proto.TypedKey p) => TypedKey(kind: p.kind, value: CryptoKeyProto.fromProto(p.value)); + static TypedKey fromProto(proto.TypedKey p) => + TypedKey(kind: p.kind, value: CryptoKeyProto.fromProto(p.value)); } diff --git a/lib/log/loggy.dart b/lib/log/loggy.dart index cee5443..a984cab 100644 --- a/lib/log/loggy.dart +++ b/lib/log/loggy.dart @@ -97,7 +97,8 @@ void initLoggy() { logOptions: getLogOptions(null), ); - const isTrace = String.fromEnvironment('logTrace') != ''; + // ignore: do_not_use_environment + const isTrace = String.fromEnvironment('LOG_TRACE') != ''; LogLevel logLevel; if (isTrace) { logLevel = traceLevel; diff --git a/lib/pages/login.dart b/lib/pages/login.dart index c38b35d..f52e5e5 100644 --- a/lib/pages/login.dart +++ b/lib/pages/login.dart @@ -10,11 +10,11 @@ class LoginPage extends ConsumerWidget { const LoginPage({super.key}); static const path = '/login'; - void _onReorder(WidgetRef ref, int oldIndex, int newIndex) { - final accounts = ref.read(localAccountsProvider.notifier); - accounts.reorderAccount(oldIndex, newIndex); - // xxx fix this so we can await this properly, use FutureBuilder or whatever - } + // void _onReorder(WidgetRef ref, int oldIndex, int newIndex) { + // final accounts = ref.read(localAccountsProvider.notifier); + // accounts.reorderAccount(oldIndex, newIndex); + // // xxx fix this so we can await this properly, use FutureBuilder or whatever + // } @override Widget build(BuildContext context, WidgetRef ref) { @@ -52,7 +52,8 @@ class LoginPage extends ConsumerWidget { // _onReorder(ref, oldIndex, newIndex), // children: accountList.map((account) { // return AccountBubble( - // key: ValueKey(account.identityMaster.masterRecordKey), + // key: ValueKey( + // account.identityMaster.masterRecordKey), // account: account); // }).toList(), // )), diff --git a/lib/providers/connection_state.dart b/lib/providers/connection_state.dart index 0f4bdbc..4a6b06b 100644 --- a/lib/providers/connection_state.dart +++ b/lib/providers/connection_state.dart @@ -1,4 +1,4 @@ -import 'package:riverpod/src/stream_provider.dart'; +import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../tools/tools.dart'; @@ -15,4 +15,5 @@ enum ConnectionState { ExternalStreamState globalConnectionState = ExternalStreamState(ConnectionState.detached); -AutoDisposeStreamProvider globalConnectionStateProvider = globalConnectionState.provider(); +AutoDisposeStreamProvider globalConnectionStateProvider = + globalConnectionState.provider(); diff --git a/lib/providers/local_accounts.dart b/lib/providers/local_accounts.dart index 1209373..eed417c 100644 --- a/lib/providers/local_accounts.dart +++ b/lib/providers/local_accounts.dart @@ -55,7 +55,8 @@ class LocalAccounts extends _$LocalAccounts Future newAccount( {required IdentityMaster identityMaster, required SecretKey identitySecret, - required proto.Account account, EncryptionKeyType encryptionKeyType = EncryptionKeyType.none, + required proto.Account account, + EncryptionKeyType encryptionKeyType = EncryptionKeyType.none, String encryptionKey = ''}) async { final veilid = await eventualVeilid.future; final localAccounts = state.requireValue; @@ -109,7 +110,7 @@ class LocalAccounts extends _$LocalAccounts // Update identity key to include account final newAccountRecordInfo = AccountRecordInfo( - key: accountRec.key(), owner: accountRec.ownerKeyPair()!); + key: accountRec.key, owner: accountRec.ownerKeyPair!); await identityRec.eventualUpdateJson(Identity.fromJson, (oldIdentity) async { @@ -141,7 +142,7 @@ class LocalAccounts extends _$LocalAccounts await store(updated); state = AsyncValue.data(updated); - // xxx todo: wipe messages + // TO DO: wipe messages return true; } diff --git a/lib/router/router_notifier.dart b/lib/router/router_notifier.dart index 86e22bb..1565ff2 100644 --- a/lib/router/router_notifier.dart +++ b/lib/router/router_notifier.dart @@ -24,14 +24,18 @@ class RouterNotifier extends _$RouterNotifier implements Listenable { // When this notifier's state changes, inform GoRouter ref.listenSelf((_, __) { - if (state.isLoading) return; + if (state.isLoading) { + return; + } routerListener?.call(); }); } /// Redirects when our state changes String? redirect(BuildContext context, GoRouterState state) { - if (this.state.isLoading || this.state.hasError) return null; + if (this.state.isLoading || this.state.hasError) { + return null; + } switch (state.location) { case IndexPage.path: diff --git a/lib/theming/themes/dark.dart b/lib/theming/themes/dark.dart index 592e191..f7668a0 100644 --- a/lib/theming/themes/dark.dart +++ b/lib/theming/themes/dark.dart @@ -16,4 +16,4 @@ ThemeData darkTheme = ThemeData.dark(); // late Color header = Color(0xFF8A8AD8); // late Color textBackground = Color(0xFF181820); // late Color active = Color(0xFF463BAD); - // late Color inactive = Color(0xFF2E2E3C); \ No newline at end of file + // late Color inactive = Color(0xFF2E2E3C); diff --git a/lib/tools/desktop_control.dart b/lib/tools/desktop_control.dart index 9df0f23..30a2b1f 100644 --- a/lib/tools/desktop_control.dart +++ b/lib/tools/desktop_control.dart @@ -23,25 +23,25 @@ Future setupDesktopWindow() async { } } -void enableTitleBar(bool enabled) { +Future enableTitleBar(bool enabled) async { if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) { if (enabled) { - windowManager.setTitleBarStyle(TitleBarStyle.normal); + await windowManager.setTitleBarStyle(TitleBarStyle.normal); } else { - windowManager.setTitleBarStyle(TitleBarStyle.hidden); + await windowManager.setTitleBarStyle(TitleBarStyle.hidden); } } } -void portraitOnly() { - SystemChrome.setPreferredOrientations([ +Future portraitOnly() async { + await SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); } -void landscapeOnly() { - SystemChrome.setPreferredOrientations([ +Future landscapeOnly() async { + await SystemChrome.setPreferredOrientations([ DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight, ]); diff --git a/lib/tools/external_stream_state.dart b/lib/tools/external_stream_state.dart index 50bd744..ba54b00 100644 --- a/lib/tools/external_stream_state.dart +++ b/lib/tools/external_stream_state.dart @@ -14,12 +14,13 @@ class ExternalStreamState { streamController.add(newState); } - AutoDisposeStreamProvider provider() => AutoDisposeStreamProvider((ref) async* { - if (await streamController.stream.isEmpty) { - yield currentState; - } - await for (final value in streamController.stream) { - yield value; - } - }); + AutoDisposeStreamProvider provider() => + AutoDisposeStreamProvider((ref) async* { + if (await streamController.stream.isEmpty) { + yield currentState; + } + await for (final value in streamController.stream) { + yield value; + } + }); } diff --git a/lib/tools/phono_byte.dart b/lib/tools/phono_byte.dart index 39b3dd9..977476d 100644 --- a/lib/tools/phono_byte.dart +++ b/lib/tools/phono_byte.dart @@ -275,10 +275,10 @@ Map _buildPhonoToByte() { String prettyPhonoString(String s, {int wordsPerLine = 5, int phonoPerWord = 2}) { - assert(wordsPerLine >= 1); - assert(phonoPerWord >= 1); + assert(wordsPerLine >= 1, 'Should not have zero or negative words per line'); + assert(phonoPerWord >= 1, 'Should not have zero or negative phono per word'); final cs = canonicalPhonoString(s).toUpperCase(); - var out = ''; + final out = StringBuffer(); var words = 0; var phonos = 0; for (var i = 0; i < cs.length; i += 3) { @@ -289,15 +289,15 @@ String prettyPhonoString(String s, words += 1; if (words == wordsPerLine) { words = 0; - out += '\n'; + out.write('\n'); } else { - out += ' '; + out.write(' '); } } } - out += cs.substring(i, i + 3); + out.write(cs.substring(i, i + 3)); } - return out; + return out.toString(); } String canonicalPhonoString(String s) { @@ -334,9 +334,9 @@ Uint8List decodePhono(String s) { } String encodePhono(Uint8List b) { - var out = ''; + final out = StringBuffer(); for (var i = 0; i < b.length; i++) { - out += _byteToPhono[b[i]]; + out.write(_byteToPhono[b[i]]); } - return out; + return out.toString(); } diff --git a/lib/tools/protobuf_tools.dart b/lib/tools/protobuf_tools.dart index 2de6bf1..c24302c 100644 --- a/lib/tools/protobuf_tools.dart +++ b/lib/tools/protobuf_tools.dart @@ -13,4 +13,5 @@ Future protobufUpdateBytes( Future Function(Uint8List) protobufUpdate( - T Function(List) fromBuffer, Future Function(T) update) => (oldBytes) => protobufUpdateBytes(fromBuffer, oldBytes, update); + T Function(List) fromBuffer, Future Function(T) update) => + (oldBytes) => protobufUpdateBytes(fromBuffer, oldBytes, update); diff --git a/lib/veilid_support/config.dart b/lib/veilid_support/config.dart index f8210c2..f359fcb 100644 --- a/lib/veilid_support/config.dart +++ b/lib/veilid_support/config.dart @@ -2,14 +2,17 @@ import 'package:veilid/veilid.dart'; Future getVeilidChatConfig() async { var config = await getDefaultVeilidConfig('VeilidChat'); + // ignore: do_not_use_environment if (const String.fromEnvironment('DELETE_TABLE_STORE') == '1') { config = config.copyWith(tableStore: config.tableStore.copyWith(delete: true)); } + // ignore: do_not_use_environment if (const String.fromEnvironment('DELETE_PROTECTED_STORE') == '1') { config = config.copyWith( protectedStore: config.protectedStore.copyWith(delete: true)); } + // ignore: do_not_use_environment if (const String.fromEnvironment('DELETE_BLOCK_STORE') == '1') { config = config.copyWith(blockStore: config.blockStore.copyWith(delete: true)); diff --git a/lib/veilid_support/dht_record.dart b/lib/veilid_support/dht_record.dart index e529c66..6196576 100644 --- a/lib/veilid_support/dht_record.dart +++ b/lib/veilid_support/dht_record.dart @@ -12,17 +12,16 @@ class DHTRecord { required DHTRecordDescriptor recordDescriptor, int defaultSubkey = 0, KeyPair? writer, - DHTRecordCrypto crypto = const DHTRecordCryptoPublic()}) + this.crypto = const DHTRecordCryptoPublic()}) : _dhtctx = dhtctx, _recordDescriptor = recordDescriptor, _defaultSubkey = defaultSubkey, - _writer = writer, - _crypto = crypto; + _writer = writer; final VeilidRoutingContext _dhtctx; final DHTRecordDescriptor _recordDescriptor; final int _defaultSubkey; final KeyPair? _writer; - DHTRecordCrypto _crypto; + DHTRecordCrypto crypto; static Future create(VeilidRoutingContext dhtctx, {DHTSchema schema = const DHTSchema.dflt(oCnt: 1), @@ -76,17 +75,13 @@ class DHTRecord { int subkeyOrDefault(int subkey) => (subkey == -1) ? _defaultSubkey : subkey; - TypedKey key() => _recordDescriptor.key; + TypedKey get key => _recordDescriptor.key; - PublicKey owner() => _recordDescriptor.owner; + PublicKey get owner => _recordDescriptor.owner; - KeyPair? ownerKeyPair() => _recordDescriptor.ownerKeyPair(); + KeyPair? get ownerKeyPair => _recordDescriptor.ownerKeyPair(); - KeyPair? writer() => _writer; - - void setCrypto(DHTRecordCrypto crypto) { - _crypto = crypto; - } + KeyPair? get writer => _writer; Future close() async { await _dhtctx.closeDHTRecord(_recordDescriptor.key); @@ -122,7 +117,7 @@ class DHTRecord { if (valueData == null) { return null; } - return _crypto.decrypt(valueData.data, subkey); + return crypto.decrypt(valueData.data, subkey); } Future getJson(T Function(dynamic) fromJson, @@ -136,7 +131,7 @@ class DHTRecord { Future eventualWriteBytes(Uint8List newValue, {int subkey = -1}) async { subkey = subkeyOrDefault(subkey); - newValue = await _crypto.encrypt(newValue, subkey); + newValue = await crypto.encrypt(newValue, subkey); // Get existing identity key ValueData? valueData; do { @@ -162,9 +157,9 @@ class DHTRecord { } // Update the data - final oldData = await _crypto.decrypt(valueData.data, subkey); + final oldData = await crypto.decrypt(valueData.data, subkey); final updatedData = await update(oldData); - final newData = await _crypto.encrypt(updatedData, subkey); + final newData = await crypto.encrypt(updatedData, subkey); // Set it back valueData = diff --git a/lib/veilid_support/dht_record_crypto.dart b/lib/veilid_support/dht_record_crypto.dart index 6c049d8..ce9c358 100644 --- a/lib/veilid_support/dht_record_crypto.dart +++ b/lib/veilid_support/dht_record_crypto.dart @@ -13,7 +13,6 @@ abstract class DHTRecordCrypto { //////////////////////////////////// /// Private DHT Record: Encrypted for a specific symmetric key class DHTRecordCryptoPrivate implements DHTRecordCrypto { - DHTRecordCryptoPrivate._( VeilidCryptoSystem cryptoSystem, SharedSecret secretKey) : _cryptoSystem = cryptoSystem, @@ -41,9 +40,9 @@ class DHTRecordCryptoPrivate implements DHTRecordCrypto { // generate nonce final nonce = await _cryptoSystem.randomNonce(); // crypt and append nonce - final b = BytesBuilder(); - b.add(await _cryptoSystem.cryptNoAuth(data, nonce, _secretKey)); - b.add(nonce.decode()); + final b = BytesBuilder() + ..add(await _cryptoSystem.cryptNoAuth(data, nonce, _secretKey)) + ..add(nonce.decode()); return b.toBytes(); } diff --git a/lib/veilid_support/identity_master.dart b/lib/veilid_support/identity_master.dart index afa74db..8c64aa9 100644 --- a/lib/veilid_support/identity_master.dart +++ b/lib/veilid_support/identity_master.dart @@ -40,19 +40,20 @@ Future newIdentityMaster() async { // Identity record is private return (await DHTRecord.create(dhtctx)).deleteScope((identityRec) async { // Make IdentityMaster - final masterRecordKey = masterRec.key(); - final masterOwner = masterRec.ownerKeyPair()!; - final masterSigBuf = BytesBuilder(); - masterSigBuf.add(masterRecordKey.decode()); - masterSigBuf.add(masterOwner.key.decode()); + final masterRecordKey = masterRec.key; + final masterOwner = masterRec.ownerKeyPair!; + final masterSigBuf = BytesBuilder() + ..add(masterRecordKey.decode()) + ..add(masterOwner.key.decode()); - final identityRecordKey = identityRec.key(); - final identityOwner = identityRec.ownerKeyPair()!; - final identitySigBuf = BytesBuilder(); - identitySigBuf.add(identityRecordKey.decode()); - identitySigBuf.add(identityOwner.key.decode()); + final identityRecordKey = identityRec.key; + final identityOwner = identityRec.ownerKeyPair!; + final identitySigBuf = BytesBuilder() + ..add(identityRecordKey.decode()) + ..add(identityOwner.key.decode()); - assert(masterRecordKey.kind == identityRecordKey.kind); + assert(masterRecordKey.kind == identityRecordKey.kind, + 'new master and identity should have same cryptosystem'); final crypto = await veilid.getCryptoSystem(masterRecordKey.kind); final identitySignature = diff --git a/lib/veilid_support/veilid_init.dart b/lib/veilid_support/veilid_init.dart index 8258844..70da2f0 100644 --- a/lib/veilid_support/veilid_init.dart +++ b/lib/veilid_support/veilid_init.dart @@ -75,4 +75,5 @@ Future initializeVeilid() async { // Expose the Veilid instance as a FutureProvider @riverpod -FutureOr veilidInstance(VeilidInstanceRef ref) async => await eventualVeilid.future; +FutureOr veilidInstance(VeilidInstanceRef ref) async => + await eventualVeilid.future; diff --git a/lib/veilid_support/veilid_log.dart b/lib/veilid_support/veilid_log.dart index b086e89..ca0bdee 100644 --- a/lib/veilid_support/veilid_log.dart +++ b/lib/veilid_support/veilid_log.dart @@ -39,8 +39,7 @@ Future processLog(VeilidLog log) async { Object? error; final backtrace = log.backtrace; if (backtrace != null) { - stackTrace = - StackTrace.fromString('$backtrace\n${StackTrace.current}'); + stackTrace = StackTrace.fromString('$backtrace\n${StackTrace.current}'); error = 'embedded stack trace for ${log.logLevel} ${log.message}'; } @@ -64,7 +63,8 @@ Future processLog(VeilidLog log) async { } void initVeilidLog() { - const isTrace = String.fromEnvironment('logTrace') != ''; + // ignore: do_not_use_environment + const isTrace = String.fromEnvironment('LOG_TRACE') != ''; LogLevel logLevel; if (isTrace) { logLevel = traceLevel; diff --git a/pubspec.yaml b/pubspec.yaml index d563806..d2373c5 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -8,59 +8,59 @@ environment: flutter: ">=3.10.0" dependencies: + animated_theme_switcher: ^2.0.7 + ansicolor: ^2.0.1 + awesome_extensions: ^2.0.9 + badges: ^3.1.1 + blurry_modal_progress_hud: ^1.1.0 + change_case: ^1.1.0 + charcode: ^1.3.1 + circular_profile_avatar: ^2.0.5 + cupertino_icons: ^1.0.2 + equatable: ^2.0.5 + fast_immutable_collections: ^9.1.5 + fixnum: ^1.1.0 flutter: sdk: flutter + flutter_form_builder: ^9.1.0 + flutter_hooks: ^0.18.0 flutter_localizations: sdk: flutter - flutter_hooks: ^0.18.0 - hooks_riverpod: ^2.1.3 flutter_riverpod: ^2.1.3 - riverpod_annotation: ^2.1.1 - cupertino_icons: ^1.0.2 - ansicolor: ^2.0.1 + flutter_spinkit: ^5.2.0 + flutter_svg: ^2.0.7 + flutter_translate: ^4.0.4 + form_builder_validators: ^9.0.0 + freezed_annotation: ^2.2.0 + go_router: ^9.0.0 + hooks_riverpod: ^2.1.3 + intl: ^0.18.0 + json_annotation: ^4.8.1 loggy: ^2.0.3 - uuid: ^3.0.7 path: ^1.8.2 path_provider: ^2.0.11 + protobuf: ^3.0.0 + quickalert: ^1.0.1 + radix_colors: ^1.0.4 + reorderable_grid: ^1.0.7 + riverpod_annotation: ^2.1.1 + shared_preferences: ^2.0.15 + uuid: ^3.0.7 veilid: # veilid: ^0.0.1 path: ../veilid/veilid-flutter - animated_theme_switcher: ^2.0.7 - shared_preferences: ^2.0.15 - go_router: ^9.0.0 - fast_immutable_collections: ^9.1.5 - freezed_annotation: ^2.2.0 - json_annotation: ^4.8.1 - equatable: ^2.0.5 - change_case: ^1.1.0 - radix_colors: ^1.0.4 - flutter_translate: ^4.0.4 - intl: ^0.18.0 - fixnum: ^1.1.0 - protobuf: ^3.0.0 - charcode: ^1.3.1 window_manager: ^0.3.5 - flutter_svg: ^2.0.7 - reorderable_grid: ^1.0.7 - circular_profile_avatar: ^2.0.5 - badges: ^3.1.1 - awesome_extensions: ^2.0.9 - flutter_form_builder: ^9.1.0 - form_builder_validators: ^9.0.0 - blurry_modal_progress_hud: ^1.1.0 - flutter_spinkit: ^5.2.0 - quickalert: ^1.0.1 dev_dependencies: + build_runner: ^2.4.6 + flutter_launcher_icons: "^0.13.1" flutter_test: sdk: flutter - build_runner: ^2.4.6 freezed: ^2.3.5 json_serializable: ^6.7.1 - riverpod_generator: ^2.2.3 - flutter_launcher_icons: "^0.13.1" lint_hard: ^4.0.0 - + riverpod_generator: ^2.2.3 + flutter_launcher_icons: image_path: "assets/launcher/icon.png" android: true