multiple bug fixes

This commit is contained in:
otsmr 2026-05-12 23:52:08 +02:00
parent 0a91e34348
commit d7dffa82ff
5 changed files with 62 additions and 26 deletions

View file

@ -3,10 +3,12 @@ package eu.twonly
import io.flutter.app.FlutterApplication
import dev.fluttercommunity.workmanager.WorkmanagerDebug
import dev.fluttercommunity.workmanager.LoggingDebugHandler
import io.crates.keyring.Keyring
class MyApplication : FlutterApplication() {
override fun onCreate() {
super.onCreate()
Keyring.initializeNdkContext(this)
// This enables the internal plugin logging to Logcat
WorkmanagerDebug.setCurrent(LoggingDebugHandler())
}

View file

@ -237,7 +237,6 @@ Future<void> postStartupTasks() async {
// 1. Immediate background cleanup (Non-blocking for UI)
await twonlyDB.messagesDao.purgeMessageTable();
unawaited(twonlyDB.receiptsDao.purgeReceivedReceipts());
unawaited(UserDiscoveryService.removeDeletedContacts());
unawaited(MediaFileService.purgeTempFolder());
// 2. Service initializations
@ -245,20 +244,7 @@ Future<void> postStartupTasks() async {
unawaited(finishStartedPreprocessing());
unawaited(createPushAvatars());
if (userService.currentUser.userDiscoveryInitializationError) {
unawaited(() async {
try {
await UserDiscoveryService.initializeOrUpdate(
threshold: userService.currentUser.userDiscoveryThreshold,
sharePromotion: userService.currentUser.userDiscoverySharePromotion,
);
} catch (e) {
Log.error(
'Failed to retry UserDiscovery initialization on startup: $e',
);
}
}());
}
unawaited(UserDiscoveryService.verifyInitializationOnStartup());
await Future.delayed(const Duration(seconds: 10));
unawaited(initializeBackgroundTaskManager());

View file

@ -1,8 +1,11 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:collection/collection.dart';
import 'package:drift/drift.dart';
import 'package:flutter/foundation.dart';
import 'package:twonly/core/bridge/wrapper/user_discovery.dart';
import 'package:twonly/globals.dart';
import 'package:twonly/locator.dart';
import 'package:twonly/src/database/twonly.db.dart';
import 'package:twonly/src/model/protobuf/client/generated/user_discovery/types.pb.dart';
@ -177,7 +180,7 @@ class UserDiscoveryService {
}
}
static Future<void> removeDeletedContacts() async {
static Future<void> _removeDeletedContacts() async {
final subquery = twonlyDB.selectOnly(twonlyDB.contacts)
..addColumns([twonlyDB.contacts.userId])
..where(twonlyDB.contacts.accountDeleted.equals(true));
@ -216,4 +219,35 @@ class UserDiscoveryService {
u.isUserDiscoveryEnabled = false;
});
}
static Future<void> verifyInitializationOnStartup() async {
await _removeDeletedContacts();
final configExists = File(
'${AppEnvironment.supportDir}/user_discovery_config.json',
).existsSync();
final hasShares = await (twonlyDB.select(
twonlyDB.userDiscoveryShares,
)..limit(1)).get().then((list) => list.isNotEmpty);
if (userService.currentUser.isUserDiscoveryEnabled &&
(userService.currentUser.userDiscoveryInitializationError ||
!configExists ||
!hasShares)) {
unawaited(() async {
try {
Log.info(
'Retrying UserDiscovery initialization on startup (configExists: $configExists, hasShares: $hasShares)',
);
await initializeOrUpdate(
threshold: userService.currentUser.userDiscoveryThreshold,
sharePromotion: userService.currentUser.userDiscoverySharePromotion,
);
} catch (e) {
Log.error(
'Failed to retry UserDiscovery initialization on startup: $e',
);
}
}());
}
}
}

View file

@ -1,6 +1,7 @@
import 'dart:async';
import 'package:app_links/app_links.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter_sharing_intent/model/sharing_file.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
@ -41,6 +42,7 @@ class HomeViewState extends State<HomeView> {
late StreamSubscription<List<SharedFile>> _intentStreamSub;
late StreamSubscription<Uri> _deepLinkSub;
StreamSubscription<RemoteMessage>? _onMessageOpenedAppSub;
static final streamHomeViewPageIndex = StreamController<int>.broadcast();
@ -67,6 +69,13 @@ class HomeViewState extends State<HomeView> {
streamHomeViewPageIndex.add(0);
});
_onMessageOpenedAppSub = FirebaseMessaging.onMessageOpenedApp.listen((
message,
) {
Log.info('Opened app from iOS/Remote push notification tap.');
streamHomeViewPageIndex.add(0);
});
unawaited(_mainCameraController.selectCamera(0, true));
unawaited(_initAsync());
@ -99,10 +108,23 @@ class HomeViewState extends State<HomeView> {
final notificationAppLaunchDetails = await flutterLocalNotificationsPlugin
.getNotificationAppLaunchDetails();
RemoteMessage? initialRemoteMessage;
try {
initialRemoteMessage =
await FirebaseMessaging.instance.getInitialMessage();
} catch (e) {
Log.error('Could not get initial Firebase message: $e');
}
if (widget.initialPage == 0 ||
initialRemoteMessage != null ||
(notificationAppLaunchDetails != null &&
notificationAppLaunchDetails.didNotificationLaunchApp)) {
if (notificationAppLaunchDetails?.didNotificationLaunchApp ?? false) {
if (initialRemoteMessage != null) {
Log.info('App launched from iOS/Remote push notification tap.');
streamHomeViewPageIndex.add(0);
} else if (notificationAppLaunchDetails?.didNotificationLaunchApp ??
false) {
final payload =
notificationAppLaunchDetails?.notificationResponse?.payload;
if (payload != null &&
@ -134,6 +156,7 @@ class HomeViewState extends State<HomeView> {
@override
void dispose() {
_onMessageOpenedAppSub?.cancel();
selectNotificationStream.close();
streamHomeViewPageIndex.close();
_disableCameraTimer?.cancel();

View file

@ -7,12 +7,10 @@ import 'package:http/http.dart' as http;
import 'package:package_info_plus/package_info_plus.dart';
import 'package:twonly/locator.dart';
import 'package:twonly/src/constants/routes.keys.dart';
import 'package:twonly/src/constants/secure_storage.keys.dart';
import 'package:twonly/src/model/protobuf/api/http/http_requests.pb.dart';
import 'package:twonly/src/services/api/utils.api.dart';
import 'package:twonly/src/utils/log.dart';
import 'package:twonly/src/utils/misc.dart';
import 'package:twonly/src/utils/secure_storage.dart';
import 'package:twonly/src/visual/components/snackbar.dart';
import 'package:twonly/src/visual/views/settings/help/contact_us/submit_message.view.dart';
import 'package:twonly/src/visual/views/settings/help/faq.view.dart';
@ -50,13 +48,6 @@ class _ContactUsState extends State<ContactUsView> {
final uploadRequestBytes = uploadRequest.writeToBuffer();
final apiAuthTokenRaw = await SecureStorage.instance.read(
key: SecureStorageKeys.apiAuthToken,
);
if (apiAuthTokenRaw == null) {
Log.error('api auth token not defined.');
return null;
}
final apiUrl =
'http${apiService.apiSecure}://${apiService.apiHost}/api/upload';