mirror of
https://github.com/twonlyapp/twonly-app.git
synced 2026-01-15 13:08:42 +00:00
move utils to separate files
This commit is contained in:
parent
52ee97c932
commit
084222eee8
14 changed files with 154 additions and 165 deletions
|
|
@ -3,8 +3,7 @@ import 'package:twonly/src/providers/api_provider.dart';
|
|||
import 'package:twonly/src/providers/db_provider.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:twonly/src/utils.dart';
|
||||
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'src/app.dart';
|
||||
import 'src/settings/settings_controller.dart';
|
||||
import 'src/settings/settings_service.dart';
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import 'package:twonly/main.dart';
|
||||
import 'package:twonly/src/utils/storage.dart';
|
||||
import 'package:twonly/src/views/onboarding_view.dart';
|
||||
import 'views/home_view.dart';
|
||||
import 'views/register_view.dart';
|
||||
import 'utils.dart';
|
||||
import 'package:twonly/src/views/home_view.dart';
|
||||
import 'package:twonly/src/views/register_view.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
|
|
|
|||
|
|
@ -11,7 +11,8 @@ import 'package:twonly/src/proto/api/error.pb.dart';
|
|||
import 'package:twonly/src/proto/api/server_to_client.pb.dart' as server;
|
||||
import 'package:twonly/src/signal/signal_helper.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:twonly/src/utils.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/utils/storage.dart';
|
||||
import 'package:web_socket_channel/io.dart';
|
||||
import 'package:libsignal_protocol_dart/src/ecc/ed25519.dart';
|
||||
import 'package:web_socket_channel/web_socket_channel.dart';
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import 'package:twonly/src/model/model_constants.dart';
|
|||
import 'package:twonly/src/model/pre_key_model.dart';
|
||||
import 'package:twonly/src/model/sender_key_store_model.dart';
|
||||
import 'package:twonly/src/model/session_store_model.dart';
|
||||
import 'package:twonly/src/utils.dart';
|
||||
import 'package:sqflite_sqlcipher/sqflite.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
|
||||
class DbProvider {
|
||||
Database? db;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import 'dart:collection';
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:twonly/src/utils.dart';
|
||||
import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
|
||||
class ConnectSignedPreKeyStore extends SignedPreKeyStore {
|
||||
// final store = HashMap<int, Uint8List>();
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import 'package:libsignal_protocol_dart/libsignal_protocol_dart.dart';
|
|||
import 'package:logging/logging.dart';
|
||||
import 'package:twonly/src/model/signal_identity_json.dart';
|
||||
import 'package:twonly/src/proto/api/server_to_client.pb.dart';
|
||||
import 'package:twonly/src/utils.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
|
||||
import 'connect_sender_key_store.dart';
|
||||
import 'connect_signal_protocol_store.dart';
|
||||
|
|
|
|||
|
|
@ -1,143 +0,0 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
import 'package:gal/gal.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:twonly/main.dart';
|
||||
import 'package:twonly/src/model/contacts_model.dart';
|
||||
import 'package:twonly/src/signal/signal_helper.dart';
|
||||
import 'package:twonly/src/providers/api_provider.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'model/user_data_json.dart';
|
||||
|
||||
// Just a helper function to get the secure storage
|
||||
FlutterSecureStorage getSecureStorage() {
|
||||
AndroidOptions _getAndroidOptions() => const AndroidOptions(
|
||||
encryptedSharedPreferences: true,
|
||||
);
|
||||
return FlutterSecureStorage(aOptions: _getAndroidOptions());
|
||||
}
|
||||
|
||||
Future<bool> isUserCreated() async {
|
||||
UserData? user = await getUser();
|
||||
if (user == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<String?> saveImageToGallery(path) async {
|
||||
final hasAccess = await Gal.hasAccess();
|
||||
if (!hasAccess) {
|
||||
await Gal.requestAccess();
|
||||
}
|
||||
try {
|
||||
await Gal.putImage(path);
|
||||
return null;
|
||||
} on GalException catch (e) {
|
||||
return e.type.message;
|
||||
}
|
||||
}
|
||||
|
||||
Future<UserData?> getUser() async {
|
||||
final storage = getSecureStorage();
|
||||
String? userJson = await storage.read(key: "user_data");
|
||||
if (userJson == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
final userMap = jsonDecode(userJson) as Map<String, dynamic>;
|
||||
Logger("get_user").info("Found user: $userMap");
|
||||
final user = UserData.fromJson(userMap);
|
||||
return user;
|
||||
} catch (e) {
|
||||
Logger("get_user").shout("Error getting user: $e");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> deleteLocalUserData() async {
|
||||
final storage = getSecureStorage();
|
||||
var password = await storage.read(key: "sqflite_database_password");
|
||||
await dbProvider.remove();
|
||||
await storage.write(key: "sqflite_database_password", value: password);
|
||||
await storage.deleteAll();
|
||||
return true;
|
||||
}
|
||||
|
||||
Uint8List getRandomUint8List(int length) {
|
||||
final Random random = Random.secure();
|
||||
final Uint8List randomBytes = Uint8List(length);
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
randomBytes[i] = random.nextInt(256); // Generate a random byte (0-255)
|
||||
}
|
||||
|
||||
return randomBytes;
|
||||
}
|
||||
|
||||
int userIdToRegistrationId(Uint8List userId) {
|
||||
int result = 0;
|
||||
for (int i = 8; i < 16; i++) {
|
||||
result = (result << 8) | userId[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
String uint8ListToHex(Uint8List list) {
|
||||
final StringBuffer hexBuffer = StringBuffer();
|
||||
for (int byte in list) {
|
||||
hexBuffer.write(byte.toRadixString(16).padLeft(2, '0'));
|
||||
}
|
||||
return hexBuffer.toString().toUpperCase();
|
||||
}
|
||||
|
||||
Future<bool> addNewUser(String username) async {
|
||||
final res = await apiProvider.getUserData(username);
|
||||
|
||||
if (res.isSuccess) {
|
||||
print(res.value);
|
||||
print(res.value.userdata.userId);
|
||||
|
||||
if (await SignalHelper.addNewContact(res.value.userdata)) {
|
||||
await dbProvider.db!.insert(DbContacts.tableName, {
|
||||
DbContacts.columnDisplayName: username,
|
||||
DbContacts.columnUserId: res.value.userdata.userId.toInt()
|
||||
});
|
||||
}
|
||||
print("Add new user: ${res}");
|
||||
}
|
||||
|
||||
return res.isSuccess;
|
||||
}
|
||||
|
||||
Future<Result> createNewUser(String username, String inviteCode) async {
|
||||
final storage = getSecureStorage();
|
||||
|
||||
await SignalHelper.createIfNotExistsSignalIdentity();
|
||||
|
||||
final res = await apiProvider.register(username, inviteCode);
|
||||
|
||||
if (res.isSuccess) {
|
||||
Logger("create_new_user").info("Got user_id ${res.value} from server");
|
||||
final userData = UserData(
|
||||
userId: res.value.userid, username: username, displayName: username);
|
||||
storage.write(key: "user_data", value: jsonEncode(userData));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
Future<void> writeLogToFile(LogRecord record) async {
|
||||
final directory = await getApplicationDocumentsDirectory();
|
||||
final logFile = File('${directory.path}/app.log');
|
||||
|
||||
// Prepare the log message
|
||||
final logMessage =
|
||||
'${record.level.name}: ${record.loggerName}: ${record.message}\n';
|
||||
|
||||
// Append the log message to the file
|
||||
await logFile.writeAsString(logMessage, mode: FileMode.append);
|
||||
}
|
||||
44
lib/src/utils/api.dart
Normal file
44
lib/src/utils/api.dart
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
import 'dart:convert';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:twonly/main.dart';
|
||||
import 'package:twonly/src/model/contacts_model.dart';
|
||||
import 'package:twonly/src/signal/signal_helper.dart';
|
||||
import 'package:twonly/src/providers/api_provider.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/model/user_data_json.dart';
|
||||
|
||||
Future<bool> addNewUser(String username) async {
|
||||
final res = await apiProvider.getUserData(username);
|
||||
|
||||
if (res.isSuccess) {
|
||||
print(res.value);
|
||||
print(res.value.userdata.userId);
|
||||
|
||||
if (await SignalHelper.addNewContact(res.value.userdata)) {
|
||||
await dbProvider.db!.insert(DbContacts.tableName, {
|
||||
DbContacts.columnDisplayName: username,
|
||||
DbContacts.columnUserId: res.value.userdata.userId.toInt()
|
||||
});
|
||||
}
|
||||
print("Add new user: ${res}");
|
||||
}
|
||||
|
||||
return res.isSuccess;
|
||||
}
|
||||
|
||||
Future<Result> createNewUser(String username, String inviteCode) async {
|
||||
final storage = getSecureStorage();
|
||||
|
||||
await SignalHelper.createIfNotExistsSignalIdentity();
|
||||
|
||||
final res = await apiProvider.register(username, inviteCode);
|
||||
|
||||
if (res.isSuccess) {
|
||||
Logger("create_new_user").info("Got user_id ${res.value} from server");
|
||||
final userData = UserData(
|
||||
userId: res.value.userid, username: username, displayName: username);
|
||||
storage.write(key: "user_data", value: jsonEncode(userData));
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
51
lib/src/utils/misc.dart
Normal file
51
lib/src/utils/misc.dart
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
import 'dart:typed_data';
|
||||
import 'package:gal/gal.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
|
||||
Future<void> writeLogToFile(LogRecord record) async {
|
||||
final directory = await getApplicationDocumentsDirectory();
|
||||
final logFile = File('${directory.path}/app.log');
|
||||
|
||||
// Prepare the log message
|
||||
final logMessage =
|
||||
'${record.level.name}: ${record.loggerName}: ${record.message}\n';
|
||||
|
||||
// Append the log message to the file
|
||||
await logFile.writeAsString(logMessage, mode: FileMode.append);
|
||||
}
|
||||
|
||||
// Just a helper function to get the secure storage
|
||||
FlutterSecureStorage getSecureStorage() {
|
||||
AndroidOptions _getAndroidOptions() => const AndroidOptions(
|
||||
encryptedSharedPreferences: true,
|
||||
);
|
||||
return FlutterSecureStorage(aOptions: _getAndroidOptions());
|
||||
}
|
||||
|
||||
Future<String?> saveImageToGallery(path) async {
|
||||
final hasAccess = await Gal.hasAccess();
|
||||
if (!hasAccess) {
|
||||
await Gal.requestAccess();
|
||||
}
|
||||
try {
|
||||
await Gal.putImage(path);
|
||||
return null;
|
||||
} on GalException catch (e) {
|
||||
return e.type.message;
|
||||
}
|
||||
}
|
||||
|
||||
Uint8List getRandomUint8List(int length) {
|
||||
final Random random = Random.secure();
|
||||
final Uint8List randomBytes = Uint8List(length);
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
randomBytes[i] = random.nextInt(256); // Generate a random byte (0-255)
|
||||
}
|
||||
|
||||
return randomBytes;
|
||||
}
|
||||
39
lib/src/utils/storage.dart
Normal file
39
lib/src/utils/storage.dart
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import 'dart:convert';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:twonly/main.dart';
|
||||
import 'package:twonly/src/model/user_data_json.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
|
||||
Future<bool> isUserCreated() async {
|
||||
UserData? user = await getUser();
|
||||
if (user == null) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Future<UserData?> getUser() async {
|
||||
final storage = getSecureStorage();
|
||||
String? userJson = await storage.read(key: "user_data");
|
||||
if (userJson == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
final userMap = jsonDecode(userJson) as Map<String, dynamic>;
|
||||
Logger("get_user").info("Found user: $userMap");
|
||||
final user = UserData.fromJson(userMap);
|
||||
return user;
|
||||
} catch (e) {
|
||||
Logger("get_user").shout("Error getting user: $e");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> deleteLocalUserData() async {
|
||||
final storage = getSecureStorage();
|
||||
var password = await storage.read(key: "sqflite_database_password");
|
||||
await dbProvider.remove();
|
||||
await storage.write(key: "sqflite_database_password", value: password);
|
||||
await storage.deleteAll();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1,10 +1,9 @@
|
|||
import 'package:twonly/src/model/user_data_json.dart';
|
||||
|
||||
import '../settings/settings_controller.dart';
|
||||
import '../settings/settings_view.dart';
|
||||
import '../utils.dart';
|
||||
import 'package:restart_app/restart_app.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:twonly/src/settings/settings_controller.dart';
|
||||
import 'package:twonly/src/settings/settings_view.dart';
|
||||
import 'package:twonly/src/utils/storage.dart';
|
||||
|
||||
class ProfileView extends StatefulWidget {
|
||||
const ProfileView({super.key, required this.settingsController});
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import 'package:twonly/main.dart';
|
||||
import 'package:twonly/src/providers/api_provider.dart';
|
||||
import '../utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:twonly/src/utils/api.dart';
|
||||
|
||||
class RegisterView extends StatefulWidget {
|
||||
const RegisterView({super.key, required this.callbackOnSuccess});
|
||||
|
|
@ -130,9 +130,11 @@ class _RegisterViewState extends State<RegisterView> {
|
|||
widget.callbackOnSuccess();
|
||||
return;
|
||||
}
|
||||
if (context.mounted) {
|
||||
final errMsg =
|
||||
ApiProvider.getLocalizedString(context, res.error);
|
||||
showAlertDialog(context, "Oh no!", errMsg);
|
||||
}
|
||||
},
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStateProperty.all<EdgeInsets>(
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:twonly/src/utils.dart';
|
||||
import 'package:twonly/src/utils/api.dart';
|
||||
import 'package:twonly/src/views/register_view.dart';
|
||||
|
||||
class SearchUsernameView extends StatefulWidget {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
import 'package:twonly/src/utils.dart';
|
||||
import 'package:twonly/src/utils/misc.dart';
|
||||
import 'package:twonly/src/views/share_image_view.dart';
|
||||
|
||||
class ShareImageEditorView extends StatefulWidget {
|
||||
|
|
|
|||
Loading…
Reference in a new issue