restructure of the files

This commit is contained in:
otsmr 2025-05-30 17:24:02 +02:00
parent 608477d07d
commit 9264d5a4b3
66 changed files with 414 additions and 399 deletions

View file

@ -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<App> 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<App> with WidgetsBindingObserver {
Future initAsync() async {
setUserPlan();
apiProvider.connect();
apiService.connect();
}
@override
@ -78,8 +78,8 @@ class _AppState extends State<App> 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;

View file

@ -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<CameraDescription> gCameras = <CameraDescription>[];

View file

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

View file

@ -13,7 +13,7 @@ class ConnectIdentityKeyStore extends IdentityKeyStore {
@override
Future<IdentityKey?> 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())))

View file

@ -7,19 +7,17 @@ import 'package:twonly/src/database/twonly_database.dart';
class ConnectPreKeyStore extends PreKeyStore {
@override
Future<bool> 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<PreKeyRecord> 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<void> 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");
}

View file

@ -7,7 +7,7 @@ class ConnectSenderKeyStore extends SenderKeyStore {
@override
Future<SenderKeyRecord> 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<void> 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()),

View file

@ -6,25 +6,24 @@ import 'package:twonly/src/database/twonly_database.dart';
class ConnectSessionStore extends SessionStore {
@override
Future<bool> 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<void> deleteAllSessions(String name) async {
await (twonlyDatabase.delete(twonlyDatabase.signalSessionStores)
await (twonlyDB.delete(twonlyDB.signalSessionStores)
..where((tbl) => tbl.name.equals(name)))
.go();
}
@override
Future<void> 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<List<int>> 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<SessionRecord> 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())))

View file

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

View file

@ -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<Map<int, GalleryItem>> convertFromMessages(
static Future<Map<int, MemoryItem>> convertFromMessages(
List<Message> messages) async {
Map<int, GalleryItem> items = {};
Map<int, MemoryItem> 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,

View file

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

View file

@ -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<Message> 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<Uint8List?> getImageBytes(int mediaId) async {
@ -301,8 +301,8 @@ Future<void> purgeMediaFiles(Directory directory) async {
try {
if (directory.path.endsWith("send")) {
List<Message> messages = await twonlyDatabase.messagesDao
.getMessagesByMediaUploadId(fileId);
List<Message> messages =
await twonlyDB.messagesDao.getMessagesByMediaUploadId(fileId);
bool canBeDeleted = true;
for (final message in messages) {
@ -319,7 +319,7 @@ Future<void> purgeMediaFiles(Directory directory) async {
file.deleteSync();
}
} else {
Message? message = await twonlyDatabase.messagesDao
Message? message = await twonlyDB.messagesDao
.getMessageByMessageId(fileId)
.getSingleOrNull();
if ((message == null) ||

View file

@ -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<ErrorCode?> 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<int?> initMediaUpload() async {
return await twonlyDatabase.mediaUploadsDao
return await twonlyDB.mediaUploadsDao
.insertMediaUpload(MediaUploadsCompanion());
}
@ -133,7 +132,7 @@ Future<Uint8List> 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<int> contactIds,
List<int> 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<int> 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<int> contactIds,
}
}
await twonlyDatabase.mediaUploadsDao.updateMediaUpload(
await twonlyDB.mediaUploadsDao.updateMediaUpload(
mediaUploadId,
MediaUploadsCompanion(
messageIds: Value(messageIds),
@ -270,7 +269,7 @@ Future finalizeUpload(int mediaUploadId, List<int> contactIds,
final lockingHandleNextMediaUploadStep = Mutex();
Future handleNextMediaUploadSteps(int mediaUploadId) async {
bool rerun = await lockingHandleNextMediaUploadStep.protect<bool>(() 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<bool> 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<bool> 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<bool> 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<bool> 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<bool> 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<bool> 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<bool> handleNotifyReceiver(MediaUpload media) async {
);
}
await twonlyDatabase.mediaUploadsDao.updateMediaUpload(
await twonlyDB.mediaUploadsDao.updateMediaUpload(
media.mediaUploadId,
MediaUploadsCompanion(
state: Value(UploadState.receiverNotified),

View file

@ -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<Map<String, dynamic>> getAllMessagesForRetransmitting() async {
Future<Result> 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<Result> 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<Contact> 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,

View file

@ -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<client.Response> 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<client.Response> 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<client.Response> 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<client.Response> 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<client.Response> 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<client.Response> 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<client.Response> 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<client.Response> 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<client.Response> 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<client.Response> 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<client.Response> 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),

View file

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

View file

@ -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<Contact> 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()),

View file

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

View file

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

61
lib/src/utils/log.dart Normal file
View file

@ -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<void> _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<String> stackLines = stackTraceString.split('\n');
if (stackLines.length > 2) {
String callerInfo = stackLines[2];
List<String> 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';
}

View file

@ -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<void> 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<bool> deleteLogFile() async {
final directory = await getApplicationSupportDirectory();
final logFile = File('${directory.path}/app.log');
@ -165,17 +152,6 @@ Future<bool> 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);

View file

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

View file

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

View file

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

View file

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

View file

@ -27,7 +27,7 @@ class _LocationFilterState extends State<LocationFilter> {
}
Future initAsync() async {
final res = await apiProvider.getCurrentLocation();
final res = await apiService.getCurrentLocation();
if (res.isSuccess) {
location = res.value.location;
_searchForImage();

View file

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

View file

@ -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<ShareImageEditorView> {
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);
}

View file

@ -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<ShareImageView> {
super.initState();
Stream<List<Contact>> allContacts =
twonlyDatabase.contactsDao.watchContactsForShareView();
twonlyDB.contactsDao.watchContactsForShareView();
contactSub = allContacts.listen((allContacts) {
setState(() {

View file

@ -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<SearchUsernameView> createState() => _SearchUsernameView();
State<AddNewUserView> createState() => _SearchUsernameView();
}
class _SearchUsernameView extends State<SearchUsernameView> {
class _SearchUsernameView extends State<AddNewUserView> {
final TextEditingController searchUserName = TextEditingController();
bool _isLoading = false;
bool hasRequestedUsers = false;
@ -50,7 +50,7 @@ class _SearchUsernameView extends State<SearchUsernameView> {
void initStreams() {
contactsStream =
twonlyDatabase.contactsDao.watchNotAcceptedContacts().listen((update) {
twonlyDB.contactsDao.watchNotAcceptedContacts().listen((update) {
setState(() {
contacts = update;
});
@ -67,7 +67,7 @@ class _SearchUsernameView extends State<SearchUsernameView> {
_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<SearchUsernameView> {
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<ContactsListView> {
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<ContactsListView> {
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<ContactsListView> {
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<ContactsListView> {
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,

View file

@ -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<ChatListView> {
]),
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<ChatListView> {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SearchUsernameView(),
builder: (context) => AddNewUserView(),
),
);
},
@ -107,7 +107,7 @@ class _ChatListViewState extends State<ChatListView> {
),
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<ChatListView> {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SearchUsernameView(),
builder: (context) => AddNewUserView(),
),
);
},
@ -138,8 +138,8 @@ class _ChatListViewState extends State<ChatListView> {
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<ChatListView> {
Navigator.push(
context,
MaterialPageRoute(builder: (context) {
return StartNewChat();
return StartNewChatView();
}),
);
},
@ -250,13 +250,13 @@ class _UserListItem extends State<UserListItem> {
}
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);

View file

@ -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<ChatMessagesView> {
late StreamSubscription<Contact> userSub;
late StreamSubscription<List<Message>> messageSub;
List<Message> messages = [];
List<GalleryItem> galleryItems = [];
List<MemoryItem> galleryItems = [];
Map<int, List<Message>> textReactionsToMessageId = {};
Map<int, List<Message>> emojiReactionsToMessageId = {};
Message? responseToMessage;
@ -67,9 +67,9 @@ class _ChatMessagesViewState extends State<ChatMessagesView> {
}
Future initStreams() async {
await twonlyDatabase.messagesDao.removeOldMessages();
await twonlyDB.messagesDao.removeOldMessages();
Stream<Contact> 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<ChatMessagesView> {
});
Stream<List<Message>> 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<ChatMessagesView> {
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<ChatMessagesView> {
.toList()
.reversed
.toList();
final items = await GalleryItem.convertFromMessages(filteredMediaFiles);
final items = await MemoryItem.convertFromMessages(filteredMediaFiles);
setState(() {
galleryItems = items.values.toList();
});

View file

@ -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<GalleryItem> galleryItems;
final List<MemoryItem> 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)),
);

View file

@ -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<Message> textReactions;
final List<Message> otherReactions;
final List<GalleryItem> galleryItems;
final List<MemoryItem> galleryItems;
final Function(Message) onResponseTriggered;
@override

View file

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

View file

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

View file

@ -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<GalleryItem> galleryItems;
final List<MemoryItem> galleryItems;
final Color color;
@override
@ -60,7 +60,7 @@ class _InChatMediaViewerState extends State<InChatMediaViewer> {
/// 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<InChatMediaViewer> {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => GalleryPhotoViewWrapper(
builder: (context) => MemoriesPhotoSliderView(
galleryItems: widget.galleryItems,
initialIndex: widget.galleryItems.indexWhere((x) =>
x.id ==

View file

@ -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<MediaViewerView> {
}
Future asyncLoadNextMedia(bool firstRun) async {
Stream<List<Message>> messages = twonlyDatabase.messagesDao
.watchMediaMessageNotOpened(widget.contact.userId);
Stream<List<Message>> messages =
twonlyDB.messagesDao.watchMediaMessageNotOpened(widget.contact.userId);
_subscription = messages.listen((messages) {
for (Message msg in messages) {
@ -172,7 +172,7 @@ class _MediaViewerViewState extends State<MediaViewerView> {
});
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<MediaViewerView> {
[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<MediaViewerView> {
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<MediaViewerView> {
setState(() {
imageSaving = true;
});
await twonlyDatabase.messagesDao.updateMessageByMessageId(
await twonlyDB.messagesDao.updateMessageByMessageId(
allMediaFiles.first.messageId,
MessagesCompanion(mediaStored: Value(true)),
);

View file

@ -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<StartNewChat> createState() => _StartNewChat();
State<StartNewChatView> createState() => _StartNewChatView();
}
class _StartNewChat extends State<StartNewChat> {
class _StartNewChatView extends State<StartNewChatView> {
List<Contact> contacts = [];
List<Contact> allContacts = [];
final TextEditingController searchUserName = TextEditingController();
@ -30,7 +30,7 @@ class _StartNewChat extends State<StartNewChat> {
super.initState();
Stream<List<Contact>> 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)

View file

@ -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<UserContextMenu> {
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<UserContextMenu> {
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<UserContextMenu> {
final update =
ContactsCompanion(pinned: Value(!widget.contact.pinned));
if (context.mounted) {
await twonlyDatabase.contactsDao
await twonlyDB.contactsDao
.updateContact(widget.contact.userId, update);
}
},

View file

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

View file

@ -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<ContactView> {
@override
Widget build(BuildContext context) {
Stream<Contact?> contact = twonlyDatabase.contactsDao
Stream<Contact?> contact = twonlyDB.contactsDao
.getContactByUserId(widget.userId)
.watchSingleOrNull();
@ -76,8 +76,7 @@ class _ContactViewState extends State<ContactView> {
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<ContactView> {
);
if (block) {
if (context.mounted) {
await twonlyDatabase.messagesDao
await twonlyDB.messagesDao
.deleteMessagesByContactId(contact.userId);
}
}
@ -125,7 +124,7 @@ class _ContactViewState extends State<ContactView> {
if (block) {
final update = ContactsCompanion(blocked: Value(true));
if (context.mounted) {
await twonlyDatabase.contactsDao
await twonlyDB.contactsDao
.updateContact(contact.userId, update);
}
if (context.mounted) {

View file

@ -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<ContactVerifyView> {
@override
Widget build(BuildContext context) {
Stream<Contact?> contact = twonlyDatabase.contactsDao
Stream<Contact?> contact = twonlyDB.contactsDao
.getContactByUserId(widget.contact.userId)
.watchSingleOrNull();
@ -114,7 +113,7 @@ class _ContactVerifyViewState extends State<ContactVerifyView> {
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<ContactVerifyView> {
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<ContactVerifyView> {
icon: FaIcon(FontAwesomeIcons.shieldHeart),
onPressed: () {
final update = ContactsCompanion(verified: Value(true));
twonlyDatabase.contactsDao
twonlyDB.contactsDao
.updateContact(contact.userId, update);
},
label: Text(context.lang.contactVerifyNumberMarkAsVerified),

View file

@ -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<HomeView> {
children: [
ChatListView(),
Container(),
GalleryMainView(),
MemoriesView(),
],
),
),

View file

@ -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<GalleryMainView> createState() => GalleryMainViewState();
State<MemoriesView> createState() => MemoriesViewState();
}
class GalleryMainViewState extends State<GalleryMainView> {
class MemoriesViewState extends State<MemoriesView> {
bool verticalGallery = false;
List<GalleryItem> galleryItems = [];
List<MemoryItem> galleryItems = [];
Map<String, List<int>> orderedByMonth = {};
List<String> months = [];
bool mounted = true;
@ -37,11 +37,11 @@ class GalleryMainViewState extends State<GalleryMainView> {
super.dispose();
}
Future<List<GalleryItem>> loadMemoriesDirectory() async {
Future<List<MemoryItem>> loadMemoriesDirectory() async {
final directoryPath = await send.getMediaBaseFilePath("memories");
final directory = Directory(directoryPath);
List<GalleryItem> items = [];
List<MemoryItem> items = [];
if (await directory.exists()) {
final files = directory.listSync();
@ -58,7 +58,7 @@ class GalleryMainViewState extends State<GalleryMainView> {
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<GalleryMainView> {
Future initAsync() async {
messageSub?.cancel();
Stream<List<Message>> msgStream =
twonlyDatabase.messagesDao.getAllStoredMediaFiles();
twonlyDB.messagesDao.getAllStoredMediaFiles();
messageSub = msgStream.listen((msgs) async {
Map<int, GalleryItem> items = await GalleryItem.convertFromMessages(msgs);
Map<int, MemoryItem> items = await MemoryItem.convertFromMessages(msgs);
// Group items by month
orderedByMonth = {};
months = [];
@ -126,7 +126,7 @@ class GalleryMainViewState extends State<GalleryMainView> {
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<GalleryMainView> {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => GalleryPhotoViewWrapper(
builder: (context) => MemoriesPhotoSliderView(
galleryItems: galleryItems,
initialIndex: index,
scrollDirection: verticalGallery ? Axis.vertical : Axis.horizontal,

View file

@ -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<GalleryItemThumbnail> createState() => _GalleryItemThumbnailState();
State<MemoriesItemThumbnail> createState() => _MemoriesItemThumbnailState();
}
class _GalleryItemThumbnailState extends State<GalleryItemThumbnail> {
class _MemoriesItemThumbnailState extends State<MemoriesItemThumbnail> {
VideoPlayerController? _controller;
@override

View file

@ -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<GalleryItem> galleryItems;
final List<MemoryItem> galleryItems;
final Axis scrollDirection;
@override
State<StatefulWidget> createState() {
return _GalleryPhotoViewWrapperState();
return _MemoriesPhotoSliderViewState();
}
}
class _GalleryPhotoViewWrapperState extends State<GalleryPhotoViewWrapper> {
class _MemoriesPhotoSliderViewState extends State<MemoriesPhotoSliderView> {
late int currentIndex = widget.initialIndex;
void onPageChanged(int index) {
@ -60,7 +60,7 @@ class _GalleryPhotoViewWrapperState extends State<GalleryPhotoViewWrapper> {
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<GalleryPhotoViewWrapper> {
}
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(

View file

@ -35,7 +35,7 @@ class _RegisterViewState extends State<RegisterView> {
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<RegisterView> {
subscriptionPlan: "Preview",
);
storage.write(key: "userData", value: jsonEncode(userData));
apiProvider.authenticate();
apiService.authenticate();
widget.callbackOnSuccess();
return;
}

View file

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

View file

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

View file

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

View file

@ -27,7 +27,7 @@ class _PrivacyViewState extends State<PrivacyView> {
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(

View file

@ -21,7 +21,7 @@ class _PrivacyViewBlockUsers extends State<PrivacyViewBlockUsers> {
@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);
}
}

View file

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

View file

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

View file

@ -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<List<Response_AddAccountsInvite>?> loadAdditionalUserInvites() async {
List<Response_AddAccountsInvite>? 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<AdditionalAccount> {
}
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<AdditionalAccount> {
"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) {

View file

@ -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<ManageSubscriptionView> {
}
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))),

View file

@ -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<SelectPaymentView> {
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) {

View file

@ -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<Response_PlanBallance?> 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<SubscriptionView> {
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(

View file

@ -22,7 +22,7 @@ class _VoucherViewState extends State<VoucherView> {
}
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(