Skip to content
This repository has been archived by the owner on Sep 22, 2024. It is now read-only.

Commit

Permalink
Support working on background #7
Browse files Browse the repository at this point in the history
general improvements
  • Loading branch information
iamalper committed Dec 15, 2023
1 parent c9f6932 commit d7605cb
Show file tree
Hide file tree
Showing 6 changed files with 114 additions and 50 deletions.
28 changes: 28 additions & 0 deletions integration_test/app_test.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:io';
import 'dart:math';
import 'package:file_picker/file_picker.dart';
import 'package:weepy/classes/database.dart';
import 'package:weepy/classes/discover.dart';
import 'package:weepy/classes/exceptions.dart';
import 'package:weepy/classes/sender.dart';
Expand All @@ -17,6 +18,7 @@ void main() {
var sendingFiles = <File>[];
var platformFiles = <PlatformFile>[];
late Directory subdir;
//TODO: Refactor
setUpAll(() async {
final tempDir = await getTemporaryDirectory();
subdir = tempDir.createTempSync("sending");
Expand All @@ -43,6 +45,32 @@ void main() {
name: path.basename(sendingFiles[index].path),
path: sendingFiles[index].path));
});

group("Database tests", () {
final db = DatabaseManager();
setUp(() => db.clear());
testWidgets("Downloaded file insert", (_) async {
final file = DbFile(
name: "test1",
path: "/.../../",
time: DateTime.now(),
fileStatus: DbFileStatus.download);
await db.insert(file);
final savedFiles = await db.files;
expect(savedFiles, equals([file]));
});
testWidgets("Uploaded file insert", (_) async {
final file = DbFile(
name: "test1",
path: "/.../../",
time: DateTime.now(),
fileStatus: DbFileStatus.upload);
await db.insert(file);
final savedFiles = await db.files;
expect(savedFiles, equals([file]));
});
tearDown(() => db.close());
});
group('IO tests', () {
var downloadedFiles = <DbFile>[];
Receiver? receiver;
Expand Down
14 changes: 9 additions & 5 deletions integration_test/mobile_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,29 +42,33 @@ void main() {
name: path.basename(sendingFiles[index].path),
path: sendingFiles[index].path));
});

final dbStatusVariant = ValueVariant({true, false});

testWidgets("Test IsolatedReceiver & IsolatedSender", (_) async {
receiver = IsolatedReceiver(
saveToTemp: true,
useDb: false,
useDb: dbStatusVariant.currentValue!,
onAllFilesDownloaded: (files) => downloadedFiles = files,
onDownloadError: (error) => throw error,
progressNotification: false);
progressNotification: true);
final code = await receiver!.listen();
var allDevices = <Device>[];
while (allDevices.isEmpty) {
allDevices = await Discover.discover();
}
final devices = allDevices.where((device) => device.code == code);
expect(devices, isNotEmpty, reason: "Expected to discover itself");
await IsolatedSender(progressNotification: false)
.send(devices.first, platformFiles, useDb: false);
await IsolatedSender(progressNotification: false).send(
devices.first, platformFiles,
useDb: dbStatusVariant.currentValue!);
for (var i = 0; i < sendingFiles.length; i++) {
final gidenDosya = sendingFiles[i];
final gelenDosya = File(downloadedFiles[i].path);
expect(gidenDosya.readAsBytesSync(), equals(gelenDosya.readAsBytesSync()),
reason: "All sent files expected to has same content as originals");
}
});
}, variant: dbStatusVariant);
tearDown(() {
for (var file in downloadedFiles) {
File(file.path).deleteSync();
Expand Down
11 changes: 7 additions & 4 deletions lib/classes/database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ import '../models.dart';

class DatabaseManager {
bool _initalised = false;
Future<Database> get _db {
Future<Database> get _db async {
if (!_initalised && (Platform.isLinux || Platform.isWindows)) {
sqfliteFfiInit();
databaseFactory = databaseFactoryFfiNoIsolate;
}
_initalised = true;
return openDatabase("files.db", version: 2, onCreate: (db, version) async {
final db = await openDatabase("files.db", version: 2,
onCreate: (db, version) async {
await db.execute(
"create table downloaded (ID integer primary key autoincrement, name text not null, path text not null, type text, timeepoch int not null)");
await db.execute(
Expand All @@ -26,7 +26,8 @@ class DatabaseManager {
.execute("alter table uploaded rename column time to timeepoch");
} on Exception catch (e) {
//Some old android devices does not support 'alert table'
//Workaround: Dropping table then recreating
//
//Workaround: Dropping table then recreating table
//since database contains only file history that would not be a problem
await FirebaseCrashlytics.instance.recordError(e, null,
reason:
Expand All @@ -42,6 +43,8 @@ class DatabaseManager {
throw UnsupportedError("Unsupported db version");
}
});
_initalised = true;
return db;
}

///Insert a uploaded or downloaded file information
Expand Down
19 changes: 14 additions & 5 deletions lib/classes/notifications.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,29 +27,38 @@ AndroidNotificationDetails _androidDetails(int progress, Type type) {
showProgress: true,
maxProgress: 100,
progress: progress,
channelAction: AndroidNotificationChannelAction.update,
category: AndroidNotificationCategory.progress);
}

///Show or update download progress notification.
///
///Make sure [progress] within range 0 to 100
Future<void> showDownload(int progress) => _localNotifications.show(
0,
Type.download.index,
null,
null,
NotificationDetails(android: _androidDetails(progress, Type.download)));

///Show or update upload progress notification.
///
///Make sure [progress] within range 0 to 100
Future<void> showUpload(int progress) => _localNotifications.show(1, null, null,
Future<void> showUpload(int progress) => _localNotifications.show(
Type.upload.index,
null,
null,
NotificationDetails(android: _androidDetails(progress, Type.upload)));

Future<void> cancelDownload() => _localNotifications.cancel(0);
Future<void> cancelDownload() async {
//_localNotifications.cancel(Type.download.index);
}

Future<void> cancelUpload() => _localNotifications.cancel(1);
Future<void> cancelUpload() async {
//_localNotifications.cancel(Type.upload.index);
}

///Inıtalise local notifications.
///
///Call before using any method.
Future<bool> initalise() async {
final status = await _localNotifications.initialize(
const InitializationSettings(
Expand Down
80 changes: 44 additions & 36 deletions lib/classes/workers/worker_interface.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import 'dart:async';
import 'dart:developer';
import 'dart:io';

import 'package:file_picker/file_picker.dart';
Expand Down Expand Up @@ -132,12 +133,12 @@ class IsolatedSender extends Sender {
await _workManager.registerOneOffTask(MyTasks.send.name, MyTasks.send.name,
inputData: map);
if (progressNotification) {
await notifications.showDownload(0);
await notifications.showUpload(0);
}
await exitBlock.future;
if (progressNotification) {
await notifications.cancelDownload();
await notifications.cancelUpload();
}
return exitBlock.future;
}

@override
Expand Down Expand Up @@ -169,7 +170,8 @@ class IsolatedReceiver extends Receiver {

///Starts worker and runs [Receiver.listen]
///
///If called twice, it has no effect.
///If necessary requests permission. Throws [NoStoragePermissionException]
///if permission rejected by user.
@override
Future<int> listen() async {
await initalize();
Expand Down Expand Up @@ -200,38 +202,44 @@ class IsolatedReceiver extends Receiver {
}

Future<void> _portCallback(data) async {
final type = messages.MessageType.values[data["type"]];
switch (type) {
case messages.MessageType.updatePercent:
final message = messages.UpdatePercent.fromMap(data);
if (progressNotification) {
await notifications.showDownload((message.newPercent * 100).round());
}
super.onDownloadUpdatePercent?.call(message.newPercent);
break;
case messages.MessageType.filedropError:
final message = messages.FiledropError.fromMap(data);
if (progressNotification) {
await notifications.cancelDownload();
}
super.onDownloadError?.call(message.exception);
break;
case messages.MessageType.fileDownloaded:
final message = messages.FileDownloaded.fromMap(data);
super.onFileDownloaded?.call(message.file);
break;
case messages.MessageType.allFilesDownloaded:
final message = messages.AllFilesDownloaded.fromMap(data);
if (progressNotification) {
await notifications.cancelDownload();
}
super.onAllFilesDownloaded?.call(message.files.toList());
break;
case messages.MessageType.downloadStarted:
final _ = messages.DownloadStarted.fromMap(data);
super.onDownloadStart?.call();
default:
throw Error();
try {
final type = messages.MessageType.values[data["type"]];
switch (type) {
case messages.MessageType.updatePercent:
final message = messages.UpdatePercent.fromMap(data);
if (progressNotification) {
await notifications
.showDownload((message.newPercent * 100).round());
}
super.onDownloadUpdatePercent?.call(message.newPercent);
break;
case messages.MessageType.filedropError:
final message = messages.FiledropError.fromMap(data);
if (progressNotification) {
await notifications.cancelDownload();
}
super.onDownloadError?.call(message.exception);
break;
case messages.MessageType.fileDownloaded:
final message = messages.FileDownloaded.fromMap(data);
super.onFileDownloaded?.call(message.file);
break;
case messages.MessageType.allFilesDownloaded:
final message = messages.AllFilesDownloaded.fromMap(data);
if (progressNotification) {
await notifications.cancelDownload();
}
super.onAllFilesDownloaded?.call(message.files.toList());
break;
case messages.MessageType.downloadStarted:
final _ = messages.DownloadStarted.fromMap(data);
super.onDownloadStart?.call();
default:
throw Error();
}
} on Exception catch (e) {
log("Interface error", name: "IsolatedReceiver", error: e);
rethrow;
}
}
}
12 changes: 12 additions & 0 deletions lib/models.dart
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,18 @@ class DbFile {
"timeepoch": timeEpoch,
"fileStatus": fileStatus.index
};
@override
int get hashCode =>
path.hashCode ^ timeEpoch.hashCode ^ fileStatus.index.hashCode;

@override
bool operator ==(Object other) {
if (other is DbFile) {
return other.hashCode == hashCode;
} else {
return false;
}
}
}

class Device {
Expand Down

0 comments on commit d7605cb

Please sign in to comment.