From cb2f0d00a6e9d61bc1cbf8b4fe4cf3a820a295bd Mon Sep 17 00:00:00 2001 From: otsmr Date: Thu, 16 Oct 2025 14:54:21 +0200 Subject: [PATCH] fixing issue and starting with developer settings --- CHANGELOG.md | 4 + ios/Podfile | 2 +- ios/Podfile.lock | 149 +++++++++--------- ios/Runner.xcodeproj/project.pbxproj | 6 +- lib/app.dart | 4 +- .../daos/message_retransmissions.dao.dart | 6 + lib/src/database/daos/signal_dao.dart | 8 +- lib/src/model/json/userdata.dart | 3 + lib/src/model/json/userdata.g.dart | 2 + lib/src/services/api/server_messages.dart | 2 +- .../zoom_selector.dart | 5 +- .../camera_preview_controller_view.dart | 4 +- lib/src/views/camera/camera_send_to_view.dart | 11 +- .../image_editor/layers/filter_layer.dart | 6 +- .../layers/filters/location_filter.dart | 5 +- .../image_editor/modules/all_emojis.dart | 6 +- .../views/camera/share_image_editor_view.dart | 20 +-- lib/src/views/camera/share_image_view.dart | 8 +- lib/src/views/chats/add_new_user.view.dart | 4 +- lib/src/views/chats/chat_list.view.dart | 6 +- .../backup_notice.card.dart | 6 +- lib/src/views/chats/chat_messages.view.dart | 10 +- .../chat_media_entry.dart | 6 +- .../in_chat_media_viewer.dart | 11 +- .../response_container.dart | 5 +- lib/src/views/chats/media_viewer.view.dart | 20 +-- lib/src/views/chats/start_new_chat.view.dart | 4 +- .../components/video_player_wrapper.dart | 23 +-- .../views/contact/contact_verify.view.dart | 8 +- lib/src/views/home.view.dart | 13 +- lib/src/views/memories/memories.view.dart | 8 +- lib/src/views/settings/account.view.dart | 4 +- lib/src/views/settings/appearance.view.dart | 6 +- .../views/settings/backup/backup.view.dart | 6 +- .../backup/twonly_safe_server.view.dart | 5 +- .../settings/chat/chat_reactions.view.dart | 6 +- .../views/settings/data_and_storage.view.dart | 5 +- .../settings/developer/developer.view.dart | 72 +++++++++ .../developer/retransmission_data.view.dart | 72 +++++++++ .../views/settings/help/changelog.view.dart | 6 +- lib/src/views/settings/help/credits.view.dart | 6 +- lib/src/views/settings/help/faq.view.dart | 5 +- lib/src/views/settings/help/help.view.dart | 11 +- .../settings/privacy_view_block.users.dart | 7 +- .../views/settings/profile/profile.view.dart | 6 +- .../views/settings/settings_main.view.dart | 22 ++- .../subscription/additional_users.view.dart | 9 +- .../manage_subscription.view.dart | 6 +- .../subscription/select_payment.view.dart | 6 +- .../subscription/subscription.view.dart | 6 +- .../settings/subscription/voucher.view.dart | 6 +- 51 files changed, 433 insertions(+), 214 deletions(-) create mode 100644 lib/src/views/settings/developer/developer.view.dart create mode 100644 lib/src/views/settings/developer/retransmission_data.view.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index cfe3681..317bf03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 0.0.61 + +- Fixing message decryption error +- Dependency and Flutter upgrade ## 0.0.60 diff --git a/ios/Podfile b/ios/Podfile index 88b581a..856e804 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -platform :ios, '14.0' +platform :ios, '15.0' use_frameworks! # CocoaPods analytics sends network stats synchronously affecting flutter build latency. diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 87dd41b..42f70db 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -9,56 +9,56 @@ PODS: - Flutter - device_info_plus (0.0.1): - Flutter - - Firebase (11.15.0): - - Firebase/Core (= 11.15.0) - - Firebase/Core (11.15.0): + - Firebase (12.4.0): + - Firebase/Core (= 12.4.0) + - Firebase/Core (12.4.0): - Firebase/CoreOnly - - FirebaseAnalytics (~> 11.15.0) - - Firebase/CoreOnly (11.15.0): - - FirebaseCore (~> 11.15.0) - - Firebase/Messaging (11.15.0): + - FirebaseAnalytics (~> 12.4.0) + - Firebase/CoreOnly (12.4.0): + - FirebaseCore (~> 12.4.0) + - Firebase/Messaging (12.4.0): - Firebase/CoreOnly - - FirebaseMessaging (~> 11.15.0) - - firebase_core (3.15.2): - - Firebase/CoreOnly (= 11.15.0) + - FirebaseMessaging (~> 12.4.0) + - firebase_core (4.2.0): + - Firebase/CoreOnly (= 12.4.0) - Flutter - - firebase_messaging (15.2.10): - - Firebase/Messaging (= 11.15.0) + - firebase_messaging (16.0.3): + - Firebase/Messaging (= 12.4.0) - firebase_core - Flutter - - FirebaseAnalytics (11.15.0): - - FirebaseAnalytics/Default (= 11.15.0) - - FirebaseCore (~> 11.15.0) - - FirebaseInstallations (~> 11.0) + - FirebaseAnalytics (12.4.0): + - FirebaseAnalytics/Default (= 12.4.0) + - FirebaseCore (~> 12.4.0) + - FirebaseInstallations (~> 12.4.0) - GoogleUtilities/AppDelegateSwizzler (~> 8.1) - GoogleUtilities/MethodSwizzler (~> 8.1) - GoogleUtilities/Network (~> 8.1) - "GoogleUtilities/NSData+zlib (~> 8.1)" - nanopb (~> 3.30910.0) - - FirebaseAnalytics/Default (11.15.0): - - FirebaseCore (~> 11.15.0) - - FirebaseInstallations (~> 11.0) - - GoogleAppMeasurement/Default (= 11.15.0) + - FirebaseAnalytics/Default (12.4.0): + - FirebaseCore (~> 12.4.0) + - FirebaseInstallations (~> 12.4.0) + - GoogleAppMeasurement/Default (= 12.4.0) - GoogleUtilities/AppDelegateSwizzler (~> 8.1) - GoogleUtilities/MethodSwizzler (~> 8.1) - GoogleUtilities/Network (~> 8.1) - "GoogleUtilities/NSData+zlib (~> 8.1)" - nanopb (~> 3.30910.0) - - FirebaseCore (11.15.0): - - FirebaseCoreInternal (~> 11.15.0) + - FirebaseCore (12.4.0): + - FirebaseCoreInternal (~> 12.4.0) - GoogleUtilities/Environment (~> 8.1) - GoogleUtilities/Logger (~> 8.1) - - FirebaseCoreInternal (11.15.0): + - FirebaseCoreInternal (12.4.0): - "GoogleUtilities/NSData+zlib (~> 8.1)" - - FirebaseInstallations (11.15.0): - - FirebaseCore (~> 11.15.0) + - FirebaseInstallations (12.4.0): + - FirebaseCore (~> 12.4.0) - GoogleUtilities/Environment (~> 8.1) - GoogleUtilities/UserDefaults (~> 8.1) - PromisesObjC (~> 2.4) - - FirebaseMessaging (11.15.0): - - FirebaseCore (~> 11.15.0) - - FirebaseInstallations (~> 11.0) - - GoogleDataTransport (~> 10.0) + - FirebaseMessaging (12.4.0): + - FirebaseCore (~> 12.4.0) + - FirebaseInstallations (~> 12.4.0) + - GoogleDataTransport (~> 10.1) - GoogleUtilities/AppDelegateSwizzler (~> 8.1) - GoogleUtilities/Environment (~> 8.1) - GoogleUtilities/Reachability (~> 8.1) @@ -70,7 +70,7 @@ PODS: - Mantle - SDWebImage - SDWebImageWebPCoder - - flutter_keyboard_visibility (0.0.1): + - flutter_keyboard_visibility_temp_fork (0.0.1): - Flutter - flutter_local_notifications (0.0.1): - Flutter @@ -82,27 +82,28 @@ PODS: - gal (1.0.0): - Flutter - FlutterMacOS - - GoogleAdsOnDeviceConversion (2.1.0): + - GoogleAdsOnDeviceConversion (3.1.0): + - GoogleUtilities/Environment (~> 8.1) - GoogleUtilities/Logger (~> 8.1) - GoogleUtilities/Network (~> 8.1) - nanopb (~> 3.30910.0) - - GoogleAppMeasurement/Core (11.15.0): + - GoogleAppMeasurement/Core (12.4.0): - GoogleUtilities/AppDelegateSwizzler (~> 8.1) - GoogleUtilities/MethodSwizzler (~> 8.1) - GoogleUtilities/Network (~> 8.1) - "GoogleUtilities/NSData+zlib (~> 8.1)" - nanopb (~> 3.30910.0) - - GoogleAppMeasurement/Default (11.15.0): - - GoogleAdsOnDeviceConversion (= 2.1.0) - - GoogleAppMeasurement/Core (= 11.15.0) - - GoogleAppMeasurement/IdentitySupport (= 11.15.0) + - GoogleAppMeasurement/Default (12.4.0): + - GoogleAdsOnDeviceConversion (~> 3.1.0) + - GoogleAppMeasurement/Core (= 12.4.0) + - GoogleAppMeasurement/IdentitySupport (= 12.4.0) - GoogleUtilities/AppDelegateSwizzler (~> 8.1) - GoogleUtilities/MethodSwizzler (~> 8.1) - GoogleUtilities/Network (~> 8.1) - "GoogleUtilities/NSData+zlib (~> 8.1)" - nanopb (~> 3.30910.0) - - GoogleAppMeasurement/IdentitySupport (11.15.0): - - GoogleAppMeasurement/Core (= 11.15.0) + - GoogleAppMeasurement/IdentitySupport (12.4.0): + - GoogleAppMeasurement/Core (= 12.4.0) - GoogleUtilities/AppDelegateSwizzler (~> 8.1) - GoogleUtilities/MethodSwizzler (~> 8.1) - GoogleUtilities/Network (~> 8.1) @@ -190,9 +191,9 @@ PODS: - restart_app (0.0.1): - Flutter - ScreenProtectorKit (1.3.1) - - SDWebImage (5.21.1): - - SDWebImage/Core (= 5.21.1) - - SDWebImage/Core (5.21.1) + - SDWebImage (5.21.3): + - SDWebImage/Core (= 5.21.3) + - SDWebImage/Core (5.21.3) - SDWebImageWebPCoder (0.14.6): - libwebp (~> 1.0) - SDWebImage/Core (~> 5.17) @@ -204,32 +205,32 @@ PODS: - sqflite_darwin (0.0.4): - Flutter - FlutterMacOS - - sqlite3 (3.50.3): - - sqlite3/common (= 3.50.3) - - sqlite3/common (3.50.3) - - sqlite3/dbstatvtab (3.50.3): + - sqlite3 (3.50.4): + - sqlite3/common (= 3.50.4) + - sqlite3/common (3.50.4) + - sqlite3/dbstatvtab (3.50.4): - sqlite3/common - - sqlite3/fts5 (3.50.3): + - sqlite3/fts5 (3.50.4): - sqlite3/common - - sqlite3/math (3.50.3): + - sqlite3/math (3.50.4): - sqlite3/common - - sqlite3/perf-threadsafe (3.50.3): + - sqlite3/perf-threadsafe (3.50.4): - sqlite3/common - - sqlite3/rtree (3.50.3): + - sqlite3/rtree (3.50.4): - sqlite3/common - - sqlite3/session (3.50.3): + - sqlite3/session (3.50.4): - sqlite3/common - sqlite3_flutter_libs (0.0.1): - Flutter - FlutterMacOS - - sqlite3 (~> 3.50.3) + - sqlite3 (~> 3.50.4) - sqlite3/dbstatvtab - sqlite3/fts5 - sqlite3/math - sqlite3/perf-threadsafe - sqlite3/rtree - sqlite3/session - - SwiftProtobuf (1.30.0) + - SwiftProtobuf (1.32.0) - url_launcher_ios (0.0.1): - Flutter - video_compress (0.3.0): @@ -255,7 +256,7 @@ DEPENDENCIES: - FirebaseMessaging - Flutter (from `Flutter`) - flutter_image_compress_common (from `.symlinks/plugins/flutter_image_compress_common/ios`) - - flutter_keyboard_visibility (from `.symlinks/plugins/flutter_keyboard_visibility/ios`) + - flutter_keyboard_visibility_temp_fork (from `.symlinks/plugins/flutter_keyboard_visibility_temp_fork/ios`) - flutter_local_notifications (from `.symlinks/plugins/flutter_local_notifications/ios`) - flutter_secure_storage_darwin (from `.symlinks/plugins/flutter_secure_storage_darwin/darwin`) - flutter_zxing (from `.symlinks/plugins/flutter_zxing/ios`) @@ -319,8 +320,8 @@ EXTERNAL SOURCES: :path: Flutter flutter_image_compress_common: :path: ".symlinks/plugins/flutter_image_compress_common/ios" - flutter_keyboard_visibility: - :path: ".symlinks/plugins/flutter_keyboard_visibility/ios" + flutter_keyboard_visibility_temp_fork: + :path: ".symlinks/plugins/flutter_keyboard_visibility_temp_fork/ios" flutter_local_notifications: :path: ".symlinks/plugins/flutter_local_notifications/ios" flutter_secure_storage_darwin: @@ -362,32 +363,32 @@ EXTERNAL SOURCES: SPEC CHECKSUMS: background_downloader: 50e91d979067b82081aba359d7d916b3ba5fadad - camera_avfoundation: be3be85408cd4126f250386828e9b1dfa40ab436 + camera_avfoundation: 5675ca25298b6f81fa0a325188e7df62cc217741 connectivity_plus: cb623214f4e1f6ef8fe7403d580fdad517d2f7dd cryptography_flutter_plus: 44f4e9e4079395fcbb3e7809c0ac2c6ae2d9576f device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe - Firebase: d99ac19b909cd2c548339c2241ecd0d1599ab02e - firebase_core: 995454a784ff288be5689b796deb9e9fa3601818 - firebase_messaging: f4a41dd102ac18b840eba3f39d67e77922d3f707 - FirebaseAnalytics: 6433dfd311ba78084fc93bdfc145e8cb75740eae - FirebaseCore: efb3893e5b94f32b86e331e3bd6dadf18b66568e - FirebaseCoreInternal: 9afa45b1159304c963da48addb78275ef701c6b4 - FirebaseInstallations: 317270fec08a5d418fdbc8429282238cab3ac843 - FirebaseMessaging: 3b26e2cee503815e01c3701236b020aa9b576f09 - Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 + Firebase: f07b15ae5a6ec0f93713e30b923d9970d144af3e + firebase_core: 744984dbbed8b3036abf34f0b98d80f130a7e464 + firebase_messaging: 82c70650c426a0a14873e1acdb9ec2b443c4e8b4 + FirebaseAnalytics: 0fc2b20091f0ddd21bf73397cf8f0eb5346dc24f + FirebaseCore: bb595f3114953664e3c1dc032f008a244147cfd3 + FirebaseCoreInternal: d7f5a043c2cd01a08103ab586587c1468047bca6 + FirebaseInstallations: ae9f4902cb5bf1d0c5eaa31ec1f4e5495a0714e2 + FirebaseMessaging: d33971b7bb252745ea6cd31ab190d1a1df4b8ed5 + Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 flutter_image_compress_common: 1697a328fd72bfb335507c6bca1a65fa5ad87df1 - flutter_keyboard_visibility: 4625131e43015dbbe759d9b20daaf77e0e3f6619 + flutter_keyboard_visibility_temp_fork: 95b2d534bacf6ac62e7fcbe5c2a9e2c2a17ce06f flutter_local_notifications: a5a732f069baa862e728d839dd2ebb904737effb flutter_secure_storage_darwin: ce237a8775b39723566dc72571190a3769d70468 flutter_zxing: e8bcc43bd3056c70c271b732ed94e7a16fd62f93 gal: baecd024ebfd13c441269ca7404792a7152fde89 - GoogleAdsOnDeviceConversion: 2be6297a4f048459e0ae17fad9bfd2844e10cf64 - GoogleAppMeasurement: 700dce7541804bec33db590a5c496b663fbe2539 + GoogleAdsOnDeviceConversion: e03a386840803ea7eef3fd22a061930142c039c1 + GoogleAppMeasurement: 1e718274b7e015cefd846ac1fcf7820c70dc017d GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1 image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8 - local_auth_darwin: d2e8c53ef0c4f43c646462e3415432c4dab3ae19 + local_auth_darwin: c3ee6cce0a8d56be34c8ccb66ba31f7f180aaebb Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 no_screenshot: 6d183496405a3ab709a67a54e5cd0f639e94729e @@ -397,19 +398,19 @@ SPEC CHECKSUMS: PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 restart_app: 9cda5378aacc5000e3f66ee76a9201534e7d3ecf ScreenProtectorKit: 83a6281b02c7a5902ee6eac4f5045f674e902ae4 - SDWebImage: f29024626962457f3470184232766516dee8dfea + SDWebImage: 16309af6d214ba3f77a7c6f6fdda888cb313a50a SDWebImageWebPCoder: e38c0a70396191361d60c092933e22c20d5b1380 share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7 sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0 - sqlite3: 83105acd294c9137c026e2da1931c30b4588ab81 - sqlite3_flutter_libs: 616267f2fca40e9c6af8c5d82324e05667040b6e - SwiftProtobuf: 3697407f0d5b23bedeba9c2eaaf3ec6fdff69349 + sqlite3: 73513155ec6979715d3904ef53a8d68892d4032b + sqlite3_flutter_libs: 83f8e9f5b6554077f1d93119fe20ebaa5f3a9ef1 + SwiftProtobuf: 81e341191afbddd64aa031bd12862dccfab2f639 url_launcher_ios: 694010445543906933d732453a59da0a173ae33d video_compress: f2133a07762889d67f0711ac831faa26f956980e video_player_avfoundation: 2cef49524dd1f16c5300b9cd6efd9611ce03639b video_thumbnail: b637e0ad5f588ca9945f6e2c927f73a69a661140 -PODFILE CHECKSUM: a01f0821a361ca6708e29b1299e8becf492a8a71 +PODFILE CHECKSUM: 47470fbd5b59affa461eaf943ac57acce81e0ee8 COCOAPODS: 1.16.2 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index ed10d98..3b02435 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -609,7 +609,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -752,7 +752,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -805,7 +805,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 12.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; diff --git a/lib/app.dart b/lib/app.dart index 6c9d781..36c9c2d 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -23,7 +23,7 @@ class _AppState extends State with WidgetsBindingObserver { bool wasPaused = false; @override - Future initState() async { + void initState() { super.initState(); globalIsAppInBackground = false; WidgetsBinding.instance.addObserver(this); @@ -39,7 +39,7 @@ class _AppState extends State with WidgetsBindingObserver { await context.read().updatePlan(planId); }; - await initAsync(); + unawaited(initAsync()); } Future setUserPlan() async { diff --git a/lib/src/database/daos/message_retransmissions.dao.dart b/lib/src/database/daos/message_retransmissions.dao.dart index 6c45077..b4a7934 100644 --- a/lib/src/database/daos/message_retransmissions.dao.dart +++ b/lib/src/database/daos/message_retransmissions.dao.dart @@ -63,6 +63,12 @@ class MessageRetransmissionDao extends DatabaseAccessor ..where((t) => t.retransmissionId.equals(retransmissionId)); } + Stream> watchAllMessages() { + return (select(messageRetransmissions) + ..orderBy([(t) => OrderingTerm.asc(t.retransmissionId)])) + .watch(); + } + Future updateRetransmission( int retransmissionId, MessageRetransmissionsCompanion updatedValues, diff --git a/lib/src/database/daos/signal_dao.dart b/lib/src/database/daos/signal_dao.dart index f74796c..de94934 100644 --- a/lib/src/database/daos/signal_dao.dart +++ b/lib/src/database/daos/signal_dao.dart @@ -93,22 +93,22 @@ class SignalDao extends DatabaseAccessor with _$SignalDaoMixin { } Future purgeOutDatedPreKeys() async { - // other pre keys are valid 25 days + // other pre keys are valid 100 days await (delete(signalContactSignedPreKeys) ..where( (t) => (t.createdAt.isSmallerThanValue( DateTime.now().subtract( - const Duration(days: 25), + const Duration(days: 100), ), )), )) .go(); - // own pre keys are valid for 40 days + // own pre keys are valid for 180 days await (delete(twonlyDB.signalPreKeyStores) ..where( (t) => (t.createdAt.isSmallerThanValue( DateTime.now().subtract( - const Duration(days: 40), + const Duration(days: 365), ), )), )) diff --git a/lib/src/model/json/userdata.dart b/lib/src/model/json/userdata.dart index d28cb58..987ff9f 100644 --- a/lib/src/model/json/userdata.dart +++ b/lib/src/model/json/userdata.dart @@ -29,6 +29,9 @@ class UserData { @JsonKey(defaultValue: 0) int avatarCounter = 0; + @JsonKey(defaultValue: false) + bool isDeveloper = false; + @JsonKey(defaultValue: 0) int deviceId = 0; diff --git a/lib/src/model/json/userdata.g.dart b/lib/src/model/json/userdata.g.dart index 1e4004d..a73b3ec 100644 --- a/lib/src/model/json/userdata.g.dart +++ b/lib/src/model/json/userdata.g.dart @@ -16,6 +16,7 @@ UserData _$UserDataFromJson(Map json) => UserData( ..avatarSvg = json['avatarSvg'] as String? ..avatarJson = json['avatarJson'] as String? ..avatarCounter = (json['avatarCounter'] as num?)?.toInt() ?? 0 + ..isDeveloper = json['isDeveloper'] as bool? ?? false ..deviceId = (json['deviceId'] as num?)?.toInt() ?? 0 ..lastImageSend = json['lastImageSend'] == null ? null @@ -79,6 +80,7 @@ Map _$UserDataToJson(UserData instance) => { 'avatarSvg': instance.avatarSvg, 'avatarJson': instance.avatarJson, 'avatarCounter': instance.avatarCounter, + 'isDeveloper': instance.isDeveloper, 'deviceId': instance.deviceId, 'subscriptionPlan': instance.subscriptionPlan, 'lastImageSend': instance.lastImageSend?.toIso8601String(), diff --git a/lib/src/services/api/server_messages.dart b/lib/src/services/api/server_messages.dart index f3515a3..491d94f 100644 --- a/lib/src/services/api/server_messages.dart +++ b/lib/src/services/api/server_messages.dart @@ -131,7 +131,7 @@ Future handleNewMessage(int fromUserId, Uint8List body) async { } case MessageKind.signalDecryptError: Log.error( - 'Got signal decrypt error from other user! Sending all non ACK messages again.', + 'Got signal decrypt error from other user! Sending it again.', ); final content = message.content; diff --git a/lib/src/views/camera/camera_preview_components/zoom_selector.dart b/lib/src/views/camera/camera_preview_components/zoom_selector.dart index 6b4061f..499a335 100644 --- a/lib/src/views/camera/camera_preview_components/zoom_selector.dart +++ b/lib/src/views/camera/camera_preview_components/zoom_selector.dart @@ -1,5 +1,6 @@ // ignore_for_file: avoid_dynamic_calls +import 'dart:async'; import 'dart:io'; import 'dart:math'; @@ -43,9 +44,9 @@ class _CameraZoomButtonsState extends State { bool _isDisposed = false; @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { diff --git a/lib/src/views/camera/camera_preview_controller_view.dart b/lib/src/views/camera/camera_preview_controller_view.dart index c57c392..cab049a 100644 --- a/lib/src/views/camera/camera_preview_controller_view.dart +++ b/lib/src/views/camera/camera_preview_controller_view.dart @@ -173,9 +173,9 @@ class _CameraPreviewViewState extends State { final GlobalKey navigatorKey = GlobalKey(); @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { diff --git a/lib/src/views/camera/camera_send_to_view.dart b/lib/src/views/camera/camera_send_to_view.dart index 7a03a43..d556b74 100644 --- a/lib/src/views/camera/camera_send_to_view.dart +++ b/lib/src/views/camera/camera_send_to_view.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:camera/camera.dart'; import 'package:flutter/material.dart'; import 'package:screenshot/screenshot.dart'; @@ -18,14 +20,15 @@ class CameraSendToViewState extends State { SelectedCameraDetails selectedCameraDetails = SelectedCameraDetails(); @override - Future initState() async { + void initState() { super.initState(); - await selectCamera(0, true, false); + unawaited(selectCamera(0, true, false)); } @override - Future dispose() async { - await cameraController?.dispose(); + void dispose() { + // ignore: discarded_futures + cameraController?.dispose(); cameraController = null; selectedCameraDetails = SelectedCameraDetails(); super.dispose(); diff --git a/lib/src/views/camera/image_editor/layers/filter_layer.dart b/lib/src/views/camera/image_editor/layers/filter_layer.dart index 32ce9b1..c0179d0 100644 --- a/lib/src/views/camera/image_editor/layers/filter_layer.dart +++ b/lib/src/views/camera/image_editor/layers/filter_layer.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:twonly/src/views/camera/image_editor/data/layer.dart'; @@ -78,12 +80,12 @@ class _FilterLayerState extends State { ]; @override - Future initState() async { + void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { pageController.jumpToPage(1); }); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { diff --git a/lib/src/views/camera/image_editor/layers/filters/location_filter.dart b/lib/src/views/camera/image_editor/layers/filters/location_filter.dart index 94cedf1..5b3ae64 100644 --- a/lib/src/views/camera/image_editor/layers/filters/location_filter.dart +++ b/lib/src/views/camera/image_editor/layers/filters/location_filter.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:convert'; import 'dart:io'; @@ -24,9 +25,9 @@ class _LocationFilterState extends State { Response_Location? location; @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { diff --git a/lib/src/views/camera/image_editor/modules/all_emojis.dart b/lib/src/views/camera/image_editor/modules/all_emojis.dart index 90e1e5c..18775ea 100755 --- a/lib/src/views/camera/image_editor/modules/all_emojis.dart +++ b/lib/src/views/camera/image_editor/modules/all_emojis.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/views/camera/image_editor/data/data.dart'; @@ -14,9 +16,9 @@ class _EmojisState extends State { List lastUsed = emojis; @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { diff --git a/lib/src/views/camera/share_image_editor_view.dart b/lib/src/views/camera/share_image_editor_view.dart index e366a1c..d00aa0c 100644 --- a/lib/src/views/camera/share_image_editor_view.dart +++ b/lib/src/views/camera/share_image_editor_view.dart @@ -72,27 +72,28 @@ class _ShareImageEditorView extends State { Future? videoUploadHandler; @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); - await initMediaFileUpload(); + unawaited(initAsync()); + unawaited(initMediaFileUpload()); layers.add(FilterLayerData()); if (widget.sendTo != null) { selectedUserIds.add(widget.sendTo!.userId); } if (widget.imageBytes != null) { - await loadImage(widget.imageBytes!); + unawaited(loadImage(widget.imageBytes!)); } else if (widget.videoFilePath != null) { setState(() { sendingOrLoadingImage = false; loadingImage = false; }); videoController = VideoPlayerController.file(widget.videoFilePath!); - await videoController?.setLooping(true); - await videoController?.initialize().then((_) async { + // ignore: discarded_futures + videoController?.setLooping(true); + videoController?.initialize().then((_) async { await videoController!.play(); setState(() {}); - // ignore: invalid_return_type_for_catch_error, argument_type_not_assignable_to_error_handler + // ignore: invalid_return_type_for_catch_error, argument_type_not_assignable_to_error_handler, discarded_futures }).catchError(Log.error); } } @@ -121,10 +122,11 @@ class _ShareImageEditorView extends State { } @override - Future dispose() async { + void dispose() { isDisposed = true; layers.clear(); - await videoController?.dispose(); + // ignore: discarded_futures + videoController?.dispose(); super.dispose(); } diff --git a/lib/src/views/camera/share_image_view.dart b/lib/src/views/camera/share_image_view.dart index f6db164..02f629e 100644 --- a/lib/src/views/camera/share_image_view.dart +++ b/lib/src/views/camera/share_image_view.dart @@ -58,7 +58,7 @@ class _ShareImageView extends State { String lastQuery = ''; @override - Future initState() async { + void initState() { super.initState(); final allContacts = twonlyDB.contactsDao.watchContactsForShareView(); @@ -70,7 +70,7 @@ class _ShareImageView extends State { await updateUsers(allContacts.where((x) => !x.archived).toList()); }); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { @@ -90,9 +90,9 @@ class _ShareImageView extends State { } @override - Future dispose() async { + void dispose() { + unawaited(contactSub.cancel()); super.dispose(); - await contactSub.cancel(); } Future updateUsers(List users) async { diff --git a/lib/src/views/chats/add_new_user.view.dart b/lib/src/views/chats/add_new_user.view.dart index ebf3910..d6398b4 100644 --- a/lib/src/views/chats/add_new_user.view.dart +++ b/lib/src/views/chats/add_new_user.view.dart @@ -46,8 +46,8 @@ class _SearchUsernameView extends State { } @override - Future dispose() async { - await contactsStream.cancel(); + void dispose() { + unawaited(contactsStream.cancel()); super.dispose(); } diff --git a/lib/src/views/chats/chat_list.view.dart b/lib/src/views/chats/chat_list.view.dart index 4ca14d1..d8efa67 100644 --- a/lib/src/views/chats/chat_list.view.dart +++ b/lib/src/views/chats/chat_list.view.dart @@ -352,9 +352,9 @@ class _UserListItem extends State { } @override - Future dispose() async { - await messagesNotOpenedStream.cancel(); - await lastMessageStream.cancel(); + void dispose() { + unawaited(messagesNotOpenedStream.cancel()); + unawaited(lastMessageStream.cancel()); super.dispose(); } diff --git a/lib/src/views/chats/chat_list_components/backup_notice.card.dart b/lib/src/views/chats/chat_list_components/backup_notice.card.dart index 2ee29b4..d5b9a36 100644 --- a/lib/src/views/chats/chat_list_components/backup_notice.card.dart +++ b/lib/src/views/chats/chat_list_components/backup_notice.card.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/storage.dart'; @@ -14,9 +16,9 @@ class _BackupNoticeCardState extends State { bool showBackupNotice = false; @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { diff --git a/lib/src/views/chats/chat_messages.view.dart b/lib/src/views/chats/chat_messages.view.dart index 407f929..1fbcf34 100644 --- a/lib/src/views/chats/chat_messages.view.dart +++ b/lib/src/views/chats/chat_messages.view.dart @@ -87,11 +87,11 @@ class _ChatMessagesViewState extends State { int? focusedScrollItem; @override - Future initState() async { + void initState() { super.initState(); user = widget.contact; textFieldFocus = FocusNode(); - await initStreams(); + unawaited(initStreams()); tutorial = Timer(const Duration(seconds: 1), () async { tutorial = null; @@ -101,9 +101,9 @@ class _ChatMessagesViewState extends State { } @override - Future dispose() async { - await userSub.cancel(); - await messageSub.cancel(); + void dispose() { + unawaited(userSub.cancel()); + unawaited(messageSub.cancel()); tutorial?.cancel(); textFieldFocus.dispose(); super.dispose(); diff --git a/lib/src/views/chats/chat_messages_components/chat_media_entry.dart b/lib/src/views/chats/chat_messages_components/chat_media_entry.dart index 5569514..65208f0 100644 --- a/lib/src/views/chats/chat_messages_components/chat_media_entry.dart +++ b/lib/src/views/chats/chat_messages_components/chat_media_entry.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:drift/drift.dart' show Value; import 'package:flutter/material.dart'; import 'package:twonly/globals.dart'; @@ -37,9 +39,9 @@ class _ChatMediaEntryState extends State { bool canBeReopened = false; @override - Future initState() async { + void initState() { super.initState(); - await checkIfTutorialCanBeShown(); + unawaited(checkIfTutorialCanBeShown()); } Future checkIfTutorialCanBeShown() async { diff --git a/lib/src/views/chats/chat_messages_components/in_chat_media_viewer.dart b/lib/src/views/chats/chat_messages_components/in_chat_media_viewer.dart index 6b34a7f..c80b601 100644 --- a/lib/src/views/chats/chat_messages_components/in_chat_media_viewer.dart +++ b/lib/src/views/chats/chat_messages_components/in_chat_media_viewer.dart @@ -35,10 +35,10 @@ class _InChatMediaViewerState extends State { Timer? _timer; @override - Future initState() async { + void initState() { super.initState(); - await loadIndexAsync(); - await initStream(); + unawaited(loadIndexAsync()); + unawaited(initStream()); } Future loadIndexAsync() async { @@ -68,9 +68,10 @@ class _InChatMediaViewerState extends State { } @override - Future dispose() async { + void dispose() { super.dispose(); - await messageStream?.cancel(); + // ignore: discarded_futures + messageStream?.cancel(); _timer?.cancel(); // videoController?.dispose(); } diff --git a/lib/src/views/chats/chat_messages_components/response_container.dart b/lib/src/views/chats/chat_messages_components/response_container.dart index ba90e6e..14bdf7a 100644 --- a/lib/src/views/chats/chat_messages_components/response_container.dart +++ b/lib/src/views/chats/chat_messages_components/response_container.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:convert'; import 'dart:io'; @@ -125,9 +126,9 @@ class _ResponsePreviewState extends State { File? thumbnailPath; @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { diff --git a/lib/src/views/chats/media_viewer.view.dart b/lib/src/views/chats/media_viewer.view.dart index c3d4f0d..0093d89 100644 --- a/lib/src/views/chats/media_viewer.view.dart +++ b/lib/src/views/chats/media_viewer.view.dart @@ -1,4 +1,4 @@ -// ignore_for_file: inference_failure_on_collection_literal, avoid_dynamic_calls +// ignore_for_file: inference_failure_on_collection_literal, avoid_dynamic_calls, discarded_futures import 'dart:async'; import 'dart:convert'; @@ -71,24 +71,24 @@ class _MediaViewerViewState extends State { TextEditingController textMessageController = TextEditingController(); @override - Future initState() async { + void initState() { super.initState(); if (widget.initialMessage != null) { allMediaFiles = [widget.initialMessage!]; } - await asyncLoadNextMedia(true); + unawaited(asyncLoadNextMedia(true)); } @override - Future dispose() async { + void dispose() { nextMediaTimer?.cancel(); progressTimer?.cancel(); - await _noScreenshot.screenshotOn(); - await _subscription.cancel(); - await downloadStateListener?.cancel(); - await videoController?.dispose(); + _noScreenshot.screenshotOn(); + _subscription.cancel(); + downloadStateListener?.cancel(); + videoController?.dispose(); super.dispose(); } @@ -737,9 +737,9 @@ class _ReactionButtonsState extends State { EmojiAnimation.animatedIcons.keys.toList().sublist(0, 6); @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { diff --git a/lib/src/views/chats/start_new_chat.view.dart b/lib/src/views/chats/start_new_chat.view.dart index 32e97fd..85c0773 100644 --- a/lib/src/views/chats/start_new_chat.view.dart +++ b/lib/src/views/chats/start_new_chat.view.dart @@ -44,8 +44,8 @@ class _StartNewChatView extends State { } @override - Future dispose() async { - await contactSub.cancel(); + void dispose() { + unawaited(contactSub.cancel()); super.dispose(); } diff --git a/lib/src/views/components/video_player_wrapper.dart b/lib/src/views/components/video_player_wrapper.dart index 2b72827..b35edc8 100644 --- a/lib/src/views/components/video_player_wrapper.dart +++ b/lib/src/views/components/video_player_wrapper.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:io'; import 'package:flutter/material.dart'; @@ -20,22 +21,24 @@ class _VideoPlayerWrapperState extends State { late VideoPlayerController _controller; @override - Future initState() async { + void initState() { super.initState(); _controller = VideoPlayerController.file(widget.videoPath); - await _controller.initialize().then((_) async { - if (context.mounted) { - await _controller.setLooping(true); - await _controller.play(); - setState(() {}); - } - }); + unawaited( + _controller.initialize().then((_) async { + if (context.mounted) { + await _controller.setLooping(true); + await _controller.play(); + setState(() {}); + } + }), + ); } @override - Future dispose() async { - await _controller.dispose(); + void dispose() { + unawaited(_controller.dispose()); super.dispose(); } diff --git a/lib/src/views/contact/contact_verify.view.dart b/lib/src/views/contact/contact_verify.view.dart index 4ccc494..05b05c3 100644 --- a/lib/src/views/contact/contact_verify.view.dart +++ b/lib/src/views/contact/contact_verify.view.dart @@ -36,15 +36,15 @@ class _ContactVerifyViewState extends State { Uint8List? _qrCodeImageBytes; @override - Future initState() async { + void initState() { super.initState(); _contact = widget.contact; - await loadAsync(); + unawaited(loadAsync()); } @override - Future dispose() async { - await _contactSub.cancel(); + void dispose() { + unawaited(_contactSub.cancel()); super.dispose(); } diff --git a/lib/src/views/home.view.dart b/lib/src/views/home.view.dart index 2644bca..346584a 100644 --- a/lib/src/views/home.view.dart +++ b/lib/src/views/home.view.dart @@ -86,7 +86,7 @@ class HomeViewState extends State { } @override - Future initState() async { + void initState() { super.initState(); activePageIdx = widget.initialPage; globalUpdateOfHomeViewPageIndex = (index) { @@ -99,15 +99,16 @@ class HomeViewState extends State { .listen((NotificationResponse? response) async { globalUpdateOfHomeViewPageIndex(0); }); - await selectCamera(0, true, false); - await initAsync(); + unawaited(selectCamera(0, true, false)); + unawaited(initAsync()); } @override - Future dispose() async { - await selectNotificationStream.close(); + void dispose() { + unawaited(selectNotificationStream.close()); disableCameraTimer?.cancel(); - await cameraController?.dispose(); + // ignore: discarded_futures + cameraController?.dispose(); super.dispose(); } diff --git a/lib/src/views/memories/memories.view.dart b/lib/src/views/memories/memories.view.dart index e34df6d..91702c6 100644 --- a/lib/src/views/memories/memories.view.dart +++ b/lib/src/views/memories/memories.view.dart @@ -27,14 +27,14 @@ class MemoriesViewState extends State { StreamSubscription>? messageSub; @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); + unawaited(initAsync()); } @override - Future dispose() async { - await messageSub?.cancel(); + void dispose() { + messageSub?.cancel(); super.dispose(); } diff --git a/lib/src/views/settings/account.view.dart b/lib/src/views/settings/account.view.dart index 64da2e0..37af702 100644 --- a/lib/src/views/settings/account.view.dart +++ b/lib/src/views/settings/account.view.dart @@ -25,9 +25,9 @@ class _AccountViewState extends State { bool hasRemainingBallance = false; @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { diff --git a/lib/src/views/settings/appearance.view.dart b/lib/src/views/settings/appearance.view.dart index 4873299..34e0688 100644 --- a/lib/src/views/settings/appearance.view.dart +++ b/lib/src/views/settings/appearance.view.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:twonly/src/providers/settings.provider.dart'; @@ -16,9 +18,9 @@ class _AppearanceViewState extends State { bool showFeedbackShortcut = false; @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { diff --git a/lib/src/views/settings/backup/backup.view.dart b/lib/src/views/settings/backup/backup.view.dart index 144c939..daa3086 100644 --- a/lib/src/views/settings/backup/backup.view.dart +++ b/lib/src/views/settings/backup/backup.view.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:twonly/src/model/json/userdata.dart'; @@ -33,9 +35,9 @@ class _BackupViewState extends State { final PageController pageController = PageController(); @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); + unawaited(initAsync()); gUpdateBackupView = initAsync; } diff --git a/lib/src/views/settings/backup/twonly_safe_server.view.dart b/lib/src/views/settings/backup/twonly_safe_server.view.dart index 9318eae..973f87a 100644 --- a/lib/src/views/settings/backup/twonly_safe_server.view.dart +++ b/lib/src/views/settings/backup/twonly_safe_server.view.dart @@ -1,5 +1,6 @@ // ignore_for_file: avoid_dynamic_calls +import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; @@ -22,10 +23,10 @@ class _TwonlySafeServerViewState extends State { final TextEditingController _passwordController = TextEditingController(); @override - Future initState() async { + void initState() { _urlController.text = 'https://'; super.initState(); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { diff --git a/lib/src/views/settings/chat/chat_reactions.view.dart b/lib/src/views/settings/chat/chat_reactions.view.dart index bd53127..086d44a 100644 --- a/lib/src/views/settings/chat/chat_reactions.view.dart +++ b/lib/src/views/settings/chat/chat_reactions.view.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/storage.dart'; @@ -15,9 +17,9 @@ class _ChatReactionSelectionView extends State { List selectedEmojis = []; @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { diff --git a/lib/src/views/settings/data_and_storage.view.dart b/lib/src/views/settings/data_and_storage.view.dart index 440e8b1..4c21c75 100644 --- a/lib/src/views/settings/data_and_storage.view.dart +++ b/lib/src/views/settings/data_and_storage.view.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/material.dart'; import 'package:twonly/src/services/api/media_download.dart'; @@ -16,9 +18,8 @@ class _DataAndStorageViewState extends State { bool storeMediaFilesInGallery = true; @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); } Future initAsync() async { diff --git a/lib/src/views/settings/developer/developer.view.dart b/lib/src/views/settings/developer/developer.view.dart new file mode 100644 index 0000000..aab4fbc --- /dev/null +++ b/lib/src/views/settings/developer/developer.view.dart @@ -0,0 +1,72 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:twonly/src/utils/storage.dart'; +import 'package:twonly/src/views/settings/developer/retransmission_data.view.dart'; + +class DeveloperSettingsView extends StatefulWidget { + const DeveloperSettingsView({super.key}); + + @override + State createState() => _DeveloperSettingsViewState(); +} + +class _DeveloperSettingsViewState extends State { + bool isDeveloper = true; + + @override + void initState() { + super.initState(); + unawaited(initAsync()); + } + + Future initAsync() async { + final user = await getUser(); + if (user == null) return; + setState(() { + isDeveloper = user.isDeveloper; + }); + } + + Future toggleDeveloperSettings() async { + await updateUserdata((u) { + u.isDeveloper = !u.isDeveloper; + return u; + }); + await initAsync(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Developer Settings'), + ), + body: ListView( + children: [ + ListTile( + title: const Text('Show Developer Settings'), + onTap: toggleDeveloperSettings, + trailing: Switch( + value: isDeveloper, + onChanged: (a) => toggleDeveloperSettings(), + ), + ), + ListTile( + title: const Text('Show Retransmission Database'), + onTap: () async { + await Navigator.push( + context, + MaterialPageRoute( + builder: (context) { + return const RetransmissionDataView(); + }, + ), + ); + }, + ), + ], + ), + ); + } +} diff --git a/lib/src/views/settings/developer/retransmission_data.view.dart b/lib/src/views/settings/developer/retransmission_data.view.dart new file mode 100644 index 0000000..da88f73 --- /dev/null +++ b/lib/src/views/settings/developer/retransmission_data.view.dart @@ -0,0 +1,72 @@ +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:twonly/globals.dart'; +import 'package:twonly/src/database/twonly_database.dart'; + +class RetransmissionDataView extends StatefulWidget { + const RetransmissionDataView({super.key}); + + @override + State createState() => _RetransmissionDataViewState(); +} + +class _RetransmissionDataViewState extends State { + List retransmissions = []; + List contacts = []; + StreamSubscription>? subscriptionRetransmission; + StreamSubscription>? subscriptionContacts; + + @override + void initState() { + super.initState(); + unawaited(initAsync()); + } + + @override + void dispose() { + // ignore: discarded_futures + subscriptionRetransmission?.cancel(); + // ignore: discarded_futures + subscriptionContacts?.cancel(); + super.dispose(); + } + + Future initAsync() async { + subscriptionContacts = + twonlyDB.contactsDao.watchAllContacts().listen((updated) { + setState(() { + contacts = updated; + }); + }); + subscriptionRetransmission = + twonlyDB.messageRetransmissionDao.watchAllMessages().listen((updated) { + setState(() { + retransmissions = updated; + }); + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Retransmission Database'), + ), + body: Column( + children: [ + ListView( + children: retransmissions + .map( + (retrans) => ListTile( + title: Text(retrans.retransmissionId.toString()), + subtitle: Text('Message to ${retrans.contactId}'), + ), + ) + .toList(), + ) + ], + ), + ); + } +} diff --git a/lib/src/views/settings/help/changelog.view.dart b/lib/src/views/settings/help/changelog.view.dart index e68e48a..bd2402f 100644 --- a/lib/src/views/settings/help/changelog.view.dart +++ b/lib/src/views/settings/help/changelog.view.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:twonly/src/utils/misc.dart'; @@ -74,12 +76,12 @@ class _ChangeLogViewState extends State { bool hideChangeLog = false; @override - Future initState() async { + void initState() { super.initState(); if (widget.changeLog != null) { changeLog = widget.changeLog!; } else { - await initAsync(); + unawaited(initAsync()); } } diff --git a/lib/src/views/settings/help/credits.view.dart b/lib/src/views/settings/help/credits.view.dart index e214ed4..ca50aa8 100644 --- a/lib/src/views/settings/help/credits.view.dart +++ b/lib/src/views/settings/help/credits.view.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; @@ -43,9 +45,9 @@ class _CreditsViewState extends State { List sticker = []; @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { diff --git a/lib/src/views/settings/help/faq.view.dart b/lib/src/views/settings/help/faq.view.dart index 753cf8a..01b114a 100644 --- a/lib/src/views/settings/help/faq.view.dart +++ b/lib/src/views/settings/help/faq.view.dart @@ -1,5 +1,6 @@ // ignore_for_file: avoid_dynamic_calls, inference_failure_on_untyped_parameter +import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; @@ -21,10 +22,10 @@ class _FaqViewState extends State { bool noInternet = false; @override - Future initState() async { + void initState() { super.initState(); domain = 'https://twonly.eu'; - await _fetchFAQData(); + unawaited(_fetchFAQData()); } Future _fetchFAQData() async { diff --git a/lib/src/views/settings/help/help.view.dart b/lib/src/views/settings/help/help.view.dart index 1a8f4b6..a0bef20 100644 --- a/lib/src/views/settings/help/help.view.dart +++ b/lib/src/views/settings/help/help.view.dart @@ -1,7 +1,6 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:package_info_plus/package_info_plus.dart'; -import 'package:twonly/globals.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/views/components/alert_dialog.dart'; @@ -154,12 +153,14 @@ class HelpView extends StatelessWidget { onLongPress: () async { final okay = await showAlertDialog( context, - 'Delete Retransmission messages', - 'Only do this if you know what you are doing :)', + 'Developer Settings', + 'Do you want to enable the developer settings?', ); if (okay) { - await twonlyDB.messageRetransmissionDao - .clearRetransmissionTable(); + await updateUserdata((u) { + u.isDeveloper = true; + return u; + }); } }, title: const Text( diff --git a/lib/src/views/settings/privacy_view_block.users.dart b/lib/src/views/settings/privacy_view_block.users.dart index 2acce07..ce1dd86 100644 --- a/lib/src/views/settings/privacy_view_block.users.dart +++ b/lib/src/views/settings/privacy_view_block.users.dart @@ -21,14 +21,9 @@ class _PrivacyViewBlockUsers extends State { String filter = ''; @override - Future initState() async { + void initState() { super.initState(); allUsers = twonlyDB.contactsDao.watchAllContacts(); - await loadAsync(); - } - - Future loadAsync() async { - setState(() {}); } @override diff --git a/lib/src/views/settings/profile/profile.view.dart b/lib/src/views/settings/profile/profile.view.dart index 5abd278..104bde0 100644 --- a/lib/src/views/settings/profile/profile.view.dart +++ b/lib/src/views/settings/profile/profile.view.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:avatar_maker/avatar_maker.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; @@ -21,9 +23,9 @@ class _ProfileViewState extends State { PersistentAvatarMakerController(customizedPropertyCategories: []); @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { diff --git a/lib/src/views/settings/settings_main.view.dart b/lib/src/views/settings/settings_main.view.dart index e67246c..b1ffe1c 100644 --- a/lib/src/views/settings/settings_main.view.dart +++ b/lib/src/views/settings/settings_main.view.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:twonly/src/model/json/userdata.dart'; @@ -10,6 +12,7 @@ import 'package:twonly/src/views/settings/appearance.view.dart'; import 'package:twonly/src/views/settings/backup/backup.view.dart'; import 'package:twonly/src/views/settings/chat/chat_settings.view.dart'; import 'package:twonly/src/views/settings/data_and_storage.view.dart'; +import 'package:twonly/src/views/settings/developer/developer.view.dart'; import 'package:twonly/src/views/settings/help/help.view.dart'; import 'package:twonly/src/views/settings/notification.view.dart'; import 'package:twonly/src/views/settings/privacy.view.dart'; @@ -28,9 +31,9 @@ class _SettingsMainViewState extends State { UserData? userData; @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { @@ -235,6 +238,21 @@ class _SettingsMainViewState extends State { ); }, ), + if (userData != null && userData!.isDeveloper) + BetterListTile( + icon: FontAwesomeIcons.code, + text: 'Developer Settings', + onTap: () async { + await Navigator.push( + context, + MaterialPageRoute( + builder: (context) { + return const DeveloperSettingsView(); + }, + ), + ); + }, + ), BetterListTile( icon: FontAwesomeIcons.shareFromSquare, text: context.lang.inviteFriends, diff --git a/lib/src/views/settings/subscription/additional_users.view.dart b/lib/src/views/settings/subscription/additional_users.view.dart index 5b4c4d6..1afc62f 100644 --- a/lib/src/views/settings/subscription/additional_users.view.dart +++ b/lib/src/views/settings/subscription/additional_users.view.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -48,10 +49,10 @@ class _AdditionalUsersViewState extends State { Response_PlanBallance? ballance; @override - Future initState() async { + void initState() { super.initState(); ballance = widget.ballance; - await initAsync(force: false); + unawaited(initAsync(force: false)); } Future initAsync({required bool force}) async { @@ -151,10 +152,10 @@ class _AdditionalAccountState extends State { late String username; @override - Future initState() async { + void initState() { super.initState(); username = widget.account.userId.toString(); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { diff --git a/lib/src/views/settings/subscription/manage_subscription.view.dart b/lib/src/views/settings/subscription/manage_subscription.view.dart index 144846c..7fb96ab 100644 --- a/lib/src/views/settings/subscription/manage_subscription.view.dart +++ b/lib/src/views/settings/subscription/manage_subscription.view.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; @@ -27,13 +29,13 @@ class _ManageSubscriptionViewState extends State { bool? autoRenewal; @override - Future initState() async { + void initState() { super.initState(); ballance = widget.ballance; if (ballance != null) { autoRenewal = ballance!.autoRenewal; } - await initAsync(true); + unawaited(initAsync(true)); } Future initAsync(bool force) async { diff --git a/lib/src/views/settings/subscription/select_payment.view.dart b/lib/src/views/settings/subscription/select_payment.view.dart index 443cc42..c92f115 100644 --- a/lib/src/views/settings/subscription/select_payment.view.dart +++ b/lib/src/views/settings/subscription/select_payment.view.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:twonly/globals.dart'; @@ -40,10 +42,10 @@ class _SelectPaymentViewState extends State { PaymentMethods paymentMethods = PaymentMethods.twonlyCredit; @override - Future initState() async { + void initState() { super.initState(); setCheckout(true); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { diff --git a/lib/src/views/settings/subscription/subscription.view.dart b/lib/src/views/settings/subscription/subscription.view.dart index f829aad..bdaeccd 100644 --- a/lib/src/views/settings/subscription/subscription.view.dart +++ b/lib/src/views/settings/subscription/subscription.view.dart @@ -1,4 +1,6 @@ // ignore_for_file: inference_failure_on_instance_creation +import 'dart:async'; + import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; @@ -115,9 +117,9 @@ class _SubscriptionViewState extends State { String? additionalOwnerName; @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async { diff --git a/lib/src/views/settings/subscription/voucher.view.dart b/lib/src/views/settings/subscription/voucher.view.dart index d92f722..f2c48dd 100644 --- a/lib/src/views/settings/subscription/voucher.view.dart +++ b/lib/src/views/settings/subscription/voucher.view.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:intl/intl.dart'; @@ -17,9 +19,9 @@ class _VoucherViewState extends State { List vouchers = []; @override - Future initState() async { + void initState() { super.initState(); - await initAsync(); + unawaited(initAsync()); } Future initAsync() async {