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