fixing issue and starting with developer settings

This commit is contained in:
otsmr 2025-10-16 14:54:21 +02:00
parent 268488dab0
commit cb2f0d00a6
51 changed files with 433 additions and 214 deletions

View file

@ -1,5 +1,9 @@
# Changelog
## 0.0.61
- Fixing message decryption error
- Dependency and Flutter upgrade
## 0.0.60

View file

@ -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.

View file

@ -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

View file

@ -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;

View file

@ -23,7 +23,7 @@ class _AppState extends State<App> with WidgetsBindingObserver {
bool wasPaused = false;
@override
Future<void> initState() async {
void initState() {
super.initState();
globalIsAppInBackground = false;
WidgetsBinding.instance.addObserver(this);
@ -39,7 +39,7 @@ class _AppState extends State<App> with WidgetsBindingObserver {
await context.read<CustomChangeProvider>().updatePlan(planId);
};
await initAsync();
unawaited(initAsync());
}
Future<void> setUserPlan() async {

View file

@ -63,6 +63,12 @@ class MessageRetransmissionDao extends DatabaseAccessor<TwonlyDatabase>
..where((t) => t.retransmissionId.equals(retransmissionId));
}
Stream<List<MessageRetransmission>> watchAllMessages() {
return (select(messageRetransmissions)
..orderBy([(t) => OrderingTerm.asc(t.retransmissionId)]))
.watch();
}
Future<void> updateRetransmission(
int retransmissionId,
MessageRetransmissionsCompanion updatedValues,

View file

@ -93,22 +93,22 @@ class SignalDao extends DatabaseAccessor<TwonlyDatabase> with _$SignalDaoMixin {
}
Future<void> 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),
),
)),
))

View file

@ -29,6 +29,9 @@ class UserData {
@JsonKey(defaultValue: 0)
int avatarCounter = 0;
@JsonKey(defaultValue: false)
bool isDeveloper = false;
@JsonKey(defaultValue: 0)
int deviceId = 0;

View file

@ -16,6 +16,7 @@ UserData _$UserDataFromJson(Map<String, dynamic> 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<String, dynamic> _$UserDataToJson(UserData instance) => <String, dynamic>{
'avatarSvg': instance.avatarSvg,
'avatarJson': instance.avatarJson,
'avatarCounter': instance.avatarCounter,
'isDeveloper': instance.isDeveloper,
'deviceId': instance.deviceId,
'subscriptionPlan': instance.subscriptionPlan,
'lastImageSend': instance.lastImageSend?.toIso8601String(),

View file

@ -131,7 +131,7 @@ Future<client.Response> 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;

View file

@ -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<CameraZoomButtons> {
bool _isDisposed = false;
@override
Future<void> initState() async {
void initState() {
super.initState();
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {

View file

@ -173,9 +173,9 @@ class _CameraPreviewViewState extends State<CameraPreviewView> {
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
@override
Future<void> initState() async {
void initState() {
super.initState();
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {

View file

@ -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<CameraSendToView> {
SelectedCameraDetails selectedCameraDetails = SelectedCameraDetails();
@override
Future<void> initState() async {
void initState() {
super.initState();
await selectCamera(0, true, false);
unawaited(selectCamera(0, true, false));
}
@override
Future<void> dispose() async {
await cameraController?.dispose();
void dispose() {
// ignore: discarded_futures
cameraController?.dispose();
cameraController = null;
selectedCameraDetails = SelectedCameraDetails();
super.dispose();

View file

@ -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<FilterLayer> {
];
@override
Future<void> initState() async {
void initState() {
super.initState();
WidgetsBinding.instance.addPostFrameCallback((_) {
pageController.jumpToPage(1);
});
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {

View file

@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
@ -24,9 +25,9 @@ class _LocationFilterState extends State<LocationFilter> {
Response_Location? location;
@override
Future<void> initState() async {
void initState() {
super.initState();
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {

View file

@ -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<Emojis> {
List<String> lastUsed = emojis;
@override
Future<void> initState() async {
void initState() {
super.initState();
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {

View file

@ -72,27 +72,28 @@ class _ShareImageEditorView extends State<ShareImageEditorView> {
Future<bool>? videoUploadHandler;
@override
Future<void> 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<ShareImageEditorView> {
}
@override
Future<void> dispose() async {
void dispose() {
isDisposed = true;
layers.clear();
await videoController?.dispose();
// ignore: discarded_futures
videoController?.dispose();
super.dispose();
}

View file

@ -58,7 +58,7 @@ class _ShareImageView extends State<ShareImageView> {
String lastQuery = '';
@override
Future<void> initState() async {
void initState() {
super.initState();
final allContacts = twonlyDB.contactsDao.watchContactsForShareView();
@ -70,7 +70,7 @@ class _ShareImageView extends State<ShareImageView> {
await updateUsers(allContacts.where((x) => !x.archived).toList());
});
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {
@ -90,9 +90,9 @@ class _ShareImageView extends State<ShareImageView> {
}
@override
Future<void> dispose() async {
void dispose() {
unawaited(contactSub.cancel());
super.dispose();
await contactSub.cancel();
}
Future<void> updateUsers(List<Contact> users) async {

View file

@ -46,8 +46,8 @@ class _SearchUsernameView extends State<AddNewUserView> {
}
@override
Future<void> dispose() async {
await contactsStream.cancel();
void dispose() {
unawaited(contactsStream.cancel());
super.dispose();
}

View file

@ -352,9 +352,9 @@ class _UserListItem extends State<UserListItem> {
}
@override
Future<void> dispose() async {
await messagesNotOpenedStream.cancel();
await lastMessageStream.cancel();
void dispose() {
unawaited(messagesNotOpenedStream.cancel());
unawaited(lastMessageStream.cancel());
super.dispose();
}

View file

@ -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<BackupNoticeCard> {
bool showBackupNotice = false;
@override
Future<void> initState() async {
void initState() {
super.initState();
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {

View file

@ -87,11 +87,11 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
int? focusedScrollItem;
@override
Future<void> 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<ChatMessagesView> {
}
@override
Future<void> dispose() async {
await userSub.cancel();
await messageSub.cancel();
void dispose() {
unawaited(userSub.cancel());
unawaited(messageSub.cancel());
tutorial?.cancel();
textFieldFocus.dispose();
super.dispose();

View file

@ -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<ChatMediaEntry> {
bool canBeReopened = false;
@override
Future<void> initState() async {
void initState() {
super.initState();
await checkIfTutorialCanBeShown();
unawaited(checkIfTutorialCanBeShown());
}
Future<void> checkIfTutorialCanBeShown() async {

View file

@ -35,10 +35,10 @@ class _InChatMediaViewerState extends State<InChatMediaViewer> {
Timer? _timer;
@override
Future<void> initState() async {
void initState() {
super.initState();
await loadIndexAsync();
await initStream();
unawaited(loadIndexAsync());
unawaited(initStream());
}
Future<void> loadIndexAsync() async {
@ -68,9 +68,10 @@ class _InChatMediaViewerState extends State<InChatMediaViewer> {
}
@override
Future<void> dispose() async {
void dispose() {
super.dispose();
await messageStream?.cancel();
// ignore: discarded_futures
messageStream?.cancel();
_timer?.cancel();
// videoController?.dispose();
}

View file

@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
@ -125,9 +126,9 @@ class _ResponsePreviewState extends State<ResponsePreview> {
File? thumbnailPath;
@override
Future<void> initState() async {
void initState() {
super.initState();
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {

View file

@ -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<MediaViewerView> {
TextEditingController textMessageController = TextEditingController();
@override
Future<void> initState() async {
void initState() {
super.initState();
if (widget.initialMessage != null) {
allMediaFiles = [widget.initialMessage!];
}
await asyncLoadNextMedia(true);
unawaited(asyncLoadNextMedia(true));
}
@override
Future<void> 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<ReactionButtons> {
EmojiAnimation.animatedIcons.keys.toList().sublist(0, 6);
@override
Future<void> initState() async {
void initState() {
super.initState();
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {

View file

@ -44,8 +44,8 @@ class _StartNewChatView extends State<StartNewChatView> {
}
@override
Future<void> dispose() async {
await contactSub.cancel();
void dispose() {
unawaited(contactSub.cancel());
super.dispose();
}

View file

@ -1,3 +1,4 @@
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
@ -20,22 +21,24 @@ class _VideoPlayerWrapperState extends State<VideoPlayerWrapper> {
late VideoPlayerController _controller;
@override
Future<void> 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<void> dispose() async {
await _controller.dispose();
void dispose() {
unawaited(_controller.dispose());
super.dispose();
}

View file

@ -36,15 +36,15 @@ class _ContactVerifyViewState extends State<ContactVerifyView> {
Uint8List? _qrCodeImageBytes;
@override
Future<void> initState() async {
void initState() {
super.initState();
_contact = widget.contact;
await loadAsync();
unawaited(loadAsync());
}
@override
Future<void> dispose() async {
await _contactSub.cancel();
void dispose() {
unawaited(_contactSub.cancel());
super.dispose();
}

View file

@ -86,7 +86,7 @@ class HomeViewState extends State<HomeView> {
}
@override
Future<void> initState() async {
void initState() {
super.initState();
activePageIdx = widget.initialPage;
globalUpdateOfHomeViewPageIndex = (index) {
@ -99,15 +99,16 @@ class HomeViewState extends State<HomeView> {
.listen((NotificationResponse? response) async {
globalUpdateOfHomeViewPageIndex(0);
});
await selectCamera(0, true, false);
await initAsync();
unawaited(selectCamera(0, true, false));
unawaited(initAsync());
}
@override
Future<void> dispose() async {
await selectNotificationStream.close();
void dispose() {
unawaited(selectNotificationStream.close());
disableCameraTimer?.cancel();
await cameraController?.dispose();
// ignore: discarded_futures
cameraController?.dispose();
super.dispose();
}

View file

@ -27,14 +27,14 @@ class MemoriesViewState extends State<MemoriesView> {
StreamSubscription<List<Message>>? messageSub;
@override
Future<void> initState() async {
void initState() {
super.initState();
await initAsync();
unawaited(initAsync());
}
@override
Future<void> dispose() async {
await messageSub?.cancel();
void dispose() {
messageSub?.cancel();
super.dispose();
}

View file

@ -25,9 +25,9 @@ class _AccountViewState extends State<AccountView> {
bool hasRemainingBallance = false;
@override
Future<void> initState() async {
void initState() {
super.initState();
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {

View file

@ -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<AppearanceView> {
bool showFeedbackShortcut = false;
@override
Future<void> initState() async {
void initState() {
super.initState();
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {

View file

@ -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<BackupView> {
final PageController pageController = PageController();
@override
Future<void> initState() async {
void initState() {
super.initState();
await initAsync();
unawaited(initAsync());
gUpdateBackupView = initAsync;
}

View file

@ -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<TwonlySafeServerView> {
final TextEditingController _passwordController = TextEditingController();
@override
Future<void> initState() async {
void initState() {
_urlController.text = 'https://';
super.initState();
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {

View file

@ -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<ChatReactionSelectionView> {
List<String> selectedEmojis = [];
@override
Future<void> initState() async {
void initState() {
super.initState();
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {

View file

@ -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<DataAndStorageView> {
bool storeMediaFilesInGallery = true;
@override
Future<void> initState() async {
void initState() {
super.initState();
await initAsync();
}
Future<void> initAsync() async {

View file

@ -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<DeveloperSettingsView> createState() => _DeveloperSettingsViewState();
}
class _DeveloperSettingsViewState extends State<DeveloperSettingsView> {
bool isDeveloper = true;
@override
void initState() {
super.initState();
unawaited(initAsync());
}
Future<void> initAsync() async {
final user = await getUser();
if (user == null) return;
setState(() {
isDeveloper = user.isDeveloper;
});
}
Future<void> 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();
},
),
);
},
),
],
),
);
}
}

View file

@ -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<RetransmissionDataView> createState() => _RetransmissionDataViewState();
}
class _RetransmissionDataViewState extends State<RetransmissionDataView> {
List<MessageRetransmission> retransmissions = [];
List<Contact> contacts = [];
StreamSubscription<List<MessageRetransmission>>? subscriptionRetransmission;
StreamSubscription<List<Contact>>? subscriptionContacts;
@override
void initState() {
super.initState();
unawaited(initAsync());
}
@override
void dispose() {
// ignore: discarded_futures
subscriptionRetransmission?.cancel();
// ignore: discarded_futures
subscriptionContacts?.cancel();
super.dispose();
}
Future<void> 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(),
)
],
),
);
}
}

View file

@ -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<ChangeLogView> {
bool hideChangeLog = false;
@override
Future<void> initState() async {
void initState() {
super.initState();
if (widget.changeLog != null) {
changeLog = widget.changeLog!;
} else {
await initAsync();
unawaited(initAsync());
}
}

View file

@ -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<CreditsView> {
List<Sticker> sticker = [];
@override
Future<void> initState() async {
void initState() {
super.initState();
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {

View file

@ -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<FaqView> {
bool noInternet = false;
@override
Future<void> initState() async {
void initState() {
super.initState();
domain = 'https://twonly.eu';
await _fetchFAQData();
unawaited(_fetchFAQData());
}
Future<void> _fetchFAQData() async {

View file

@ -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(

View file

@ -21,14 +21,9 @@ class _PrivacyViewBlockUsers extends State<PrivacyViewBlockUsers> {
String filter = '';
@override
Future<void> initState() async {
void initState() {
super.initState();
allUsers = twonlyDB.contactsDao.watchAllContacts();
await loadAsync();
}
Future<void> loadAsync() async {
setState(() {});
}
@override

View file

@ -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<ProfileView> {
PersistentAvatarMakerController(customizedPropertyCategories: []);
@override
Future<void> initState() async {
void initState() {
super.initState();
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {

View file

@ -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<SettingsMainView> {
UserData? userData;
@override
Future<void> initState() async {
void initState() {
super.initState();
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {
@ -235,6 +238,21 @@ class _SettingsMainViewState extends State<SettingsMainView> {
);
},
),
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,

View file

@ -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<AdditionalUsersView> {
Response_PlanBallance? ballance;
@override
Future<void> initState() async {
void initState() {
super.initState();
ballance = widget.ballance;
await initAsync(force: false);
unawaited(initAsync(force: false));
}
Future<void> initAsync({required bool force}) async {
@ -151,10 +152,10 @@ class _AdditionalAccountState extends State<AdditionalAccount> {
late String username;
@override
Future<void> initState() async {
void initState() {
super.initState();
username = widget.account.userId.toString();
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {

View file

@ -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<ManageSubscriptionView> {
bool? autoRenewal;
@override
Future<void> initState() async {
void initState() {
super.initState();
ballance = widget.ballance;
if (ballance != null) {
autoRenewal = ballance!.autoRenewal;
}
await initAsync(true);
unawaited(initAsync(true));
}
Future<void> initAsync(bool force) async {

View file

@ -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<SelectPaymentView> {
PaymentMethods paymentMethods = PaymentMethods.twonlyCredit;
@override
Future<void> initState() async {
void initState() {
super.initState();
setCheckout(true);
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {

View file

@ -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<SubscriptionView> {
String? additionalOwnerName;
@override
Future<void> initState() async {
void initState() {
super.initState();
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {

View file

@ -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<VoucherView> {
List<Response_Voucher> vouchers = [];
@override
Future<void> initState() async {
void initState() {
super.initState();
await initAsync();
unawaited(initAsync());
}
Future<void> initAsync() async {