diff --git a/lib/app.dart b/lib/app.dart index d09b45b..11f9f5d 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -1,13 +1,13 @@ import 'package:provider/provider.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/localization/generated/app_localizations.dart'; -import 'package:twonly/src/providers/connection_provider.dart'; -import 'package:twonly/src/providers/settings_change_provider.dart'; -import 'package:twonly/src/services/notification_service.dart'; +import 'package:twonly/src/providers/connection.provider.dart'; +import 'package:twonly/src/providers/settings.provider.dart'; +import 'package:twonly/src/services/notification.service.dart'; import 'package:twonly/src/utils/storage.dart'; -import 'package:twonly/src/views/onboarding/onboarding_view.dart'; -import 'package:twonly/src/views/home_view.dart'; -import 'package:twonly/src/views/onboarding/register_view.dart'; +import 'package:twonly/src/views/onboarding.view.dart'; +import 'package:twonly/src/views/home.view.dart'; +import 'package:twonly/src/views/register.view.dart'; import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'dart:async'; @@ -54,7 +54,7 @@ class _AppState extends State with WidgetsBindingObserver { globalBestFriendUserId = -1; if (user != null && context.mounted) { if (user.myBestFriendContactId != null) { - final contact = await twonlyDatabase.contactsDao + final contact = await twonlyDB.contactsDao .getContactByUserId(user.myBestFriendContactId!) .getSingleOrNull(); if (contact != null) { @@ -69,7 +69,7 @@ class _AppState extends State with WidgetsBindingObserver { Future initAsync() async { setUserPlan(); - apiProvider.connect(); + apiService.connect(); } @override @@ -78,8 +78,8 @@ class _AppState extends State with WidgetsBindingObserver { if (state == AppLifecycleState.resumed) { if (wasPaused) { globalIsAppInBackground = false; - twonlyDatabase.markUpdated(); - apiProvider.connect(); + twonlyDB.markUpdated(); + apiService.connect(); } } else if (state == AppLifecycleState.paused) { wasPaused = true; diff --git a/lib/globals.dart b/lib/globals.dart index 70015d7..0083ee7 100644 --- a/lib/globals.dart +++ b/lib/globals.dart @@ -1,10 +1,10 @@ import 'package:camera/camera.dart'; import 'package:twonly/src/database/twonly_database.dart'; -import 'package:twonly/src/providers/api_provider.dart'; +import 'package:twonly/src/services/api.service.dart'; -late ApiProvider apiProvider; +late ApiService apiService; // uses for background notification -late TwonlyDatabase twonlyDatabase; +late TwonlyDatabase twonlyDB; List gCameras = []; diff --git a/lib/main.dart b/lib/main.dart index f1ab66f..85e7be3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,16 +3,16 @@ import 'package:flutter/services.dart'; import 'package:provider/provider.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/database/twonly_database.dart'; -import 'package:twonly/src/providers/api/media_received.dart'; -import 'package:twonly/src/providers/api/media_send.dart'; -import 'package:twonly/src/providers/api_provider.dart'; +import 'package:twonly/src/services/api/media_received.dart'; +import 'package:twonly/src/services/api/media_send.dart'; +import 'package:twonly/src/services/api.service.dart'; import 'package:flutter/material.dart'; -import 'package:twonly/src/providers/connection_provider.dart'; -import 'package:twonly/src/providers/hive.dart'; -import 'package:twonly/src/providers/settings_change_provider.dart'; -import 'package:twonly/src/services/fcm_service.dart'; -import 'package:twonly/src/services/notification_service.dart'; -import 'package:twonly/src/utils/misc.dart'; +import 'package:twonly/src/providers/connection.provider.dart'; +import 'package:twonly/src/utils/hive.dart'; +import 'package:twonly/src/providers/settings.provider.dart'; +import 'package:twonly/src/services/fcm.service.dart'; +import 'package:twonly/src/services/notification.service.dart'; +import 'package:twonly/src/utils/log.dart'; import 'app.dart'; void main() async { @@ -24,16 +24,16 @@ void main() async { // This prevents a sudden theme change when the app is first displayed. await settingsController.loadSettings(); - setupLogger(); + initLogger(); await setupPushNotification(); await initMediaStorage(); gCameras = await availableCameras(); - apiProvider = ApiProvider(); - twonlyDatabase = TwonlyDatabase(); - await twonlyDatabase.messagesDao.resetPendingDownloadState(); + apiService = ApiService(); + twonlyDB = TwonlyDatabase(); + await twonlyDB.messagesDao.resetPendingDownloadState(); await purgeReceivedMediaFiles(); await purgeSendMediaFiles(); diff --git a/lib/src/providers/signal/connect_identitiy_key_store.dart b/lib/src/database/signal/connect_identitiy_key_store.dart similarity index 90% rename from lib/src/providers/signal/connect_identitiy_key_store.dart rename to lib/src/database/signal/connect_identitiy_key_store.dart index 55ae180..0b0f9b0 100644 --- a/lib/src/providers/signal/connect_identitiy_key_store.dart +++ b/lib/src/database/signal/connect_identitiy_key_store.dart @@ -13,7 +13,7 @@ class ConnectIdentityKeyStore extends IdentityKeyStore { @override Future getIdentity(SignalProtocolAddress address) async { SignalIdentityKeyStore? identity = - await (twonlyDatabase.select(twonlyDatabase.signalIdentityKeyStores) + await (twonlyDB.select(twonlyDB.signalIdentityKeyStores) ..where((t) => t.deviceId.equals(address.getDeviceId()) & t.name.equals(address.getName()))) @@ -47,7 +47,7 @@ class ConnectIdentityKeyStore extends IdentityKeyStore { return false; } if (await getIdentity(address) == null) { - await twonlyDatabase.into(twonlyDatabase.signalIdentityKeyStores).insert( + await twonlyDB.into(twonlyDB.signalIdentityKeyStores).insert( SignalIdentityKeyStoresCompanion( deviceId: Value(address.getDeviceId()), name: Value(address.getName()), @@ -55,7 +55,7 @@ class ConnectIdentityKeyStore extends IdentityKeyStore { ), ); } else { - await (twonlyDatabase.update(twonlyDatabase.signalIdentityKeyStores) + await (twonlyDB.update(twonlyDB.signalIdentityKeyStores) ..where((t) => t.deviceId.equals(address.getDeviceId()) & t.name.equals(address.getName()))) diff --git a/lib/src/providers/signal/connect_pre_key_store.dart b/lib/src/database/signal/connect_pre_key_store.dart similarity index 67% rename from lib/src/providers/signal/connect_pre_key_store.dart rename to lib/src/database/signal/connect_pre_key_store.dart index 04eb501..8bb33e2 100644 --- a/lib/src/providers/signal/connect_pre_key_store.dart +++ b/lib/src/database/signal/connect_pre_key_store.dart @@ -7,19 +7,17 @@ import 'package:twonly/src/database/twonly_database.dart'; class ConnectPreKeyStore extends PreKeyStore { @override Future containsPreKey(int preKeyId) async { - final preKeyRecord = - await (twonlyDatabase.select(twonlyDatabase.signalPreKeyStores) - ..where((tbl) => tbl.preKeyId.equals(preKeyId))) - .get(); + final preKeyRecord = await (twonlyDB.select(twonlyDB.signalPreKeyStores) + ..where((tbl) => tbl.preKeyId.equals(preKeyId))) + .get(); return preKeyRecord.isNotEmpty; } @override Future loadPreKey(int preKeyId) async { - final preKeyRecord = - await (twonlyDatabase.select(twonlyDatabase.signalPreKeyStores) - ..where((tbl) => tbl.preKeyId.equals(preKeyId))) - .get(); + final preKeyRecord = await (twonlyDB.select(twonlyDB.signalPreKeyStores) + ..where((tbl) => tbl.preKeyId.equals(preKeyId))) + .get(); if (preKeyRecord.isEmpty) { throw InvalidKeyIdException('No such preKey record! - $preKeyId'); } @@ -29,7 +27,7 @@ class ConnectPreKeyStore extends PreKeyStore { @override Future removePreKey(int preKeyId) async { - await (twonlyDatabase.delete(twonlyDatabase.signalPreKeyStores) + await (twonlyDB.delete(twonlyDB.signalPreKeyStores) ..where((tbl) => tbl.preKeyId.equals(preKeyId))) .go(); } @@ -42,9 +40,7 @@ class ConnectPreKeyStore extends PreKeyStore { ); try { - await twonlyDatabase - .into(twonlyDatabase.signalPreKeyStores) - .insert(preKeyCompanion); + await twonlyDB.into(twonlyDB.signalPreKeyStores).insert(preKeyCompanion); } catch (e) { Logger("pre_key_store").shout("$e"); } diff --git a/lib/src/providers/signal/connect_sender_key_store.dart b/lib/src/database/signal/connect_sender_key_store.dart similarity index 86% rename from lib/src/providers/signal/connect_sender_key_store.dart rename to lib/src/database/signal/connect_sender_key_store.dart index 47f8aee..d798150 100644 --- a/lib/src/providers/signal/connect_sender_key_store.dart +++ b/lib/src/database/signal/connect_sender_key_store.dart @@ -7,7 +7,7 @@ class ConnectSenderKeyStore extends SenderKeyStore { @override Future loadSenderKey(SenderKeyName senderKeyName) async { SignalSenderKeyStore? identity = - await (twonlyDatabase.select(twonlyDatabase.signalSenderKeyStores) + await (twonlyDB.select(twonlyDB.signalSenderKeyStores) ..where((t) => t.senderKeyName.equals(senderKeyName.serialize()))) .getSingleOrNull(); if (identity == null) { @@ -20,7 +20,7 @@ class ConnectSenderKeyStore extends SenderKeyStore { @override Future storeSenderKey( SenderKeyName senderKeyName, SenderKeyRecord record) async { - await twonlyDatabase.into(twonlyDatabase.signalSenderKeyStores).insert( + await twonlyDB.into(twonlyDB.signalSenderKeyStores).insert( SignalSenderKeyStoresCompanion( senderKey: Value(record.serialize()), senderKeyName: Value(senderKeyName.serialize()), diff --git a/lib/src/providers/signal/connect_session_store.dart b/lib/src/database/signal/connect_session_store.dart similarity index 66% rename from lib/src/providers/signal/connect_session_store.dart rename to lib/src/database/signal/connect_session_store.dart index f811fe4..79b1395 100644 --- a/lib/src/providers/signal/connect_session_store.dart +++ b/lib/src/database/signal/connect_session_store.dart @@ -6,25 +6,24 @@ import 'package:twonly/src/database/twonly_database.dart'; class ConnectSessionStore extends SessionStore { @override Future containsSession(SignalProtocolAddress address) async { - final sessions = - await (twonlyDatabase.select(twonlyDatabase.signalSessionStores) - ..where((tbl) => - tbl.deviceId.equals(address.getDeviceId()) & - tbl.name.equals(address.getName()))) - .get(); + final sessions = await (twonlyDB.select(twonlyDB.signalSessionStores) + ..where((tbl) => + tbl.deviceId.equals(address.getDeviceId()) & + tbl.name.equals(address.getName()))) + .get(); return sessions.isNotEmpty; } @override Future deleteAllSessions(String name) async { - await (twonlyDatabase.delete(twonlyDatabase.signalSessionStores) + await (twonlyDB.delete(twonlyDB.signalSessionStores) ..where((tbl) => tbl.name.equals(name))) .go(); } @override Future deleteSession(SignalProtocolAddress address) async { - await (twonlyDatabase.delete(twonlyDatabase.signalSessionStores) + await (twonlyDB.delete(twonlyDB.signalSessionStores) ..where((tbl) => tbl.deviceId.equals(address.getDeviceId()) & tbl.name.equals(address.getName()))) @@ -33,8 +32,7 @@ class ConnectSessionStore extends SessionStore { @override Future> getSubDeviceSessions(String name) async { - final deviceIds = await (twonlyDatabase - .select(twonlyDatabase.signalSessionStores) + final deviceIds = await (twonlyDB.select(twonlyDB.signalSessionStores) ..where( (tbl) => tbl.deviceId.equals(1).not() & tbl.name.equals(name))) .get(); @@ -43,12 +41,11 @@ class ConnectSessionStore extends SessionStore { @override Future loadSession(SignalProtocolAddress address) async { - final dbSession = - await (twonlyDatabase.select(twonlyDatabase.signalSessionStores) - ..where((tbl) => - tbl.deviceId.equals(address.getDeviceId()) & - tbl.name.equals(address.getName()))) - .get(); + final dbSession = await (twonlyDB.select(twonlyDB.signalSessionStores) + ..where((tbl) => + tbl.deviceId.equals(address.getDeviceId()) & + tbl.name.equals(address.getName()))) + .get(); if (dbSession.isEmpty) { return SessionRecord(); @@ -67,11 +64,11 @@ class ConnectSessionStore extends SessionStore { ); if (!await containsSession(address)) { - await twonlyDatabase - .into(twonlyDatabase.signalSessionStores) + await twonlyDB + .into(twonlyDB.signalSessionStores) .insert(sessionCompanion); } else { - await (twonlyDatabase.update(twonlyDatabase.signalSessionStores) + await (twonlyDB.update(twonlyDB.signalSessionStores) ..where((tbl) => tbl.deviceId.equals(address.getDeviceId()) & tbl.name.equals(address.getName()))) diff --git a/lib/src/providers/signal/connect_signal_protocol_store.dart b/lib/src/database/signal/connect_signal_protocol_store.dart similarity index 91% rename from lib/src/providers/signal/connect_signal_protocol_store.dart rename to lib/src/database/signal/connect_signal_protocol_store.dart index db2c5a3..1a0107c 100644 --- a/lib/src/providers/signal/connect_signal_protocol_store.dart +++ b/lib/src/database/signal/connect_signal_protocol_store.dart @@ -1,7 +1,7 @@ -import 'package:twonly/src/providers/signal/connect_identitiy_key_store.dart'; -import 'package:twonly/src/providers/signal/connect_pre_key_store.dart'; -import 'package:twonly/src/providers/signal/connect_session_store.dart'; -import 'package:twonly/src/providers/signal/connect_signed_pre_key_store.dart'; +import 'package:twonly/src/database/signal/connect_identitiy_key_store.dart'; +import 'package:twonly/src/database/signal/connect_pre_key_store.dart'; +import 'package:twonly/src/database/signal/connect_session_store.dart'; +import 'package:twonly/src/database/signal/connect_signed_pre_key_store.dart'; import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart'; class ConnectSignalProtocolStore implements SignalProtocolStore { diff --git a/lib/src/providers/signal/connect_signed_pre_key_store.dart b/lib/src/database/signal/connect_signed_pre_key_store.dart similarity index 100% rename from lib/src/providers/signal/connect_signed_pre_key_store.dart rename to lib/src/database/signal/connect_signed_pre_key_store.dart diff --git a/lib/src/views/gallery/gallery_item.dart b/lib/src/model/memory_item.model.dart similarity index 86% rename from lib/src/views/gallery/gallery_item.dart rename to lib/src/model/memory_item.model.dart index 1df192b..de36fcd 100644 --- a/lib/src/views/gallery/gallery_item.dart +++ b/lib/src/model/memory_item.model.dart @@ -2,12 +2,12 @@ import 'dart:convert'; import 'dart:io'; import 'package:drift/drift.dart'; import 'package:twonly/src/model/json/message.dart'; -import 'package:twonly/src/providers/api/media_send.dart' as send; +import 'package:twonly/src/services/api/media_send.dart' as send; import 'package:twonly/globals.dart'; import 'package:twonly/src/database/twonly_database.dart'; -class GalleryItem { - GalleryItem({ +class MemoryItem { + MemoryItem({ required this.id, required this.messages, required this.date, @@ -22,9 +22,9 @@ class GalleryItem { final File? imagePath; final File? videoPath; - static Future> convertFromMessages( + static Future> convertFromMessages( List messages) async { - Map items = {}; + Map items = {}; for (final message in messages) { bool isSend = message.messageOtherId == null; int id = message.mediaUploadId ?? message.messageId; @@ -41,7 +41,7 @@ class GalleryItem { } else { if (message.mediaStored) { /// media file was deleted, ... remove the file - twonlyDatabase.messagesDao.updateMessageByMessageId( + twonlyDB.messagesDao.updateMessageByMessageId( message.messageId, MessagesCompanion(mediaStored: Value(false))); } continue; @@ -56,7 +56,7 @@ class GalleryItem { items .putIfAbsent( id, - () => GalleryItem( + () => MemoryItem( id: id.toString(), messages: [], date: message.sendAt, diff --git a/lib/src/providers/connection_provider.dart b/lib/src/providers/connection.provider.dart similarity index 100% rename from lib/src/providers/connection_provider.dart rename to lib/src/providers/connection.provider.dart diff --git a/lib/src/providers/settings_change_provider.dart b/lib/src/providers/settings.provider.dart similarity index 100% rename from lib/src/providers/settings_change_provider.dart rename to lib/src/providers/settings.provider.dart diff --git a/lib/src/providers/api_provider.dart b/lib/src/services/api.service.dart similarity index 90% rename from lib/src/providers/api_provider.dart rename to lib/src/services/api.service.dart index 5ab7716..4c1d94b 100644 --- a/lib/src/providers/api_provider.dart +++ b/lib/src/services/api.service.dart @@ -6,7 +6,6 @@ import 'dart:math'; import 'package:fixnum/fixnum.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; -import 'package:logging/logging.dart'; import 'package:mutex/mutex.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:twonly/globals.dart'; @@ -17,14 +16,15 @@ import 'package:twonly/src/model/protobuf/api/error.pb.dart'; import 'package:twonly/src/model/protobuf/api/server_to_client.pb.dart' as server; import 'package:twonly/src/model/protobuf/api/server_to_client.pbserver.dart'; -import 'package:twonly/src/providers/api/api.dart'; -import 'package:twonly/src/providers/api/api_utils.dart'; -import 'package:twonly/src/providers/api/media_received.dart'; -import 'package:twonly/src/providers/api/media_send.dart'; -import 'package:twonly/src/providers/api/server_messages.dart'; -import 'package:twonly/src/providers/hive.dart'; -import 'package:twonly/src/services/fcm_service.dart'; -import 'package:twonly/src/services/flame_service.dart'; +import 'package:twonly/src/services/api/messages.dart'; +import 'package:twonly/src/services/api/utils.dart'; +import 'package:twonly/src/services/api/media_received.dart'; +import 'package:twonly/src/services/api/media_send.dart'; +import 'package:twonly/src/services/api/server_messages.dart'; +import 'package:twonly/src/utils/hive.dart'; +import 'package:twonly/src/services/fcm.service.dart'; +import 'package:twonly/src/services/flame.service.dart'; +import 'package:twonly/src/utils/log.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/storage.dart'; // ignore: library_prefixes @@ -39,14 +39,12 @@ final lockConnecting = Mutex(); /// The ApiProvider is responsible for communicating with the server. /// It handles errors and does automatically tries to reconnect on /// errors or network changes. -class ApiProvider { +class ApiService { final String apiHost = (kDebugMode) ? "10.99.0.140:3030" : "api.twonly.eu"; final String apiSecure = (kDebugMode) ? "" : "s"; bool isAuthenticated = false; - ApiProvider(); - - final log = Logger("ApiProvider"); + ApiService(); // reconnection params Timer? reconnectionTimer; @@ -63,10 +61,10 @@ class ApiProvider { _channel = channel; _channel!.stream.listen(_onData, onDone: _onDone, onError: _onError); await _channel!.ready; - log.info("Websocket is connected!"); + Log.info("websocket connected to $apiUrl"); return true; } on WebSocketChannelException catch (e) { - log.shout("Error: $e"); + Log.error("could not connect to api got: $e"); return false; } } @@ -83,7 +81,7 @@ class ApiProvider { retryMediaUpload(); tryDownloadAllMediaFiles(); notifyContactsAboutProfileChange(); - twonlyDatabase.markUpdated(); + twonlyDB.markUpdated(); syncFlameCounters(); } } @@ -97,11 +95,11 @@ class ApiProvider { _channel = null; isAuthenticated = false; globalCallbackConnectionState(false); - await twonlyDatabase.messagesDao.resetPendingDownloadState(); + await twonlyDB.messagesDao.resetPendingDownloadState(); } Future close(Function callback) async { - log.info("Closing the websocket connection!"); + Log.info("closing websocket connection"); if (_channel != null) { await _channel!.sink.close(); onClosed(); @@ -125,7 +123,7 @@ class ApiProvider { String apiUrl = "ws$apiSecure://$apiHost/api/client"; - log.fine("Trying to connect to the backend $apiUrl!"); + Log.info("connecting to $apiUrl"); if (await _connectTo(apiUrl)) { await onConnected(); return true; @@ -137,12 +135,12 @@ class ApiProvider { bool get isConnected => _channel != null && _channel!.closeCode != null; void _onDone() { - log.info("WebSocket Closed"); + Log.info("websocket closed without error"); onClosed(); } void _onError(dynamic e) { - log.info("WebSocket Error: $e"); + Log.error("websocket error: $e"); onClosed(); } @@ -156,7 +154,7 @@ class ApiProvider { await handleServerMessage(msg); } } catch (e) { - log.shout("Error parsing the servers message: $e"); + Log.error("Error parsing the servers message: $e"); } } @@ -172,7 +170,7 @@ class ApiProvider { return tmp; } if (DateTime.now().difference(startTime) > timeout) { - log.shout("Timeout for message $seq"); + Log.error("Timeout for message $seq"); return null; } await Future.delayed(Duration(milliseconds: 10)); @@ -196,13 +194,12 @@ class ApiProvider { Future retransmitRawBytes() async { var retransmit = await getRetransmission(); - Logger("api_provider.dart") - .info("Retransmit: ${retransmit.keys.length} messages"); + Log.info("retransmitting ${retransmit.keys.length} messages"); for (final seq in retransmit.keys) { try { _channel!.sink.add(base64Decode(retransmit[seq])); } catch (e) { - Logger("api_provider.dart").shout("$e"); + Log.error("$e"); } } } @@ -237,7 +234,7 @@ class ApiProvider { } if (_channel == null) { - log.shout("sending request, but api is not connected."); + Log.warn("sending request while api is not connected"); if (!await connect()) { return Result.error(ErrorCode.InternalError); } @@ -250,7 +247,7 @@ class ApiProvider { Result res = asResult(await _waitForResponse(seq)); if (res.isError) { - Logger("api_provider").shout("Got error from SERVER: ${res.error}"); + Log.error("got error from server: ${res.error}"); if (res.error == ErrorCode.SessionNotAuthenticated) { isAuthenticated = false; if (authenticated) { @@ -259,7 +256,7 @@ class ApiProvider { // this will send the request one more time. return sendRequestSync(request, authenticated: false); } else { - log.shout("Session is not authenticated."); + Log.error("session is not authenticated"); return Result.error(ErrorCode.InternalError); } } @@ -293,13 +290,13 @@ class ApiProvider { await updateUser(user); } } - log.info("Authenticated using api_auth_token"); + Log.info("websocket is authenticated"); onAuthenticated(); return true; } if (result.isError) { if (result.error != ErrorCode.AuthTokenNotValid) { - log.shout("Error while authenticating using token", result); + Log.error("got error while authenticating to the server", result); return false; } } @@ -326,7 +323,7 @@ class ApiProvider { final result = await sendRequestSync(req, authenticated: false); if (result.isError) { - log.shout("Error requesting auth challenge", result); + Log.error("could not request auth challenge", result); return; } @@ -347,7 +344,7 @@ class ApiProvider { final result2 = await sendRequestSync(req2, authenticated: false); if (result2.isError) { - log.shout("Error while sending auth challenge: ${result2.error}"); + Log.error("could not send auth response: ${result2.error}"); return; } @@ -370,7 +367,6 @@ class ApiProvider { await SignalHelper.getSignalStoreFromIdentity(signalIdentity); final signedPreKey = (await signalStore.loadSignedPreKeys())[0]; - log.shout("handle registrationId", signalIdentity.registrationId); var register = Handshake_Register() ..username = username @@ -385,7 +381,7 @@ class ApiProvider { if (inviteCode != null && inviteCode != "") { register.inviteCode = inviteCode; } - // Create the Handshake message + var handshake = Handshake()..register = register; var req = createClientToServerFromHandshake(handshake); diff --git a/lib/src/providers/api/media_received.dart b/lib/src/services/api/media_received.dart similarity index 91% rename from lib/src/providers/api/media_received.dart rename to lib/src/services/api/media_received.dart index 6751eaa..4952220 100644 --- a/lib/src/providers/api/media_received.dart +++ b/lib/src/services/api/media_received.dart @@ -10,7 +10,7 @@ import 'package:twonly/src/database/tables/messages_table.dart'; import 'package:twonly/src/model/json/message.dart'; import 'package:http/http.dart' as http; // import 'package:twonly/src/providers/api/api_utils.dart'; -import 'package:twonly/src/providers/api/media_send.dart'; +import 'package:twonly/src/services/api/media_send.dart'; import 'package:cryptography_plus/cryptography_plus.dart'; import 'package:logging/logging.dart'; import 'package:twonly/src/model/protobuf/api/client_to_server.pb.dart' @@ -23,7 +23,7 @@ Future tryDownloadAllMediaFiles({bool force = false}) async { // this is called when websocket is newly connected, so allow all downloads to be restarted. downloadStartedForMediaReceived = {}; List messages = - await twonlyDatabase.messagesDao.getAllMessagesPendingDownloading(); + await twonlyDB.messagesDao.getAllMessagesPendingDownloading(); for (Message message in messages) { await startDownloadMedia(message, force); @@ -91,17 +91,17 @@ Future startDownloadMedia(Message message, bool force) async { if (content is! MediaMessageContent) return; if (content.downloadToken == null) return; - var media = await twonlyDatabase.mediaDownloadsDao + var media = await twonlyDB.mediaDownloadsDao .getMediaDownloadById(message.messageId) .getSingleOrNull(); if (media == null) { - await twonlyDatabase.mediaDownloadsDao.insertMediaDownload( + await twonlyDB.mediaDownloadsDao.insertMediaDownload( MediaDownloadsCompanion( messageId: Value(message.messageId), downloadToken: Value(content.downloadToken!), ), ); - media = await twonlyDatabase.mediaDownloadsDao + media = await twonlyDB.mediaDownloadsDao .getMediaDownloadById(message.messageId) .getSingleOrNull(); } @@ -113,7 +113,7 @@ Future startDownloadMedia(Message message, bool force) async { } if (message.downloadState != DownloadState.downloaded) { - await twonlyDatabase.messagesDao.updateMessageByMessageId( + await twonlyDB.messagesDao.updateMessageByMessageId( message.messageId, MessagesCompanion( downloadState: Value(DownloadState.downloading), @@ -131,7 +131,7 @@ Future startDownloadMedia(Message message, bool force) async { String downloadToken = uint8ListToHex(content.downloadToken!); String apiUrl = - "http${apiProvider.apiSecure}://${apiProvider.apiHost}/api/download/$downloadToken"; + "http${apiService.apiSecure}://${apiService.apiHost}/api/download/$downloadToken"; var httpClient = http.Client(); var request = http.Request('GET', Uri.parse(apiUrl)); @@ -150,7 +150,7 @@ Future startDownloadMedia(Message message, bool force) async { }, onDone: () async { if (r.statusCode != 200) { Logger("media_received.dart").shout("Download error: $r"); - await twonlyDatabase.messagesDao.updateMessageByMessageId( + await twonlyDB.messagesDao.updateMessageByMessageId( message.messageId, MessagesCompanion( errorWhileSending: Value(true), @@ -211,7 +211,7 @@ Future handleEncryptedFile(Message msg, {Uint8List? encryptedBytesTmp}) async { await writeMediaFile(msg.messageId, "png", imageBytes); } catch (e) { Logger("media_received.dart").info("Decryption error: $e"); - await twonlyDatabase.messagesDao.updateMessageByMessageId( + await twonlyDB.messagesDao.updateMessageByMessageId( msg.messageId, MessagesCompanion( errorWhileSending: Value(true), @@ -222,14 +222,14 @@ Future handleEncryptedFile(Message msg, {Uint8List? encryptedBytesTmp}) async { return client.Response()..ok = ok; } - await twonlyDatabase.messagesDao.updateMessageByMessageId( + await twonlyDB.messagesDao.updateMessageByMessageId( msg.messageId, MessagesCompanion(downloadState: Value(DownloadState.downloaded)), ); await deleteMediaFile(msg.messageId, "encrypted"); - apiProvider.downloadDone(content.downloadToken!); + apiService.downloadDone(content.downloadToken!); } Future getImageBytes(int mediaId) async { @@ -301,8 +301,8 @@ Future purgeMediaFiles(Directory directory) async { try { if (directory.path.endsWith("send")) { - List messages = await twonlyDatabase.messagesDao - .getMessagesByMediaUploadId(fileId); + List messages = + await twonlyDB.messagesDao.getMessagesByMediaUploadId(fileId); bool canBeDeleted = true; for (final message in messages) { @@ -319,7 +319,7 @@ Future purgeMediaFiles(Directory directory) async { file.deleteSync(); } } else { - Message? message = await twonlyDatabase.messagesDao + Message? message = await twonlyDB.messagesDao .getMessageByMessageId(fileId) .getSingleOrNull(); if ((message == null) || diff --git a/lib/src/providers/api/media_send.dart b/lib/src/services/api/media_send.dart similarity index 92% rename from lib/src/providers/api/media_send.dart rename to lib/src/services/api/media_send.dart index 8576f32..8e2ed18 100644 --- a/lib/src/providers/api/media_send.dart +++ b/lib/src/services/api/media_send.dart @@ -18,10 +18,10 @@ import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/model/json/message.dart'; import 'package:twonly/src/model/protobuf/api/error.pb.dart'; import 'package:twonly/src/model/protobuf/api/server_to_client.pb.dart'; -import 'package:twonly/src/providers/api/api.dart'; -import 'package:twonly/src/providers/api/api_utils.dart'; -import 'package:twonly/src/providers/api/media_received.dart'; -import 'package:twonly/src/services/notification_service.dart'; +import 'package:twonly/src/services/api/messages.dart'; +import 'package:twonly/src/services/api/utils.dart'; +import 'package:twonly/src/services/api/media_received.dart'; +import 'package:twonly/src/services/notification.service.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/storage.dart'; import 'package:video_compress/video_compress.dart'; @@ -66,8 +66,7 @@ Future isAllowedToSend() async { final lockingHandleMediaFile = Mutex(); Future retryMediaUpload({int maxRetries = 3}) async { await lockingHandleMediaFile.protect(() async { - final mediaFiles = - await twonlyDatabase.mediaUploadsDao.getMediaUploadsForRetry(); + final mediaFiles = await twonlyDB.mediaUploadsDao.getMediaUploadsForRetry(); if (mediaFiles.isEmpty) return; for (final mediaFile in mediaFiles) { if (mediaFile.messageIds == null || mediaFile.metadata == null) { @@ -75,9 +74,9 @@ Future retryMediaUpload({int maxRetries = 3}) async { if (mediaFile.uploadTokens != null) { /// the file was already uploaded. /// notify the server to remove the upload - apiProvider.getDownloadTokens(mediaFile.uploadTokens!.uploadToken, 0); + apiService.getDownloadTokens(mediaFile.uploadTokens!.uploadToken, 0); } - await twonlyDatabase.mediaUploadsDao + await twonlyDB.mediaUploadsDao .deleteMediaUpload(mediaFile.mediaUploadId); Logger("media_send.dart").shout( "upload can be removed, the finalized function was never called..."); @@ -94,7 +93,7 @@ Future retryMediaUpload({int maxRetries = 3}) async { } Future initMediaUpload() async { - return await twonlyDatabase.mediaUploadsDao + return await twonlyDB.mediaUploadsDao .insertMediaUpload(MediaUploadsCompanion()); } @@ -133,7 +132,7 @@ Future addOrModifyImageToUpload( /// in case the media file was already encrypted of even uploaded /// remove the data so it will be done again. /// TODO: when the uploadTokens are already set notify the server... - await twonlyDatabase.mediaUploadsDao.updateMediaUpload( + await twonlyDB.mediaUploadsDao.updateMediaUpload( mediaUploadId, MediaUploadsCompanion( encryptionData: Value(null), @@ -195,7 +194,7 @@ Future encryptAndPreUploadMediaFiles( encryptedBytes, ); - await twonlyDatabase.mediaUploadsDao.updateMediaUpload( + await twonlyDB.mediaUploadsDao.updateMediaUpload( mediaUploadId, MediaUploadsCompanion( state: Value(UploadState.readyToUpload), @@ -206,7 +205,7 @@ Future encryptAndPreUploadMediaFiles( } Future cancelSendMediaFile(int mediaUploadId) async { - await twonlyDatabase.mediaUploadsDao.deleteMediaUpload(mediaUploadId); + await twonlyDB.mediaUploadsDao.deleteMediaUpload(mediaUploadId); /// server should purge the uploads... when it did not receive a } @@ -224,7 +223,7 @@ Future finalizeUpload(int mediaUploadId, List contactIds, List messageIds = []; for (final contactId in contactIds) { - int? messageId = await twonlyDatabase.messagesDao.insertMessage( + int? messageId = await twonlyDB.messagesDao.insertMessage( MessagesCompanion( contactId: Value(contactId), kind: Value(MessageKind.media), @@ -244,7 +243,7 @@ Future finalizeUpload(int mediaUploadId, List contactIds, ), ); // de-archive contact when sending a new message - await twonlyDatabase.contactsDao.updateContact( + await twonlyDB.contactsDao.updateContact( contactId, ContactsCompanion( archived: Value(false), @@ -258,7 +257,7 @@ Future finalizeUpload(int mediaUploadId, List contactIds, } } - await twonlyDatabase.mediaUploadsDao.updateMediaUpload( + await twonlyDB.mediaUploadsDao.updateMediaUpload( mediaUploadId, MediaUploadsCompanion( messageIds: Value(messageIds), @@ -270,7 +269,7 @@ Future finalizeUpload(int mediaUploadId, List contactIds, final lockingHandleNextMediaUploadStep = Mutex(); Future handleNextMediaUploadSteps(int mediaUploadId) async { bool rerun = await lockingHandleNextMediaUploadStep.protect(() async { - var mediaUpload = await twonlyDatabase.mediaUploadsDao + var mediaUpload = await twonlyDB.mediaUploadsDao .getMediaUploadById(mediaUploadId) .getSingleOrNull(); @@ -328,7 +327,7 @@ Future handleUploadError(MediaUpload mediaUpload) async { // if the messageIds are already there notify the user about this error... if (mediaUpload.messageIds != null) { for (int messageId in mediaUpload.messageIds!) { - await twonlyDatabase.messagesDao.updateMessageByMessageId( + await twonlyDB.messagesDao.updateMessageByMessageId( messageId, MessagesCompanion( errorWhileSending: Value(true), @@ -336,12 +335,11 @@ Future handleUploadError(MediaUpload mediaUpload) async { ); } } - await twonlyDatabase.mediaUploadsDao - .deleteMediaUpload(mediaUpload.mediaUploadId); + await twonlyDB.mediaUploadsDao.deleteMediaUpload(mediaUpload.mediaUploadId); } Future handleUploadDone(MediaUpload media) async { - Result res = await apiProvider.getDownloadTokens( + Result res = await apiService.getDownloadTokens( media.uploadTokens!.uploadToken, media.messageIds!.length); if (res.isError || !res.value.hasDownloadtokens()) { @@ -363,7 +361,7 @@ Future handleUploadDone(MediaUpload media) async { token.uploadToken = media.uploadTokens!.uploadToken; token.downloadTokens = tokens.downloadTokens; - await twonlyDatabase.mediaUploadsDao.updateMediaUpload( + await twonlyDB.mediaUploadsDao.updateMediaUpload( media.mediaUploadId, MediaUploadsCompanion( uploadTokens: Value(token), @@ -383,7 +381,7 @@ Future handleMediaUpload(int mediaUploadId) async { } String apiUrl = - "http${apiProvider.apiSecure}://${apiProvider.apiHost}/api/upload"; + "http${apiService.apiSecure}://${apiService.apiHost}/api/upload"; var requestMultipart = http.MultipartRequest( "POST", @@ -415,7 +413,7 @@ Future handleMediaUpload(int mediaUploadId) async { token.uploadToken = uploadToken; token.downloadTokens = []; - await twonlyDatabase.mediaUploadsDao.updateMediaUpload( + await twonlyDB.mediaUploadsDao.updateMediaUpload( mediaUploadId, MediaUploadsCompanion( uploadTokens: Value(token), @@ -439,12 +437,12 @@ Future handleNotifyReceiver(MediaUpload media) async { continue; } - Message? message = await twonlyDatabase.messagesDao + Message? message = await twonlyDB.messagesDao .getMessageByMessageId(messageId) .getSingleOrNull(); if (message == null) continue; - await twonlyDatabase.contactsDao.incFlameCounter( + await twonlyDB.contactsDao.incFlameCounter( message.contactId, false, message.sendAt, @@ -477,7 +475,7 @@ Future handleNotifyReceiver(MediaUpload media) async { ); alreadyNotified.add(messageId); - await twonlyDatabase.mediaUploadsDao.updateMediaUpload( + await twonlyDB.mediaUploadsDao.updateMediaUpload( media.mediaUploadId, MediaUploadsCompanion( alreadyNotified: Value(alreadyNotified), @@ -485,7 +483,7 @@ Future handleNotifyReceiver(MediaUpload media) async { ); } - await twonlyDatabase.mediaUploadsDao.updateMediaUpload( + await twonlyDB.mediaUploadsDao.updateMediaUpload( media.mediaUploadId, MediaUploadsCompanion( state: Value(UploadState.receiverNotified), diff --git a/lib/src/providers/api/api.dart b/lib/src/services/api/messages.dart similarity index 91% rename from lib/src/providers/api/api.dart rename to lib/src/services/api/messages.dart index 9e3e25d..7fa2b3f 100644 --- a/lib/src/providers/api/api.dart +++ b/lib/src/services/api/messages.dart @@ -9,9 +9,9 @@ import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/database/tables/messages_table.dart'; import 'package:twonly/src/model/json/message.dart'; import 'package:twonly/src/model/json/userdata.dart'; -import 'package:twonly/src/providers/api/api_utils.dart'; -import 'package:twonly/src/providers/hive.dart'; -import 'package:twonly/src/services/notification_service.dart'; +import 'package:twonly/src/services/api/utils.dart'; +import 'package:twonly/src/utils/hive.dart'; +import 'package:twonly/src/services/notification.service.dart'; // ignore: library_prefixes import 'package:twonly/src/utils/signal.dart' as SignalHelper; import 'package:twonly/src/utils/storage.dart'; @@ -35,7 +35,7 @@ Future tryTransmitMessages() async { RetransmitMessage msg = RetransmitMessage.fromJson(jsonDecode(element.value)); - Result resp = await apiProvider.sendTextMessage( + Result resp = await apiService.sendTextMessage( msg.userId, msg.bytes, msg.pushData, @@ -43,7 +43,7 @@ Future tryTransmitMessages() async { if (resp.isSuccess) { if (msg.messageId != null) { - await twonlyDatabase.messagesDao.updateMessageByMessageId( + await twonlyDB.messagesDao.updateMessageByMessageId( msg.messageId!, MessagesCompanion( acknowledgeByServer: Value(true), @@ -113,7 +113,7 @@ Future> getAllMessagesForRetransmitting() async { Future sendRetransmitMessage( String stateId, RetransmitMessage msg) async { Result resp = - await apiProvider.sendTextMessage(msg.userId, msg.bytes, msg.pushData); + await apiService.sendTextMessage(msg.userId, msg.bytes, msg.pushData); if (resp.isSuccess) { { @@ -123,7 +123,7 @@ Future sendRetransmitMessage( box.put("messages-to-retransmit", jsonEncode(retransmit)); } if (msg.messageId != null) { - await twonlyDatabase.messagesDao.updateMessageByMessageId( + await twonlyDB.messagesDao.updateMessageByMessageId( msg.messageId!, MessagesCompanion(acknowledgeByServer: Value(true)), ); @@ -195,7 +195,7 @@ Future sendTextMessage( int target, TextMessageContent content, PushKind? pushKind) async { DateTime messageSendAt = DateTime.now(); - int? messageId = await twonlyDatabase.messagesDao.insertMessage( + int? messageId = await twonlyDB.messagesDao.insertMessage( MessagesCompanion( contactId: Value(target), kind: Value(MessageKind.textMessage), @@ -239,7 +239,7 @@ Future notifyContactAboutOpeningMessage( Future notifyContactsAboutProfileChange() async { List contacts = - await twonlyDatabase.contactsDao.getAllNotBlockedContacts(); + await twonlyDB.contactsDao.getAllNotBlockedContacts(); UserData? user = await getUser(); if (user == null) return; @@ -248,7 +248,7 @@ Future notifyContactsAboutProfileChange() async { for (Contact contact in contacts) { if (contact.myAvatarCounter < user.avatarCounter!) { - twonlyDatabase.contactsDao.updateContact(contact.userId, + twonlyDB.contactsDao.updateContact(contact.userId, ContactsCompanion(myAvatarCounter: Value(user.avatarCounter!))); await encryptAndSendMessageAsync( null, diff --git a/lib/src/providers/api/server_messages.dart b/lib/src/services/api/server_messages.dart similarity index 86% rename from lib/src/providers/api/server_messages.dart rename to lib/src/services/api/server_messages.dart index c6efc79..4123e00 100644 --- a/lib/src/providers/api/server_messages.dart +++ b/lib/src/services/api/server_messages.dart @@ -14,10 +14,10 @@ import 'package:twonly/src/model/protobuf/api/client_to_server.pbserver.dart'; import 'package:twonly/src/model/protobuf/api/error.pb.dart'; import 'package:twonly/src/model/protobuf/api/server_to_client.pb.dart' as server; -import 'package:twonly/src/providers/api/api.dart'; -import 'package:twonly/src/providers/api/api_utils.dart'; -import 'package:twonly/src/providers/api/media_received.dart'; -import 'package:twonly/src/services/notification_service.dart'; +import 'package:twonly/src/services/api/messages.dart'; +import 'package:twonly/src/services/api/utils.dart'; +import 'package:twonly/src/services/api/media_received.dart'; +import 'package:twonly/src/services/notification.service.dart'; import 'package:twonly/src/utils/misc.dart'; // ignore: library_prefixes import 'package:twonly/src/utils/signal.dart' as SignalHelper; @@ -48,7 +48,7 @@ Future handleServerMessage(server.ServerToClient msg) async { ..seq = msg.v0.seq ..response = response; - apiProvider.sendResponse(ClientToServer()..v0 = v0); + apiService.sendResponse(ClientToServer()..v0 = v0); }); } @@ -67,7 +67,7 @@ Future handleNewMessage(int fromUserId, Uint8List body) async { return handleContactRequest(fromUserId, message); case MessageKind.flameSync: - Contact? contact = await twonlyDatabase.contactsDao + Contact? contact = await twonlyDB.contactsDao .getContactByUserId(fromUserId) .getSingleOrNull(); if (contact != null && contact.lastFlameCounterChange != null) { @@ -85,23 +85,23 @@ Future handleNewMessage(int fromUserId, Uint8List body) async { ); } } - await twonlyDatabase.contactsDao.updateContact(fromUserId, updates); + await twonlyDB.contactsDao.updateContact(fromUserId, updates); } } case MessageKind.opened: final update = MessagesCompanion(openedAt: Value(message.timestamp)); - await twonlyDatabase.messagesDao.updateMessageByOtherUser( + await twonlyDB.messagesDao.updateMessageByOtherUser( fromUserId, message.messageId!, update, ); - final openedMessage = await twonlyDatabase.messagesDao + final openedMessage = await twonlyDB.messagesDao .getMessageByMessageId(message.messageId!) .getSingleOrNull(); if (openedMessage != null && openedMessage.kind == MessageKind.textMessage) { - await twonlyDatabase.messagesDao.openedAllNonMediaMessagesFromOtherUser( + await twonlyDB.messagesDao.openedAllNonMediaMessagesFromOtherUser( fromUserId, ); } @@ -109,12 +109,12 @@ Future handleNewMessage(int fromUserId, Uint8List body) async { break; case MessageKind.rejectRequest: - await twonlyDatabase.contactsDao.deleteContactByUserId(fromUserId); + await twonlyDB.contactsDao.deleteContactByUserId(fromUserId); break; case MessageKind.acceptRequest: final update = ContactsCompanion(accepted: Value(true)); - await twonlyDatabase.contactsDao.updateContact(fromUserId, update); + await twonlyDB.contactsDao.updateContact(fromUserId, update); notifyContactsAboutProfileChange(); break; @@ -125,7 +125,7 @@ Future handleNewMessage(int fromUserId, Uint8List body) async { avatarSvg: Value(content.avatarSvg), displayName: Value(content.displayName), ); - twonlyDatabase.contactsDao.updateContact(fromUserId, update); + twonlyDB.contactsDao.updateContact(fromUserId, update); } break; @@ -134,7 +134,7 @@ Future handleNewMessage(int fromUserId, Uint8List body) async { acknowledgeByUser: Value(true), errorWhileSending: Value(false), ); - await twonlyDatabase.messagesDao.updateMessageByOtherUser( + await twonlyDB.messagesDao.updateMessageByOtherUser( fromUserId, message.messageId!, update, @@ -164,7 +164,7 @@ Future handleNewMessage(int fromUserId, Uint8List body) async { if (content is StoredMediaFileContent) { /// stored media file just updates the message - await twonlyDatabase.messagesDao.updateMessageByOtherUser( + await twonlyDB.messagesDao.updateMessageByOtherUser( fromUserId, content.messageId, MessagesCompanion( @@ -173,7 +173,7 @@ Future handleNewMessage(int fromUserId, Uint8List body) async { ); } else { // when a message is received doubled ignore it... - if ((await twonlyDatabase.messagesDao + if ((await twonlyDB.messagesDao .containsOtherMessageId(fromUserId, message.messageId!))) { var ok = client.Response_Ok()..none = true; return client.Response()..ok = ok; @@ -216,7 +216,7 @@ Future handleNewMessage(int fromUserId, Uint8List body) async { sendAt: Value(message.timestamp), ); - messageId = await twonlyDatabase.messagesDao.insertMessage( + messageId = await twonlyDB.messagesDao.insertMessage( update, ); @@ -224,13 +224,13 @@ Future handleNewMessage(int fromUserId, Uint8List body) async { return client.Response()..error = ErrorCode.InternalError; } if (message.kind == MessageKind.media) { - twonlyDatabase.contactsDao.incFlameCounter( + twonlyDB.contactsDao.incFlameCounter( fromUserId, true, message.timestamp, ); - final msg = await twonlyDatabase.messagesDao + final msg = await twonlyDB.messagesDao .getMessageByMessageId(messageId) .getSingleOrNull(); if (msg != null) { @@ -251,7 +251,7 @@ Future handleNewMessage(int fromUserId, Uint8List body) async { ); // unarchive contact when receiving a new message - await twonlyDatabase.contactsDao.updateContact( + await twonlyDB.contactsDao.updateContact( fromUserId, ContactsCompanion( archived: Value(false), @@ -281,10 +281,10 @@ Future handleContactRequest( int fromUserId, MessageJson message) async { // request the username by the server so an attacker can not // forge the displayed username in the contact request - Result username = await apiProvider.getUsername(fromUserId); + Result username = await apiService.getUsername(fromUserId); if (username.isSuccess) { Uint8List name = username.value.userdata.username; - await twonlyDatabase.contactsDao.insertContact( + await twonlyDB.contactsDao.insertContact( ContactsCompanion( username: Value(utf8.decode(name)), userId: Value(fromUserId), diff --git a/lib/src/providers/api/api_utils.dart b/lib/src/services/api/utils.dart similarity index 100% rename from lib/src/providers/api/api_utils.dart rename to lib/src/services/api/utils.dart diff --git a/lib/src/services/fcm_service.dart b/lib/src/services/fcm.service.dart similarity index 92% rename from lib/src/services/fcm_service.dart rename to lib/src/services/fcm.service.dart index f43867b..fafbb0b 100644 --- a/lib/src/services/fcm_service.dart +++ b/lib/src/services/fcm.service.dart @@ -5,8 +5,8 @@ import 'package:logging/logging.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/app.dart'; import 'package:twonly/src/database/twonly_database.dart'; -import 'package:twonly/src/services/notification_service.dart'; -import 'package:twonly/src/utils/misc.dart'; +import 'package:twonly/src/services/notification.service.dart'; +import 'package:twonly/src/utils/log.dart'; import 'dart:io' show Platform; import '../../firebase_options.dart'; @@ -27,12 +27,12 @@ Future initFCMAfterAuthenticated() async { } if (storedToken == null || fcmToken != storedToken) { - await apiProvider.updateFCMToken(fcmToken); + await apiService.updateFCMToken(fcmToken); await storage.write(key: "google_fcm", value: fcmToken); } FirebaseMessaging.instance.onTokenRefresh.listen((fcmToken) async { - await apiProvider.updateFCMToken(fcmToken); + await apiService.updateFCMToken(fcmToken); await storage.write(key: "google_fcm", value: fcmToken); }).onError((err) { // Logger("init_fcm_service").shout("Error getting fcmToken"); @@ -78,10 +78,10 @@ Future initFCMService() async { @pragma('vm:entry-point') Future _firebaseMessagingBackgroundHandler(RemoteMessage message) async { - setupLogger(); + initLogger(); Logger("firebase-background") .info('Handling a background message: ${message.messageId}'); - twonlyDatabase = TwonlyDatabase(); + twonlyDB = TwonlyDatabase(); await handleRemoteMessage(message); // make sure every thing run... diff --git a/lib/src/services/flame_service.dart b/lib/src/services/flame.service.dart similarity index 91% rename from lib/src/services/flame_service.dart rename to lib/src/services/flame.service.dart index b69dce2..d350683 100644 --- a/lib/src/services/flame_service.dart +++ b/lib/src/services/flame.service.dart @@ -4,7 +4,7 @@ import 'package:twonly/globals.dart'; import 'package:twonly/src/database/daos/contacts_dao.dart'; import 'package:twonly/src/database/tables/messages_table.dart'; import 'package:twonly/src/database/twonly_database.dart'; -import 'package:twonly/src/providers/api/api.dart'; +import 'package:twonly/src/services/api/messages.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/model/json/message.dart' as my; @@ -14,7 +14,7 @@ Future syncFlameCounters() async { if (user == null) return; List contacts = - await twonlyDatabase.contactsDao.getAllNotBlockedContacts(); + await twonlyDB.contactsDao.getAllNotBlockedContacts(); if (contacts.isEmpty) return; int maxMessageCounter = contacts.map((x) => x.totalMediaCounter).max; Contact bestFriend = @@ -50,7 +50,7 @@ Future syncFlameCounters() async { ), ); - await twonlyDatabase.contactsDao.updateContact( + await twonlyDB.contactsDao.updateContact( contact.userId, ContactsCompanion( lastFlameSync: Value(DateTime.now()), diff --git a/lib/src/services/notification_service.dart b/lib/src/services/notification.service.dart similarity index 99% rename from lib/src/services/notification_service.dart rename to lib/src/services/notification.service.dart index 8076e9c..74f739d 100644 --- a/lib/src/services/notification_service.dart +++ b/lib/src/services/notification.service.dart @@ -15,7 +15,7 @@ import 'package:twonly/src/database/daos/contacts_dao.dart'; import 'package:twonly/src/database/tables/messages_table.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/model/json/message.dart' as my; -import 'package:twonly/src/providers/api/api.dart'; +import 'package:twonly/src/services/api/messages.dart'; class PushUser { String displayName; @@ -83,7 +83,7 @@ Future setupNotificationWithUsers({bool force = false}) async { final random = Random.secure(); - final contacts = await twonlyDatabase.contactsDao.getAllNotBlockedContacts(); + final contacts = await twonlyDB.contactsDao.getAllNotBlockedContacts(); for (final contact in contacts) { if (pushKeys.containsKey(contact.userId)) { // make it harder to predict the change of the key @@ -427,7 +427,7 @@ Future showLocalPushNotification( String? title; String? body; - Contact? user = await twonlyDatabase.contactsDao + Contact? user = await twonlyDB.contactsDao .getContactByUserId(fromUserId) .getSingleOrNull(); diff --git a/lib/src/providers/hive.dart b/lib/src/utils/hive.dart similarity index 94% rename from lib/src/providers/hive.dart rename to lib/src/utils/hive.dart index e8f463e..053cf5f 100644 --- a/lib/src/providers/hive.dart +++ b/lib/src/utils/hive.dart @@ -3,7 +3,7 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:hive/hive.dart'; import 'package:logging/logging.dart'; import 'package:path_provider/path_provider.dart'; -import 'package:twonly/src/services/notification_service.dart'; +import 'package:twonly/src/services/notification.service.dart'; Future initMediaStorage() async { final storage = FlutterSecureStorage(); diff --git a/lib/src/utils/log.dart b/lib/src/utils/log.dart new file mode 100644 index 0000000..b1bb7bb --- /dev/null +++ b/lib/src/utils/log.dart @@ -0,0 +1,61 @@ +import 'dart:io'; +import 'package:flutter/foundation.dart'; +import 'package:logging/logging.dart'; +import 'package:path_provider/path_provider.dart'; + +void initLogger() { + Logger.root.level = kReleaseMode ? Level.INFO : Level.ALL; + Logger.root.onRecord.listen((record) async { + await _writeLogToFile(record); + if (kDebugMode) { + print( + '${record.level.name} [twonly] ${record.loggerName} > ${record.message}'); + } + }); +} + +class Log { + static void error(Object? message, [Object? error, StackTrace? stackTrace]) { + Logger(_getCallerSourceCodeFilename()).shout(message, error, stackTrace); + } + + static void warn(Object? message, [Object? error, StackTrace? stackTrace]) { + Logger(_getCallerSourceCodeFilename()).warning(message, error, stackTrace); + } + + static void info(Object? message, [Object? error, StackTrace? stackTrace]) { + Logger(_getCallerSourceCodeFilename()).fine(message, error, stackTrace); + } +} + +Future _writeLogToFile(LogRecord record) async { + final directory = await getApplicationSupportDirectory(); + final logFile = File('${directory.path}/app.log'); + + // Prepare the log message + final logMessage = + '${DateTime.now()} ${record.level.name} [twonly] ${record.loggerName} > ${record.message}\n'; + + // Append the log message to the file + await logFile.writeAsString(logMessage, mode: FileMode.append); +} + +String _getCallerSourceCodeFilename() { + StackTrace stackTrace = StackTrace.current; + String stackTraceString = stackTrace.toString(); + String fileName = ""; + String lineNumber = ""; + List stackLines = stackTraceString.split('\n'); + if (stackLines.length > 2) { + String callerInfo = stackLines[2]; + List parts = callerInfo.split('/'); + fileName = parts.last.split(':').first; // Extract the file name + lineNumber = parts.last.split(':')[1]; // Extract the line number + } else { + String firstLine = stackTraceString.split('\n')[0]; + fileName = + firstLine.split('/').last.split(':').first; // Extract the file name + lineNumber = firstLine.split(':')[1]; // Extract the line number + } + return '$fileName:$lineNumber'; +} diff --git a/lib/src/utils/misc.dart b/lib/src/utils/misc.dart index 7e952e9..8480e07 100644 --- a/lib/src/utils/misc.dart +++ b/lib/src/utils/misc.dart @@ -6,13 +6,12 @@ import 'package:flutter/services.dart'; import 'package:flutter_image_compress/flutter_image_compress.dart'; import 'package:gal/gal.dart'; import 'package:local_auth/local_auth.dart'; -import 'package:logging/logging.dart'; import 'package:path_provider/path_provider.dart'; import 'package:provider/provider.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/model/protobuf/api/error.pb.dart'; import 'package:twonly/src/localization/generated/app_localizations.dart'; -import 'package:twonly/src/providers/settings_change_provider.dart'; +import 'package:twonly/src/providers/settings.provider.dart'; extension ShortCutsExtension on BuildContext { AppLocalizations get lang => AppLocalizations.of(this)!; @@ -20,18 +19,6 @@ extension ShortCutsExtension on BuildContext { ColorScheme get color => Theme.of(this).colorScheme; } -Future writeLogToFile(LogRecord record) async { - final directory = await getApplicationSupportDirectory(); - final logFile = File('${directory.path}/app.log'); - - // Prepare the log message - final logMessage = - '${DateTime.now()}: ${record.level.name}: ${record.loggerName}: ${record.message}\n'; - - // Append the log message to the file - await logFile.writeAsString(logMessage, mode: FileMode.append); -} - Future deleteLogFile() async { final directory = await getApplicationSupportDirectory(); final logFile = File('${directory.path}/app.log'); @@ -165,17 +152,6 @@ Future authenticateUser(String localizedReason, return false; } -void setupLogger() { - Logger.root.level = kReleaseMode ? Level.INFO : Level.ALL; - Logger.root.onRecord.listen((record) async { - await writeLogToFile(record); - if (kDebugMode) { - print( - '${record.level.name}: twonly:${record.loggerName}: ${record.message}'); - } - }); -} - Uint8List intToBytes(int value) { final byteData = ByteData(4); byteData.setInt32(0, value, Endian.big); diff --git a/lib/src/utils/signal.dart b/lib/src/utils/signal.dart index 52c5de1..b2cca2d 100644 --- a/lib/src/utils/signal.dart +++ b/lib/src/utils/signal.dart @@ -8,7 +8,7 @@ import 'package:twonly/src/model/json/message.dart'; import 'package:twonly/src/model/json/signal_identity.dart'; import 'package:twonly/src/model/json/userdata.dart'; import 'package:twonly/src/model/protobuf/api/server_to_client.pb.dart'; -import 'package:twonly/src/providers/signal/connect_signal_protocol_store.dart'; +import 'package:twonly/src/database/signal/connect_signal_protocol_store.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/storage.dart'; diff --git a/lib/src/views/camera/camera_preview_components/camera_preview.dart b/lib/src/views/camera/camera_preview_components/camera_preview.dart index 25760fb..e5be556 100644 --- a/lib/src/views/camera/camera_preview_components/camera_preview.dart +++ b/lib/src/views/camera/camera_preview_components/camera_preview.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'package:screenshot/screenshot.dart'; import 'package:twonly/src/views/camera/camera_send_to_view.dart'; import 'package:twonly/src/views/components/media_view_sizing.dart'; -import 'package:twonly/src/views/home_view.dart'; +import 'package:twonly/src/views/home.view.dart'; class HomeViewCameraPreview extends StatefulWidget { const HomeViewCameraPreview({ diff --git a/lib/src/views/camera/camera_preview_components/save_to_gallery.dart b/lib/src/views/camera/camera_preview_components/save_to_gallery.dart index 875e428..22c3769 100644 --- a/lib/src/views/camera/camera_preview_components/save_to_gallery.dart +++ b/lib/src/views/camera/camera_preview_components/save_to_gallery.dart @@ -3,7 +3,7 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:path/path.dart'; -import 'package:twonly/src/providers/api/media_send.dart'; +import 'package:twonly/src/services/api/media_send.dart'; import 'dart:typed_data'; import 'package:twonly/src/utils/misc.dart'; diff --git a/lib/src/views/camera/camera_preview_controller_view.dart b/lib/src/views/camera/camera_preview_controller_view.dart index aef04c8..fb4c903 100644 --- a/lib/src/views/camera/camera_preview_controller_view.dart +++ b/lib/src/views/camera/camera_preview_controller_view.dart @@ -21,7 +21,7 @@ import 'package:twonly/src/views/components/media_view_sizing.dart'; import 'package:twonly/src/views/camera/camera_preview_components/permissions_view.dart'; import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/views/camera/share_image_editor_view.dart'; -import 'package:twonly/src/views/home_view.dart'; +import 'package:twonly/src/views/home.view.dart'; int maxVideoRecordingTime = 15; 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 83da2dc..a504b73 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 @@ -27,7 +27,7 @@ class _LocationFilterState extends State { } Future initAsync() async { - final res = await apiProvider.getCurrentLocation(); + final res = await apiService.getCurrentLocation(); if (res.isSuccess) { location = res.value.location; _searchForImage(); diff --git a/lib/src/views/camera/share_image_components/best_friends_selector.dart b/lib/src/views/camera/share_image_components/best_friends_selector.dart index 855611f..06fb5b1 100644 --- a/lib/src/views/camera/share_image_components/best_friends_selector.dart +++ b/lib/src/views/camera/share_image_components/best_friends_selector.dart @@ -170,8 +170,7 @@ class UserCheckbox extends StatelessWidget { ], ), StreamBuilder( - stream: twonlyDatabase.contactsDao - .watchFlameCounter(user.userId), + stream: twonlyDB.contactsDao.watchFlameCounter(user.userId), builder: (context, snapshot) { if (!snapshot.hasData || snapshot.data! == 0) { return Container(); diff --git a/lib/src/views/camera/share_image_editor_view.dart b/lib/src/views/camera/share_image_editor_view.dart index 34ba504..35da02f 100644 --- a/lib/src/views/camera/share_image_editor_view.dart +++ b/lib/src/views/camera/share_image_editor_view.dart @@ -6,7 +6,7 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:logging/logging.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/model/protobuf/api/error.pb.dart' show ErrorCode; -import 'package:twonly/src/providers/api/media_send.dart'; +import 'package:twonly/src/services/api/media_send.dart'; import 'package:twonly/src/views/camera/camera_preview_components/save_to_gallery.dart'; import 'package:twonly/src/views/camera/image_editor/action_button.dart'; import 'package:twonly/src/views/components/alert_dialog.dart'; @@ -135,9 +135,8 @@ class _ShareImageEditorView extends State { Future updateAsync(int userId) async { if (sendNextMediaToUserName != null) return; - Contact? contact = await twonlyDatabase.contactsDao - .getContactByUserId(userId) - .getSingleOrNull(); + Contact? contact = + await twonlyDB.contactsDao.getContactByUserId(userId).getSingleOrNull(); if (contact != null) { sendNextMediaToUserName = getContactDisplayName(contact); } diff --git a/lib/src/views/camera/share_image_view.dart b/lib/src/views/camera/share_image_view.dart index ea4c79f..a6241e2 100644 --- a/lib/src/views/camera/share_image_view.dart +++ b/lib/src/views/camera/share_image_view.dart @@ -5,7 +5,7 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/model/protobuf/api/error.pb.dart'; -import 'package:twonly/src/providers/api/media_send.dart'; +import 'package:twonly/src/services/api/media_send.dart'; import 'package:twonly/src/views/camera/share_image_components/best_friends_selector.dart'; import 'package:twonly/src/views/components/flame.dart'; import 'package:twonly/src/views/components/headline.dart'; @@ -60,7 +60,7 @@ class _ShareImageView extends State { super.initState(); Stream> allContacts = - twonlyDatabase.contactsDao.watchContactsForShareView(); + twonlyDB.contactsDao.watchContactsForShareView(); contactSub = allContacts.listen((allContacts) { setState(() { diff --git a/lib/src/views/chats/search_username_view.dart b/lib/src/views/chats/add_new_user.view.dart similarity index 90% rename from lib/src/views/chats/search_username_view.dart rename to lib/src/views/chats/add_new_user.view.dart index fc0f504..847e598 100644 --- a/lib/src/views/chats/search_username_view.dart +++ b/lib/src/views/chats/add_new_user.view.dart @@ -4,31 +4,31 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; -import 'package:twonly/src/providers/connection_provider.dart'; +import 'package:twonly/src/providers/connection.provider.dart'; import 'package:twonly/src/views/components/alert_dialog.dart'; import 'package:twonly/src/database/daos/contacts_dao.dart'; import 'package:twonly/src/database/tables/messages_table.dart'; import 'package:twonly/src/database/twonly_database.dart'; -import 'package:twonly/src/services/notification_service.dart'; +import 'package:twonly/src/services/notification.service.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/views/components/headline.dart'; import 'package:twonly/src/views/components/initialsavatar.dart'; import 'package:twonly/src/model/json/message.dart'; -import 'package:twonly/src/providers/api/api.dart'; +import 'package:twonly/src/services/api/messages.dart'; // ignore: library_prefixes import 'package:twonly/src/utils/signal.dart' as SignalHelper; import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/views/settings/subscription/subscription_view.dart'; -class SearchUsernameView extends StatefulWidget { - const SearchUsernameView({super.key}); +class AddNewUserView extends StatefulWidget { + const AddNewUserView({super.key}); @override - State createState() => _SearchUsernameView(); + State createState() => _SearchUsernameView(); } -class _SearchUsernameView extends State { +class _SearchUsernameView extends State { final TextEditingController searchUserName = TextEditingController(); bool _isLoading = false; bool hasRequestedUsers = false; @@ -50,7 +50,7 @@ class _SearchUsernameView extends State { void initStreams() { contactsStream = - twonlyDatabase.contactsDao.watchNotAcceptedContacts().listen((update) { + twonlyDB.contactsDao.watchNotAcceptedContacts().listen((update) { setState(() { contacts = update; }); @@ -67,7 +67,7 @@ class _SearchUsernameView extends State { _isLoading = true; }); - final res = await apiProvider.getUserData(searchUserName.text); + final res = await apiService.getUserData(searchUserName.text); if (!context.mounted) { return; @@ -83,7 +83,7 @@ class _SearchUsernameView extends State { return; } - int added = await twonlyDatabase.contactsDao.insertContact( + int added = await twonlyDB.contactsDao.insertContact( ContactsCompanion( username: Value(searchUserName.text), userId: Value(res.value.userdata.userId.toInt()), @@ -237,8 +237,7 @@ class _ContactsListViewState extends State { icon: FaIcon(FontAwesomeIcons.boxArchive, size: 15), onPressed: () async { final update = ContactsCompanion(archived: Value(true)); - await twonlyDatabase.contactsDao - .updateContact(contact.userId, update); + await twonlyDB.contactsDao.updateContact(contact.userId, update); }, ), ), @@ -255,8 +254,7 @@ class _ContactsListViewState extends State { color: const Color.fromARGB(164, 244, 67, 54)), onPressed: () async { final update = ContactsCompanion(blocked: Value(true)); - await twonlyDatabase.contactsDao - .updateContact(contact.userId, update); + await twonlyDB.contactsDao.updateContact(contact.userId, update); }, ), ), @@ -265,8 +263,7 @@ class _ContactsListViewState extends State { child: IconButton( icon: Icon(Icons.close, color: Colors.red), onPressed: () async { - await twonlyDatabase.contactsDao - .deleteContactByUserId(contact.userId); + await twonlyDB.contactsDao.deleteContactByUserId(contact.userId); await encryptAndSendMessageAsync( null, contact.userId, @@ -283,8 +280,7 @@ class _ContactsListViewState extends State { icon: Icon(Icons.check, color: Colors.green), onPressed: () async { final update = ContactsCompanion(accepted: Value(true)); - await twonlyDatabase.contactsDao - .updateContact(contact.userId, update); + await twonlyDB.contactsDao.updateContact(contact.userId, update); await encryptAndSendMessageAsync( null, contact.userId, diff --git a/lib/src/views/chats/chat_list_view.dart b/lib/src/views/chats/chat_list.view.dart similarity index 92% rename from lib/src/views/chats/chat_list_view.dart rename to lib/src/views/chats/chat_list.view.dart index ea61c17..bb806bb 100644 --- a/lib/src/views/chats/chat_list_view.dart +++ b/lib/src/views/chats/chat_list.view.dart @@ -2,8 +2,8 @@ import 'dart:async'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:provider/provider.dart'; import 'package:twonly/globals.dart'; -import 'package:twonly/src/providers/api/media_received.dart'; -import 'package:twonly/src/views/components/connection_state.dart'; +import 'package:twonly/src/services/api/media_received.dart'; +import 'package:twonly/src/views/chats/chat_list_components/connection_info.comp.dart'; import 'package:twonly/src/views/components/flame.dart'; import 'package:twonly/src/views/components/initialsavatar.dart'; import 'package:twonly/src/views/components/message_send_state_icon.dart'; @@ -12,14 +12,14 @@ import 'package:twonly/src/views/components/user_context_menu.dart'; import 'package:twonly/src/database/daos/contacts_dao.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/database/tables/messages_table.dart'; -import 'package:twonly/src/providers/connection_provider.dart'; +import 'package:twonly/src/providers/connection.provider.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/views/camera/camera_send_to_view.dart'; -import 'package:twonly/src/views/chats/chat_messages_view.dart'; -import 'package:twonly/src/views/chats/media_viewer_view.dart'; -import 'package:twonly/src/views/chats/start_new_chat.dart'; +import 'package:twonly/src/views/chats/chat_messages.view.dart'; +import 'package:twonly/src/views/chats/media_viewer.view.dart'; +import 'package:twonly/src/views/chats/start_new_chat.view.dart'; import 'package:twonly/src/views/settings/settings_main_view.dart'; -import 'package:twonly/src/views/chats/search_username_view.dart'; +import 'package:twonly/src/views/chats/add_new_user.view.dart'; import 'package:flutter/material.dart'; import 'package:twonly/src/views/settings/subscription/subscription_view.dart'; @@ -62,7 +62,7 @@ class _ChatListViewState extends State { ]), actions: [ StreamBuilder( - stream: twonlyDatabase.contactsDao.watchContactsRequested(), + stream: twonlyDB.contactsDao.watchContactsRequested(), builder: (context, snapshot) { var count = 0; if (snapshot.hasData && snapshot.data != null) { @@ -76,7 +76,7 @@ class _ChatListViewState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => SearchUsernameView(), + builder: (context) => AddNewUserView(), ), ); }, @@ -107,7 +107,7 @@ class _ChatListViewState extends State { ), Positioned.fill( child: StreamBuilder( - stream: twonlyDatabase.contactsDao.watchContactsForChatList(), + stream: twonlyDB.contactsDao.watchContactsForChatList(), builder: (context, snapshot) { if (!snapshot.hasData || snapshot.data == null) { return Container(); @@ -124,7 +124,7 @@ class _ChatListViewState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => SearchUsernameView(), + builder: (context) => AddNewUserView(), ), ); }, @@ -138,8 +138,8 @@ class _ChatListViewState extends State { return RefreshIndicator( onRefresh: () async { - await apiProvider.close(() {}); - await apiProvider.connect(); + await apiService.close(() {}); + await apiService.connect(); await Future.delayed(Duration(seconds: 1)); }, child: ListView.builder( @@ -196,7 +196,7 @@ class _ChatListViewState extends State { Navigator.push( context, MaterialPageRoute(builder: (context) { - return StartNewChat(); + return StartNewChatView(); }), ); }, @@ -250,13 +250,13 @@ class _UserListItem extends State { } void initStreams() { - lastMessageStream = twonlyDatabase.messagesDao + lastMessageStream = twonlyDB.messagesDao .watchLastMessage(widget.user.userId) .listen((update) { updateState(update, messagesNotOpened); }); - messagesNotOpenedStream = twonlyDatabase.messagesDao + messagesNotOpenedStream = twonlyDB.messagesDao .watchMessageNotOpened(widget.user.userId) .listen((update) { updateState(lastMessages, update); diff --git a/lib/src/views/components/connection_state.dart b/lib/src/views/chats/chat_list_components/connection_info.comp.dart similarity index 100% rename from lib/src/views/components/connection_state.dart rename to lib/src/views/chats/chat_list_components/connection_info.comp.dart diff --git a/lib/src/views/chats/chat_messages_view.dart b/lib/src/views/chats/chat_messages.view.dart similarity index 95% rename from lib/src/views/chats/chat_messages_view.dart rename to lib/src/views/chats/chat_messages.view.dart index af93edf..9a0af4f 100644 --- a/lib/src/views/chats/chat_messages_view.dart +++ b/lib/src/views/chats/chat_messages.view.dart @@ -13,12 +13,12 @@ import 'package:twonly/src/database/daos/contacts_dao.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/database/tables/messages_table.dart'; import 'package:twonly/src/model/json/message.dart'; -import 'package:twonly/src/providers/api/api.dart'; -import 'package:twonly/src/services/notification_service.dart'; +import 'package:twonly/src/services/api/messages.dart'; +import 'package:twonly/src/services/notification.service.dart'; import 'package:twonly/src/views/camera/camera_send_to_view.dart'; import 'package:twonly/src/utils/misc.dart'; -import 'package:twonly/src/views/contact/contact_view.dart'; -import 'package:twonly/src/views/gallery/gallery_item.dart'; +import 'package:twonly/src/views/contact/contact.view.dart'; +import 'package:twonly/src/model/memory_item.model.dart'; Color getMessageColor(Message message) { return (message.messageOtherId == null) @@ -44,7 +44,7 @@ class _ChatMessagesViewState extends State { late StreamSubscription userSub; late StreamSubscription> messageSub; List messages = []; - List galleryItems = []; + List galleryItems = []; Map> textReactionsToMessageId = {}; Map> emojiReactionsToMessageId = {}; Message? responseToMessage; @@ -67,9 +67,9 @@ class _ChatMessagesViewState extends State { } Future initStreams() async { - await twonlyDatabase.messagesDao.removeOldMessages(); + await twonlyDB.messagesDao.removeOldMessages(); Stream contact = - twonlyDatabase.contactsDao.watchContact(widget.contact.userId); + twonlyDB.contactsDao.watchContact(widget.contact.userId); userSub = contact.listen((contact) { setState(() { user = contact; @@ -77,7 +77,7 @@ class _ChatMessagesViewState extends State { }); Stream> msgStream = - twonlyDatabase.messagesDao.watchAllMessagesFrom(widget.contact.userId); + twonlyDB.messagesDao.watchAllMessagesFrom(widget.contact.userId); messageSub = msgStream.listen((msgs) async { // if (!context.mounted) return; if (Platform.isAndroid) { @@ -139,8 +139,7 @@ class _ChatMessagesViewState extends State { widget.contact.userId, openedMessageOtherIds); } - twonlyDatabase.messagesDao - .openedAllNonMediaMessages(widget.contact.userId); + twonlyDB.messagesDao.openedAllNonMediaMessages(widget.contact.userId); setState(() { textReactionsToMessageId = tmpTextReactionsToMessageId; @@ -153,7 +152,7 @@ class _ChatMessagesViewState extends State { .toList() .reversed .toList(); - final items = await GalleryItem.convertFromMessages(filteredMediaFiles); + final items = await MemoryItem.convertFromMessages(filteredMediaFiles); setState(() { galleryItems = items.values.toList(); }); diff --git a/lib/src/views/chats/chat_messages_components/chat_message_entry_components/chat_media_entry.dart b/lib/src/views/chats/chat_messages_components/chat_media_entry.dart similarity index 85% rename from lib/src/views/chats/chat_messages_components/chat_message_entry_components/chat_media_entry.dart rename to lib/src/views/chats/chat_messages_components/chat_media_entry.dart index 7f901a9..1af6a24 100644 --- a/lib/src/views/chats/chat_messages_components/chat_message_entry_components/chat_media_entry.dart +++ b/lib/src/views/chats/chat_messages_components/chat_media_entry.dart @@ -5,11 +5,11 @@ import 'package:twonly/src/views/chats/chat_messages_components/in_chat_media_vi import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/database/tables/messages_table.dart'; import 'package:twonly/src/model/json/message.dart'; -import 'package:twonly/src/providers/api/api.dart'; -import 'package:twonly/src/providers/api/media_received.dart' as received; -import 'package:twonly/src/services/notification_service.dart'; -import 'package:twonly/src/views/chats/media_viewer_view.dart'; -import 'package:twonly/src/views/gallery/gallery_item.dart'; +import 'package:twonly/src/services/api/messages.dart'; +import 'package:twonly/src/services/api/media_received.dart' as received; +import 'package:twonly/src/services/notification.service.dart'; +import 'package:twonly/src/views/chats/media_viewer.view.dart'; +import 'package:twonly/src/model/memory_item.model.dart'; class ChatMediaEntry extends StatelessWidget { const ChatMediaEntry({ @@ -23,7 +23,7 @@ class ChatMediaEntry extends StatelessWidget { final Message message; final Contact contact; final MessageContent content; - final List galleryItems; + final List galleryItems; @override Widget build(BuildContext context) { @@ -52,7 +52,7 @@ class ChatMediaEntry extends StatelessWidget { ), pushKind: PushKind.reopenedMedia, ); - await twonlyDatabase.messagesDao.updateMessageByMessageId( + await twonlyDB.messagesDao.updateMessageByMessageId( message.messageId, MessagesCompanion(openedAt: Value(null)), ); diff --git a/lib/src/views/chats/chat_messages_components/chat_message_entry.dart b/lib/src/views/chats/chat_messages_components/chat_message_entry.dart index 7d731a4..c301623 100644 --- a/lib/src/views/chats/chat_messages_components/chat_message_entry.dart +++ b/lib/src/views/chats/chat_messages_components/chat_message_entry.dart @@ -1,13 +1,13 @@ import 'dart:convert'; import 'package:flutter/material.dart'; -import 'package:twonly/src/views/chats/chat_messages_components/chat_message_entry_components/chat_media_entry.dart'; -import 'package:twonly/src/views/chats/chat_messages_components/chat_message_entry_components/chat_reaction_row.dart'; -import 'package:twonly/src/views/chats/chat_messages_components/chat_message_entry_components/chat_text_entry.dart'; -import 'package:twonly/src/views/chats/chat_messages_components/chat_message_entry_components/chat_text_response_columns.dart'; +import 'package:twonly/src/views/chats/chat_messages_components/chat_media_entry.dart'; +import 'package:twonly/src/views/chats/chat_messages_components/chat_reaction_row.dart'; +import 'package:twonly/src/views/chats/chat_messages_components/chat_text_entry.dart'; +import 'package:twonly/src/views/chats/chat_messages_components/chat_text_response_columns.dart'; import 'package:twonly/src/views/chats/chat_messages_components/sliding_response.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/model/json/message.dart'; -import 'package:twonly/src/views/gallery/gallery_item.dart'; +import 'package:twonly/src/model/memory_item.model.dart'; class ChatListEntry extends StatefulWidget { const ChatListEntry( @@ -25,7 +25,7 @@ class ChatListEntry extends StatefulWidget { final bool lastMessageFromSameUser; final List textReactions; final List otherReactions; - final List galleryItems; + final List galleryItems; final Function(Message) onResponseTriggered; @override diff --git a/lib/src/views/chats/chat_messages_components/chat_message_entry_components/chat_reaction_row.dart b/lib/src/views/chats/chat_messages_components/chat_reaction_row.dart similarity index 100% rename from lib/src/views/chats/chat_messages_components/chat_message_entry_components/chat_reaction_row.dart rename to lib/src/views/chats/chat_messages_components/chat_reaction_row.dart diff --git a/lib/src/views/chats/chat_messages_components/chat_message_entry_components/chat_text_entry.dart b/lib/src/views/chats/chat_messages_components/chat_text_entry.dart similarity index 94% rename from lib/src/views/chats/chat_messages_components/chat_message_entry_components/chat_text_entry.dart rename to lib/src/views/chats/chat_messages_components/chat_text_entry.dart index f0520ba..0e5e876 100644 --- a/lib/src/views/chats/chat_messages_components/chat_message_entry_components/chat_text_entry.dart +++ b/lib/src/views/chats/chat_messages_components/chat_text_entry.dart @@ -1,5 +1,5 @@ import 'package:flutter/material.dart'; -import 'package:twonly/src/views/chats/chat_messages_view.dart'; +import 'package:twonly/src/views/chats/chat_messages.view.dart'; import 'package:twonly/src/views/components/animate_icon.dart'; import 'package:twonly/src/views/components/better_text.dart'; import 'package:twonly/src/database/twonly_database.dart'; diff --git a/lib/src/views/chats/chat_messages_components/chat_message_entry_components/chat_text_response_columns.dart b/lib/src/views/chats/chat_messages_components/chat_text_response_columns.dart similarity index 97% rename from lib/src/views/chats/chat_messages_components/chat_message_entry_components/chat_text_response_columns.dart rename to lib/src/views/chats/chat_messages_components/chat_text_response_columns.dart index 5422b19..4d7aec5 100644 --- a/lib/src/views/chats/chat_messages_components/chat_message_entry_components/chat_text_response_columns.dart +++ b/lib/src/views/chats/chat_messages_components/chat_text_response_columns.dart @@ -1,7 +1,7 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; -import 'package:twonly/src/views/chats/chat_messages_view.dart'; +import 'package:twonly/src/views/chats/chat_messages.view.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/model/json/message.dart'; 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 6c96c75..1543f1e 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 @@ -3,13 +3,13 @@ import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:twonly/globals.dart'; -import 'package:twonly/src/providers/api/media_send.dart' as send; +import 'package:twonly/src/services/api/media_send.dart' as send; import 'package:twonly/src/views/components/message_send_state_icon.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/database/tables/messages_table.dart'; import 'package:twonly/src/model/json/message.dart'; -import 'package:twonly/src/views/gallery/gallery_item.dart'; -import 'package:twonly/src/views/gallery/gallery_photo_view.dart'; +import 'package:twonly/src/model/memory_item.model.dart'; +import 'package:twonly/src/views/memories/memories_photo_slider.view.dart'; import 'package:video_player/video_player.dart'; class InChatMediaViewer extends StatefulWidget { @@ -23,7 +23,7 @@ class InChatMediaViewer extends StatefulWidget { final Message message; final Contact contact; - final List galleryItems; + final List galleryItems; final Color color; @override @@ -60,7 +60,7 @@ class _InChatMediaViewerState extends State { /// image is already show if (widget.message.mediaStored) return; - final stream = twonlyDatabase.messagesDao + final stream = twonlyDB.messagesDao .getMessageByMessageId(widget.message.messageId) .watchSingleOrNull(); messageStream = stream.listen((updated) async { @@ -116,7 +116,7 @@ class _InChatMediaViewerState extends State { Navigator.push( context, MaterialPageRoute( - builder: (context) => GalleryPhotoViewWrapper( + builder: (context) => MemoriesPhotoSliderView( galleryItems: widget.galleryItems, initialIndex: widget.galleryItems.indexWhere((x) => x.id == diff --git a/lib/src/views/chats/media_viewer_view.dart b/lib/src/views/chats/media_viewer.view.dart similarity index 98% rename from lib/src/views/chats/media_viewer_view.dart rename to lib/src/views/chats/media_viewer.view.dart index f4f93f1..168a99c 100644 --- a/lib/src/views/chats/media_viewer_view.dart +++ b/lib/src/views/chats/media_viewer.view.dart @@ -15,9 +15,9 @@ import 'package:twonly/src/views/components/media_view_sizing.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/database/tables/messages_table.dart'; import 'package:twonly/src/model/json/message.dart'; -import 'package:twonly/src/providers/api/api.dart'; -import 'package:twonly/src/providers/api/media_received.dart'; -import 'package:twonly/src/services/notification_service.dart'; +import 'package:twonly/src/services/api/messages.dart'; +import 'package:twonly/src/services/api/media_received.dart'; +import 'package:twonly/src/services/notification.service.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/views/camera/camera_send_to_view.dart'; @@ -90,8 +90,8 @@ class _MediaViewerViewState extends State { } Future asyncLoadNextMedia(bool firstRun) async { - Stream> messages = twonlyDatabase.messagesDao - .watchMediaMessageNotOpened(widget.contact.userId); + Stream> messages = + twonlyDB.messagesDao.watchMediaMessageNotOpened(widget.contact.userId); _subscription = messages.listen((messages) { for (Message msg in messages) { @@ -172,7 +172,7 @@ class _MediaViewerViewState extends State { }); await startDownloadMedia(allMediaFiles.first, true); - final stream = twonlyDatabase.messagesDao + final stream = twonlyDB.messagesDao .getMessageByMessageId(allMediaFiles.first.messageId) .watchSingleOrNull(); downloadStateListener?.cancel(); @@ -216,7 +216,7 @@ class _MediaViewerViewState extends State { [current.messageOtherId!], ); - await twonlyDatabase.messagesDao.updateMessageByMessageId( + await twonlyDB.messagesDao.updateMessageByMessageId( current.messageId, MessagesCompanion(openedAt: Value(DateTime.now())), ); @@ -255,7 +255,7 @@ class _MediaViewerViewState extends State { if ((imageBytes == null && !content.isVideo) || (content.isVideo && videoController == null)) { // When the message should be downloaded but imageBytes are null then a error happened - await twonlyDatabase.messagesDao.updateMessageByMessageId( + await twonlyDB.messagesDao.updateMessageByMessageId( current.messageId, MessagesCompanion( errorWhileSending: Value(true), @@ -304,7 +304,7 @@ class _MediaViewerViewState extends State { setState(() { imageSaving = true; }); - await twonlyDatabase.messagesDao.updateMessageByMessageId( + await twonlyDB.messagesDao.updateMessageByMessageId( allMediaFiles.first.messageId, MessagesCompanion(mediaStored: Value(true)), ); diff --git a/lib/src/views/chats/start_new_chat.dart b/lib/src/views/chats/start_new_chat.view.dart similarity index 91% rename from lib/src/views/chats/start_new_chat.dart rename to lib/src/views/chats/start_new_chat.view.dart index 689abc7..aa94da6 100644 --- a/lib/src/views/chats/start_new_chat.dart +++ b/lib/src/views/chats/start_new_chat.view.dart @@ -10,16 +10,16 @@ import 'package:twonly/src/views/components/user_context_menu.dart'; import 'package:twonly/src/database/daos/contacts_dao.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/utils/misc.dart'; -import 'package:twonly/src/views/chats/chat_messages_view.dart'; -import 'package:twonly/src/views/chats/search_username_view.dart'; +import 'package:twonly/src/views/chats/chat_messages.view.dart'; +import 'package:twonly/src/views/chats/add_new_user.view.dart'; -class StartNewChat extends StatefulWidget { - const StartNewChat({super.key}); +class StartNewChatView extends StatefulWidget { + const StartNewChatView({super.key}); @override - State createState() => _StartNewChat(); + State createState() => _StartNewChatView(); } -class _StartNewChat extends State { +class _StartNewChatView extends State { List contacts = []; List allContacts = []; final TextEditingController searchUserName = TextEditingController(); @@ -30,7 +30,7 @@ class _StartNewChat extends State { super.initState(); Stream> stream = - twonlyDatabase.contactsDao.watchContactsForShareView(); + twonlyDB.contactsDao.watchContactsForShareView(); contactSub = stream.listen((update) { update.sort((a, b) => @@ -133,7 +133,7 @@ class UserList extends StatelessWidget { Navigator.push( context, MaterialPageRoute( - builder: (context) => SearchUsernameView(), + builder: (context) => AddNewUserView(), ), ); }, @@ -168,7 +168,7 @@ class UserList extends StatelessWidget { ? () async { final update = ContactsCompanion(archived: Value(false)); - await twonlyDatabase.contactsDao + await twonlyDB.contactsDao .updateContact(user.userId, update); } : null) diff --git a/lib/src/views/components/user_context_menu.dart b/lib/src/views/components/user_context_menu.dart index 46fbdbb..4ef3cfc 100644 --- a/lib/src/views/components/user_context_menu.dart +++ b/lib/src/views/components/user_context_menu.dart @@ -5,8 +5,8 @@ import 'package:pie_menu/pie_menu.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/utils/misc.dart'; -import 'package:twonly/src/views/chats/chat_messages_view.dart'; -import 'package:twonly/src/views/contact/contact_verify_view.dart'; +import 'package:twonly/src/views/chats/chat_messages.view.dart'; +import 'package:twonly/src/views/contact/contact_verify.view.dart'; class UserContextMenu extends StatefulWidget { final Widget child; @@ -31,7 +31,7 @@ class _UserContextMenuState extends State { onSelect: () async { final update = ContactsCompanion(archived: Value(true)); if (context.mounted) { - await twonlyDatabase.contactsDao + await twonlyDB.contactsDao .updateContact(widget.contact.userId, update); } }, @@ -43,7 +43,7 @@ class _UserContextMenuState extends State { onSelect: () async { final update = ContactsCompanion(archived: Value(false)); if (context.mounted) { - await twonlyDatabase.contactsDao + await twonlyDB.contactsDao .updateContact(widget.contact.userId, update); } }, @@ -82,7 +82,7 @@ class _UserContextMenuState extends State { final update = ContactsCompanion(pinned: Value(!widget.contact.pinned)); if (context.mounted) { - await twonlyDatabase.contactsDao + await twonlyDB.contactsDao .updateContact(widget.contact.userId, update); } }, diff --git a/lib/src/views/components/verified_shield.dart b/lib/src/views/components/verified_shield.dart index 83f2544..780a196 100644 --- a/lib/src/views/components/verified_shield.dart +++ b/lib/src/views/components/verified_shield.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:twonly/src/database/twonly_database.dart'; -import 'package:twonly/src/views/contact/contact_verify_view.dart'; +import 'package:twonly/src/views/contact/contact_verify.view.dart'; class VerifiedShield extends StatelessWidget { final Contact contact; diff --git a/lib/src/views/contact/contact_view.dart b/lib/src/views/contact/contact.view.dart similarity index 94% rename from lib/src/views/contact/contact_view.dart rename to lib/src/views/contact/contact.view.dart index 474b270..30db481 100644 --- a/lib/src/views/contact/contact_view.dart +++ b/lib/src/views/contact/contact.view.dart @@ -9,7 +9,7 @@ import 'package:twonly/src/views/components/verified_shield.dart'; import 'package:flutter/material.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/utils/misc.dart'; -import 'package:twonly/src/views/contact/contact_verify_view.dart'; +import 'package:twonly/src/views/contact/contact_verify.view.dart'; import 'package:twonly/src/database/daos/contacts_dao.dart'; class ContactView extends StatefulWidget { @@ -24,7 +24,7 @@ class ContactView extends StatefulWidget { class _ContactViewState extends State { @override Widget build(BuildContext context) { - Stream contact = twonlyDatabase.contactsDao + Stream contact = twonlyDB.contactsDao .getContactByUserId(widget.userId) .watchSingleOrNull(); @@ -76,8 +76,7 @@ class _ContactViewState extends State { if (context.mounted && nickName != null && nickName != "") { final update = ContactsCompanion(nickName: Value(nickName)); - twonlyDatabase.contactsDao - .updateContact(contact.userId, update); + twonlyDB.contactsDao.updateContact(contact.userId, update); } }, ), @@ -105,7 +104,7 @@ class _ContactViewState extends State { ); if (block) { if (context.mounted) { - await twonlyDatabase.messagesDao + await twonlyDB.messagesDao .deleteMessagesByContactId(contact.userId); } } @@ -125,7 +124,7 @@ class _ContactViewState extends State { if (block) { final update = ContactsCompanion(blocked: Value(true)); if (context.mounted) { - await twonlyDatabase.contactsDao + await twonlyDB.contactsDao .updateContact(contact.userId, update); } if (context.mounted) { diff --git a/lib/src/views/contact/contact_verify_view.dart b/lib/src/views/contact/contact_verify.view.dart similarity index 96% rename from lib/src/views/contact/contact_verify_view.dart rename to lib/src/views/contact/contact_verify.view.dart index 013d1f5..6b21745 100644 --- a/lib/src/views/contact/contact_verify_view.dart +++ b/lib/src/views/contact/contact_verify.view.dart @@ -14,7 +14,6 @@ import 'package:url_launcher/url_launcher.dart'; class ContactVerifyView extends StatefulWidget { const ContactVerifyView(this.contact, {super.key}); - final Contact contact; @override @@ -37,7 +36,7 @@ class _ContactVerifyViewState extends State { @override Widget build(BuildContext context) { - Stream contact = twonlyDatabase.contactsDao + Stream contact = twonlyDB.contactsDao .getContactByUserId(widget.contact.userId) .watchSingleOrNull(); @@ -114,7 +113,7 @@ class _ContactVerifyViewState extends State { child: GestureDetector( onTap: () { launchUrl(Uri.parse( - "https://twonly.eu/faq/security/verify-security-number")); + "https://twonly.eu/en/faq/security/verify-security-number.html")); }, child: Text( "Read more.", @@ -146,7 +145,7 @@ class _ContactVerifyViewState extends State { onPressed: () { final update = ContactsCompanion(verified: Value(false)); - twonlyDatabase.contactsDao + twonlyDB.contactsDao .updateContact(contact.userId, update); }, label: Text( @@ -157,7 +156,7 @@ class _ContactVerifyViewState extends State { icon: FaIcon(FontAwesomeIcons.shieldHeart), onPressed: () { final update = ContactsCompanion(verified: Value(true)); - twonlyDatabase.contactsDao + twonlyDB.contactsDao .updateContact(contact.userId, update); }, label: Text(context.lang.contactVerifyNumberMarkAsVerified), diff --git a/lib/src/views/home_view.dart b/lib/src/views/home.view.dart similarity index 97% rename from lib/src/views/home_view.dart rename to lib/src/views/home.view.dart index ea383e7..5bc1410 100644 --- a/lib/src/views/home_view.dart +++ b/lib/src/views/home.view.dart @@ -7,10 +7,10 @@ import 'package:screenshot/screenshot.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/views/camera/camera_preview_components/camera_preview.dart'; import 'package:twonly/src/views/components/user_context_menu.dart'; -import 'package:twonly/src/services/notification_service.dart'; -import 'package:twonly/src/views/gallery/gallery_main_view.dart'; +import 'package:twonly/src/services/notification.service.dart'; +import 'package:twonly/src/views/memories/memories.view.dart'; import 'camera/camera_preview_controller_view.dart'; -import 'chats/chat_list_view.dart'; +import 'chats/chat_list.view.dart'; import 'package:flutter/material.dart'; Function(int) globalUpdateOfHomeViewPageIndex = (a) {}; @@ -163,7 +163,7 @@ class HomeViewState extends State { children: [ ChatListView(), Container(), - GalleryMainView(), + MemoriesView(), ], ), ), diff --git a/lib/src/views/gallery/gallery_main_view.dart b/lib/src/views/memories/memories.view.dart similarity index 81% rename from lib/src/views/gallery/gallery_main_view.dart rename to lib/src/views/memories/memories.view.dart index c1ac94a..b84b703 100644 --- a/lib/src/views/gallery/gallery_main_view.dart +++ b/lib/src/views/memories/memories.view.dart @@ -1,24 +1,24 @@ import 'dart:async'; import 'dart:io'; import 'package:intl/intl.dart'; -import 'package:twonly/src/providers/api/media_send.dart' as send; +import 'package:twonly/src/services/api/media_send.dart' as send; import 'package:flutter/material.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/database/twonly_database.dart'; -import 'package:twonly/src/views/gallery/gallery_item.dart'; -import 'package:twonly/src/views/gallery/gallery_item_thumbnail.dart'; -import 'package:twonly/src/views/gallery/gallery_photo_view.dart'; +import 'package:twonly/src/model/memory_item.model.dart'; +import 'package:twonly/src/views/memories/memories_item_thumbnail.dart'; +import 'package:twonly/src/views/memories/memories_photo_slider.view.dart'; -class GalleryMainView extends StatefulWidget { - const GalleryMainView({super.key}); +class MemoriesView extends StatefulWidget { + const MemoriesView({super.key}); @override - State createState() => GalleryMainViewState(); + State createState() => MemoriesViewState(); } -class GalleryMainViewState extends State { +class MemoriesViewState extends State { bool verticalGallery = false; - List galleryItems = []; + List galleryItems = []; Map> orderedByMonth = {}; List months = []; bool mounted = true; @@ -37,11 +37,11 @@ class GalleryMainViewState extends State { super.dispose(); } - Future> loadMemoriesDirectory() async { + Future> loadMemoriesDirectory() async { final directoryPath = await send.getMediaBaseFilePath("memories"); final directory = Directory(directoryPath); - List items = []; + List items = []; if (await directory.exists()) { final files = directory.listSync(); @@ -58,7 +58,7 @@ class GalleryMainViewState extends State { break; } final creationDate = await file.lastModified(); - items.add(GalleryItem( + items.add(MemoryItem( id: fileName, messages: [], date: creationDate, @@ -75,10 +75,10 @@ class GalleryMainViewState extends State { Future initAsync() async { messageSub?.cancel(); Stream> msgStream = - twonlyDatabase.messagesDao.getAllStoredMediaFiles(); + twonlyDB.messagesDao.getAllStoredMediaFiles(); messageSub = msgStream.listen((msgs) async { - Map items = await GalleryItem.convertFromMessages(msgs); + Map items = await MemoryItem.convertFromMessages(msgs); // Group items by month orderedByMonth = {}; months = []; @@ -126,7 +126,7 @@ class GalleryMainViewState extends State { itemCount: orderedByMonth[months[index]]!.length, itemBuilder: (context, gIndex) { int gaIndex = orderedByMonth[months[index]]![gIndex]; - return GalleryItemThumbnail( + return MemoriesItemThumbnail( galleryItem: galleryItems[gaIndex], onTap: () { open(context, gaIndex); @@ -144,7 +144,7 @@ class GalleryMainViewState extends State { await Navigator.push( context, MaterialPageRoute( - builder: (context) => GalleryPhotoViewWrapper( + builder: (context) => MemoriesPhotoSliderView( galleryItems: galleryItems, initialIndex: index, scrollDirection: verticalGallery ? Axis.vertical : Axis.horizontal, diff --git a/lib/src/views/gallery/gallery_item_thumbnail.dart b/lib/src/views/memories/memories_item_thumbnail.dart similarity index 86% rename from lib/src/views/gallery/gallery_item_thumbnail.dart rename to lib/src/views/memories/memories_item_thumbnail.dart index e882fb2..afdce4b 100644 --- a/lib/src/views/gallery/gallery_item_thumbnail.dart +++ b/lib/src/views/memories/memories_item_thumbnail.dart @@ -1,22 +1,22 @@ import 'package:flutter/material.dart'; -import 'package:twonly/src/views/gallery/gallery_item.dart'; +import 'package:twonly/src/model/memory_item.model.dart'; import 'package:video_player/video_player.dart'; -class GalleryItemThumbnail extends StatefulWidget { - const GalleryItemThumbnail({ +class MemoriesItemThumbnail extends StatefulWidget { + const MemoriesItemThumbnail({ super.key, required this.galleryItem, required this.onTap, }); - final GalleryItem galleryItem; + final MemoryItem galleryItem; final GestureTapCallback onTap; @override - State createState() => _GalleryItemThumbnailState(); + State createState() => _MemoriesItemThumbnailState(); } -class _GalleryItemThumbnailState extends State { +class _MemoriesItemThumbnailState extends State { VideoPlayerController? _controller; @override diff --git a/lib/src/views/gallery/gallery_photo_view.dart b/lib/src/views/memories/memories_photo_slider.view.dart similarity index 92% rename from lib/src/views/gallery/gallery_photo_view.dart rename to lib/src/views/memories/memories_photo_slider.view.dart index 6338884..0b2ad39 100644 --- a/lib/src/views/gallery/gallery_photo_view.dart +++ b/lib/src/views/memories/memories_photo_slider.view.dart @@ -5,17 +5,17 @@ import 'package:photo_view/photo_view.dart'; import 'package:photo_view/photo_view_gallery.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/database/twonly_database.dart'; -import 'package:twonly/src/providers/api/media_received.dart' as received; -import 'package:twonly/src/providers/api/media_send.dart' as send; +import 'package:twonly/src/services/api/media_received.dart' as received; +import 'package:twonly/src/services/api/media_send.dart' as send; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/views/camera/share_image_editor_view.dart'; import 'package:twonly/src/views/components/alert_dialog.dart'; import 'package:twonly/src/views/components/media_view_sizing.dart'; import 'package:twonly/src/views/components/video_player_wrapper.dart'; -import 'package:twonly/src/views/gallery/gallery_item.dart'; +import 'package:twonly/src/model/memory_item.model.dart'; -class GalleryPhotoViewWrapper extends StatefulWidget { - GalleryPhotoViewWrapper({ +class MemoriesPhotoSliderView extends StatefulWidget { + MemoriesPhotoSliderView({ super.key, this.loadingBuilder, this.backgroundDecoration, @@ -32,16 +32,16 @@ class GalleryPhotoViewWrapper extends StatefulWidget { final dynamic maxScale; final int initialIndex; final PageController pageController; - final List galleryItems; + final List galleryItems; final Axis scrollDirection; @override State createState() { - return _GalleryPhotoViewWrapperState(); + return _MemoriesPhotoSliderViewState(); } } -class _GalleryPhotoViewWrapperState extends State { +class _MemoriesPhotoSliderViewState extends State { late int currentIndex = widget.initialIndex; void onPageChanged(int index) { @@ -60,7 +60,7 @@ class _GalleryPhotoViewWrapperState extends State { widget.galleryItems[currentIndex].imagePath?.deleteSync(); widget.galleryItems[currentIndex].videoPath?.deleteSync(); for (final message in messages) { - await twonlyDatabase.messagesDao.updateMessageByMessageId( + await twonlyDB.messagesDao.updateMessageByMessageId( message.messageId, MessagesCompanion(mediaStored: Value(false)), ); @@ -166,7 +166,7 @@ class _GalleryPhotoViewWrapperState extends State { } PhotoViewGalleryPageOptions _buildItem(BuildContext context, int index) { - final GalleryItem item = widget.galleryItems[index]; + final MemoryItem item = widget.galleryItems[index]; return item.videoPath != null ? PhotoViewGalleryPageOptions.customChild( child: VideoPlayerWrapper( diff --git a/lib/src/views/onboarding/onboarding_view.dart b/lib/src/views/onboarding.view.dart similarity index 100% rename from lib/src/views/onboarding/onboarding_view.dart rename to lib/src/views/onboarding.view.dart diff --git a/lib/src/views/onboarding/register_view.dart b/lib/src/views/register.view.dart similarity index 98% rename from lib/src/views/onboarding/register_view.dart rename to lib/src/views/register.view.dart index 944168e..58b5d88 100644 --- a/lib/src/views/onboarding/register_view.dart +++ b/lib/src/views/register.view.dart @@ -35,7 +35,7 @@ class _RegisterViewState extends State { await createIfNotExistsSignalIdentity(); - final res = await apiProvider.register(username, inviteCode); + final res = await apiService.register(username, inviteCode); setState(() { _isTryingToRegister = false; @@ -50,7 +50,7 @@ class _RegisterViewState extends State { subscriptionPlan: "Preview", ); storage.write(key: "userData", value: jsonEncode(userData)); - apiProvider.authenticate(); + apiService.authenticate(); widget.callbackOnSuccess(); return; } diff --git a/lib/src/views/settings/appearance_view.dart b/lib/src/views/settings/appearance_view.dart index 34d5137..723c194 100644 --- a/lib/src/views/settings/appearance_view.dart +++ b/lib/src/views/settings/appearance_view.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:twonly/src/views/components/radio_button.dart'; -import 'package:twonly/src/providers/settings_change_provider.dart'; +import 'package:twonly/src/providers/settings.provider.dart'; import 'package:twonly/src/utils/misc.dart'; class AppearanceView extends StatelessWidget { diff --git a/lib/src/views/settings/data_and_storage_view.dart b/lib/src/views/settings/data_and_storage_view.dart index 67de151..26b895a 100644 --- a/lib/src/views/settings/data_and_storage_view.dart +++ b/lib/src/views/settings/data_and_storage_view.dart @@ -1,6 +1,6 @@ import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/material.dart'; -import 'package:twonly/src/providers/api/media_received.dart'; +import 'package:twonly/src/services/api/media_received.dart'; import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/utils/misc.dart'; diff --git a/lib/src/views/settings/notification_view.dart b/lib/src/views/settings/notification_view.dart index 3f73dd0..6566469 100644 --- a/lib/src/views/settings/notification_view.dart +++ b/lib/src/views/settings/notification_view.dart @@ -5,8 +5,8 @@ import 'package:flutter/services.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/views/components/alert_dialog.dart'; -import 'package:twonly/src/services/fcm_service.dart'; -import 'package:twonly/src/services/notification_service.dart'; +import 'package:twonly/src/services/fcm.service.dart'; +import 'package:twonly/src/services/notification.service.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/storage.dart'; @@ -48,7 +48,7 @@ class NotificationView extends StatelessWidget { user.userId, PushKind.testNotification, ); - await apiProvider.sendTextMessage( + await apiService.sendTextMessage( user.userId, Uint8List(0), pushData, diff --git a/lib/src/views/settings/privacy_view.dart b/lib/src/views/settings/privacy_view.dart index 237649d..311ccf3 100644 --- a/lib/src/views/settings/privacy_view.dart +++ b/lib/src/views/settings/privacy_view.dart @@ -27,7 +27,7 @@ class _PrivacyViewState extends State { ListTile( title: Text(context.lang.settingsPrivacyBlockUsers), subtitle: StreamBuilder( - stream: twonlyDatabase.contactsDao.watchContactsBlocked(), + stream: twonlyDB.contactsDao.watchContactsBlocked(), builder: (context, snapshot) { if (snapshot.hasData && snapshot.data != null) { return Text( diff --git a/lib/src/views/settings/privacy_view_block_users.dart b/lib/src/views/settings/privacy_view_block_users.dart index 1b18ba7..688fde9 100644 --- a/lib/src/views/settings/privacy_view_block_users.dart +++ b/lib/src/views/settings/privacy_view_block_users.dart @@ -21,7 +21,7 @@ class _PrivacyViewBlockUsers extends State { @override void initState() { super.initState(); - allUsers = twonlyDatabase.contactsDao.watchAllContacts(); + allUsers = twonlyDB.contactsDao.watchAllContacts(); loadAsync(); } @@ -91,7 +91,7 @@ class UserList extends StatelessWidget { Future block(BuildContext context, int userId, bool? value) async { if (value != null) { final update = ContactsCompanion(blocked: Value(value)); - await twonlyDatabase.contactsDao.updateContact(userId, update); + await twonlyDB.contactsDao.updateContact(userId, update); } } diff --git a/lib/src/views/settings/profile/modify_avatar_view.dart b/lib/src/views/settings/profile/modify_avatar_view.dart index 8a9a3c0..c6b500f 100644 --- a/lib/src/views/settings/profile/modify_avatar_view.dart +++ b/lib/src/views/settings/profile/modify_avatar_view.dart @@ -3,7 +3,7 @@ import 'package:avatar_maker/avatar_maker.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:twonly/src/model/json/userdata.dart'; -import 'package:twonly/src/providers/api/api.dart'; +import 'package:twonly/src/services/api/messages.dart'; import 'package:twonly/src/utils/misc.dart'; import "package:get/get.dart"; import 'package:twonly/src/utils/storage.dart'; diff --git a/lib/src/views/settings/profile/profile_view.dart b/lib/src/views/settings/profile/profile_view.dart index cfd9ab5..ecfc3dc 100644 --- a/lib/src/views/settings/profile/profile_view.dart +++ b/lib/src/views/settings/profile/profile_view.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:twonly/src/views/components/better_list_title.dart'; import 'package:twonly/src/model/json/userdata.dart'; -import 'package:twonly/src/providers/api/api.dart'; +import 'package:twonly/src/services/api/messages.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/views/settings/profile/modify_avatar_view.dart'; diff --git a/lib/src/views/settings/subscription/additional_users_view.dart b/lib/src/views/settings/subscription/additional_users_view.dart index 1f4c062..991cbba 100644 --- a/lib/src/views/settings/subscription/additional_users_view.dart +++ b/lib/src/views/settings/subscription/additional_users_view.dart @@ -7,7 +7,7 @@ import 'package:logging/logging.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/database/daos/contacts_dao.dart'; import 'package:twonly/src/model/protobuf/api/server_to_client.pb.dart'; -import 'package:twonly/src/providers/api/api_utils.dart'; +import 'package:twonly/src/services/api/utils.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/views/components/alert_dialog.dart'; @@ -17,7 +17,7 @@ Future?> loadAdditionalUserInvites() async { List? ballance; final user = await getUser(); if (user == null) return ballance; - ballance = await apiProvider.getAdditionalUserInvites(); + ballance = await apiService.getAdditionalUserInvites(); if (ballance != null) { user.additionalUserInvites = jsonEncode(ballance.map((x) => x.writeToJson()).toList()); @@ -147,7 +147,7 @@ class _AdditionalAccountState extends State { } Future initAsync() async { - final contact = await twonlyDatabase.contactsDao + final contact = await twonlyDB.contactsDao .getContactByUserId(widget.account.userId.toInt()) .getSingleOrNull(); if (contact != null) { @@ -188,7 +188,7 @@ class _AdditionalAccountState extends State { "Remove this additional user", "The additional user will automatically be downgraded to the preview plan after removal and you will receive a new invitation code to give to another person."); if (remove) { - Result res = await apiProvider + Result res = await apiService .removeAdditionalUser(widget.account.userId); if (!context.mounted) return; if (res.isSuccess) { diff --git a/lib/src/views/settings/subscription/manage_subscription_view.dart b/lib/src/views/settings/subscription/manage_subscription_view.dart index 349e4c4..7110eb6 100644 --- a/lib/src/views/settings/subscription/manage_subscription_view.dart +++ b/lib/src/views/settings/subscription/manage_subscription_view.dart @@ -3,8 +3,8 @@ import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import 'package:twonly/globals.dart'; import 'package:twonly/src/model/protobuf/api/server_to_client.pb.dart'; -import 'package:twonly/src/providers/api/api_utils.dart'; -import 'package:twonly/src/providers/connection_provider.dart'; +import 'package:twonly/src/services/api/utils.dart'; +import 'package:twonly/src/providers/connection.provider.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/views/settings/subscription/subscription_view.dart'; @@ -44,7 +44,7 @@ class _ManageSubscriptionViewState extends State { } Future toggleRenewalOption() async { - Result res = await apiProvider.updatePlanOptions(!autoRenewal!); + Result res = await apiService.updatePlanOptions(!autoRenewal!); if (res.isError) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(errorCodeToText(context, res.error))), diff --git a/lib/src/views/settings/subscription/select_payment.dart b/lib/src/views/settings/subscription/select_payment.dart index 61e95e6..e833686 100644 --- a/lib/src/views/settings/subscription/select_payment.dart +++ b/lib/src/views/settings/subscription/select_payment.dart @@ -2,7 +2,7 @@ import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:twonly/globals.dart'; -import 'package:twonly/src/providers/connection_provider.dart'; +import 'package:twonly/src/providers/connection.provider.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/views/settings/subscription/subscription_view.dart'; @@ -213,7 +213,7 @@ class _SelectPaymentViewState extends State { child: FilledButton( onPressed: (canPay) ? () async { - final res = await apiProvider.switchToPayedPlan( + final res = await apiService.switchToPayedPlan( widget.planId!, widget.payMonthly!, tryAutoRenewal); if (!context.mounted) return; if (res.isSuccess) { diff --git a/lib/src/views/settings/subscription/subscription_view.dart b/lib/src/views/settings/subscription/subscription_view.dart index 809850e..0f215e4 100644 --- a/lib/src/views/settings/subscription/subscription_view.dart +++ b/lib/src/views/settings/subscription/subscription_view.dart @@ -9,7 +9,7 @@ import 'package:twonly/src/database/daos/contacts_dao.dart'; import 'package:twonly/src/database/twonly_database.dart'; import 'package:twonly/src/model/protobuf/api/error.pb.dart'; import 'package:twonly/src/model/protobuf/api/server_to_client.pb.dart'; -import 'package:twonly/src/providers/connection_provider.dart'; +import 'package:twonly/src/providers/connection.provider.dart'; import 'package:twonly/src/utils/misc.dart'; import 'package:twonly/src/utils/storage.dart'; import 'package:twonly/src/views/components/better_list_title.dart'; @@ -39,7 +39,7 @@ Future loadPlanBallance() async { Response_PlanBallance? ballance; final user = await getUser(); if (user == null) return ballance; - ballance = await apiProvider.getPlanBallance(); + ballance = await apiService.getPlanBallance(); if (ballance != null) { user.lastPlanBallance = ballance.writeToJson(); await updateUser(user); @@ -116,7 +116,7 @@ class _SubscriptionViewState extends State { ballance = await loadPlanBallance(); if (ballance != null && ballance!.hasAdditionalAccountOwnerId()) { final ownerId = ballance!.additionalAccountOwnerId.toInt(); - Contact? contact = await twonlyDatabase.contactsDao + Contact? contact = await twonlyDB.contactsDao .getContactByUserId(ownerId) .getSingleOrNull(); if (contact != null) { @@ -551,7 +551,7 @@ Future redeemUserInviteCode(BuildContext context, String newPlan) async { ), TextButton( onPressed: () async { - final res = await apiProvider.redeemUserInviteCode(inviteCode); + final res = await apiService.redeemUserInviteCode(inviteCode); if (!context.mounted) return; if (res.isSuccess) { ScaffoldMessenger.of(context).showSnackBar( @@ -559,8 +559,8 @@ Future redeemUserInviteCode(BuildContext context, String newPlan) async { content: Text(context.lang.redeemUserInviteCodeSuccess)), ); // reconnect to load new plan. - apiProvider.close(() { - apiProvider.connect(); + apiService.close(() { + apiService.connect(); }); } else { ScaffoldMessenger.of(context).showSnackBar( diff --git a/lib/src/views/settings/subscription/voucher_view.dart b/lib/src/views/settings/subscription/voucher_view.dart index 6ccdfc9..cf6da99 100644 --- a/lib/src/views/settings/subscription/voucher_view.dart +++ b/lib/src/views/settings/subscription/voucher_view.dart @@ -22,7 +22,7 @@ class _VoucherViewState extends State { } Future initAsync() async { - Response_Vouchers? resVouchers = await apiProvider.getVoucherList(); + Response_Vouchers? resVouchers = await apiService.getVoucherList(); if (resVouchers != null) { setState(() { vouchers = resVouchers.vouchers; @@ -193,7 +193,7 @@ Future redeemVoucher(BuildContext context) async { ), TextButton( onPressed: () async { - final res = await apiProvider.redeemVoucher(voucherCode); + final res = await apiService.redeemVoucher(voucherCode); if (!context.mounted) return; if (res.isSuccess) { ScaffoldMessenger.of(context).showSnackBar( @@ -284,7 +284,7 @@ Future showBuyVoucher(BuildContext context) async { ), TextButton( onPressed: () async { - final res = await apiProvider.buyVoucher(quantity); + final res = await apiService.buyVoucher(quantity); if (!context.mounted) return; if (res.isSuccess) { ScaffoldMessenger.of(context).showSnackBar(