mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-05-25 05:12:11 +00:00
multiple bug fixes
This commit is contained in:
parent
0a91e34348
commit
d7dffa82ff
5 changed files with 62 additions and 26 deletions
|
|
@ -3,10 +3,12 @@ package eu.twonly
|
||||||
import io.flutter.app.FlutterApplication
|
import io.flutter.app.FlutterApplication
|
||||||
import dev.fluttercommunity.workmanager.WorkmanagerDebug
|
import dev.fluttercommunity.workmanager.WorkmanagerDebug
|
||||||
import dev.fluttercommunity.workmanager.LoggingDebugHandler
|
import dev.fluttercommunity.workmanager.LoggingDebugHandler
|
||||||
|
import io.crates.keyring.Keyring
|
||||||
|
|
||||||
class MyApplication : FlutterApplication() {
|
class MyApplication : FlutterApplication() {
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
|
Keyring.initializeNdkContext(this)
|
||||||
// This enables the internal plugin logging to Logcat
|
// This enables the internal plugin logging to Logcat
|
||||||
WorkmanagerDebug.setCurrent(LoggingDebugHandler())
|
WorkmanagerDebug.setCurrent(LoggingDebugHandler())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -237,7 +237,6 @@ Future<void> postStartupTasks() async {
|
||||||
// 1. Immediate background cleanup (Non-blocking for UI)
|
// 1. Immediate background cleanup (Non-blocking for UI)
|
||||||
await twonlyDB.messagesDao.purgeMessageTable();
|
await twonlyDB.messagesDao.purgeMessageTable();
|
||||||
unawaited(twonlyDB.receiptsDao.purgeReceivedReceipts());
|
unawaited(twonlyDB.receiptsDao.purgeReceivedReceipts());
|
||||||
unawaited(UserDiscoveryService.removeDeletedContacts());
|
|
||||||
unawaited(MediaFileService.purgeTempFolder());
|
unawaited(MediaFileService.purgeTempFolder());
|
||||||
|
|
||||||
// 2. Service initializations
|
// 2. Service initializations
|
||||||
|
|
@ -245,20 +244,7 @@ Future<void> postStartupTasks() async {
|
||||||
unawaited(finishStartedPreprocessing());
|
unawaited(finishStartedPreprocessing());
|
||||||
unawaited(createPushAvatars());
|
unawaited(createPushAvatars());
|
||||||
|
|
||||||
if (userService.currentUser.userDiscoveryInitializationError) {
|
unawaited(UserDiscoveryService.verifyInitializationOnStartup());
|
||||||
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',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}());
|
|
||||||
}
|
|
||||||
|
|
||||||
await Future.delayed(const Duration(seconds: 10));
|
await Future.delayed(const Duration(seconds: 10));
|
||||||
unawaited(initializeBackgroundTaskManager());
|
unawaited(initializeBackgroundTaskManager());
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:twonly/core/bridge/wrapper/user_discovery.dart';
|
import 'package:twonly/core/bridge/wrapper/user_discovery.dart';
|
||||||
|
import 'package:twonly/globals.dart';
|
||||||
import 'package:twonly/locator.dart';
|
import 'package:twonly/locator.dart';
|
||||||
import 'package:twonly/src/database/twonly.db.dart';
|
import 'package:twonly/src/database/twonly.db.dart';
|
||||||
import 'package:twonly/src/model/protobuf/client/generated/user_discovery/types.pb.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)
|
final subquery = twonlyDB.selectOnly(twonlyDB.contacts)
|
||||||
..addColumns([twonlyDB.contacts.userId])
|
..addColumns([twonlyDB.contacts.userId])
|
||||||
..where(twonlyDB.contacts.accountDeleted.equals(true));
|
..where(twonlyDB.contacts.accountDeleted.equals(true));
|
||||||
|
|
@ -216,4 +219,35 @@ class UserDiscoveryService {
|
||||||
u.isUserDiscoveryEnabled = false;
|
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',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:app_links/app_links.dart';
|
import 'package:app_links/app_links.dart';
|
||||||
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_sharing_intent/model/sharing_file.dart';
|
import 'package:flutter_sharing_intent/model/sharing_file.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.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<List<SharedFile>> _intentStreamSub;
|
||||||
late StreamSubscription<Uri> _deepLinkSub;
|
late StreamSubscription<Uri> _deepLinkSub;
|
||||||
|
StreamSubscription<RemoteMessage>? _onMessageOpenedAppSub;
|
||||||
|
|
||||||
static final streamHomeViewPageIndex = StreamController<int>.broadcast();
|
static final streamHomeViewPageIndex = StreamController<int>.broadcast();
|
||||||
|
|
||||||
|
|
@ -67,6 +69,13 @@ class HomeViewState extends State<HomeView> {
|
||||||
streamHomeViewPageIndex.add(0);
|
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(_mainCameraController.selectCamera(0, true));
|
||||||
unawaited(_initAsync());
|
unawaited(_initAsync());
|
||||||
|
|
||||||
|
|
@ -99,10 +108,23 @@ class HomeViewState extends State<HomeView> {
|
||||||
final notificationAppLaunchDetails = await flutterLocalNotificationsPlugin
|
final notificationAppLaunchDetails = await flutterLocalNotificationsPlugin
|
||||||
.getNotificationAppLaunchDetails();
|
.getNotificationAppLaunchDetails();
|
||||||
|
|
||||||
|
RemoteMessage? initialRemoteMessage;
|
||||||
|
try {
|
||||||
|
initialRemoteMessage =
|
||||||
|
await FirebaseMessaging.instance.getInitialMessage();
|
||||||
|
} catch (e) {
|
||||||
|
Log.error('Could not get initial Firebase message: $e');
|
||||||
|
}
|
||||||
|
|
||||||
if (widget.initialPage == 0 ||
|
if (widget.initialPage == 0 ||
|
||||||
|
initialRemoteMessage != null ||
|
||||||
(notificationAppLaunchDetails != null &&
|
(notificationAppLaunchDetails != null &&
|
||||||
notificationAppLaunchDetails.didNotificationLaunchApp)) {
|
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 =
|
final payload =
|
||||||
notificationAppLaunchDetails?.notificationResponse?.payload;
|
notificationAppLaunchDetails?.notificationResponse?.payload;
|
||||||
if (payload != null &&
|
if (payload != null &&
|
||||||
|
|
@ -134,6 +156,7 @@ class HomeViewState extends State<HomeView> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
_onMessageOpenedAppSub?.cancel();
|
||||||
selectNotificationStream.close();
|
selectNotificationStream.close();
|
||||||
streamHomeViewPageIndex.close();
|
streamHomeViewPageIndex.close();
|
||||||
_disableCameraTimer?.cancel();
|
_disableCameraTimer?.cancel();
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,10 @@ import 'package:http/http.dart' as http;
|
||||||
import 'package:package_info_plus/package_info_plus.dart';
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
import 'package:twonly/locator.dart';
|
import 'package:twonly/locator.dart';
|
||||||
import 'package:twonly/src/constants/routes.keys.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/model/protobuf/api/http/http_requests.pb.dart';
|
||||||
import 'package:twonly/src/services/api/utils.api.dart';
|
import 'package:twonly/src/services/api/utils.api.dart';
|
||||||
import 'package:twonly/src/utils/log.dart';
|
import 'package:twonly/src/utils/log.dart';
|
||||||
import 'package:twonly/src/utils/misc.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/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/contact_us/submit_message.view.dart';
|
||||||
import 'package:twonly/src/visual/views/settings/help/faq.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 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 =
|
final apiUrl =
|
||||||
'http${apiService.apiSecure}://${apiService.apiHost}/api/upload';
|
'http${apiService.apiSecure}://${apiService.apiHost}/api/upload';
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue