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

Commit

Permalink
add crash reporting setting, ui states are enum
Browse files Browse the repository at this point in the history
  • Loading branch information
iamalper committed Sep 9, 2023
1 parent 74148db commit 06122c3
Show file tree
Hide file tree
Showing 15 changed files with 191 additions and 173 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ I am not much experienced at Flutter so any advice or pull request welcomed (eve
Also you can help with improving translations or translating another languages with committing in **lib/l10** folder.
### TODO
- [ ] Handle connection lost while transfer and show proper error dialog
- [ ] Convert throw types from `String` to `enum` or `exception`
- [ ] Convert UI states from `integer` to `enum`
- [ ] Add setting for opt-out crash reporting
- [x] Convert throw types from `String` to `enum` or `exception`
- [x] Convert UI states from `integer` to `enum`
- [x] Add setting for opt-out crash reporting
- [ ] Add setting for change to system theme
- [ ] Add logs for crash reporting
- [ ] Find a way to build for windows in actions script
Expand Down
16 changes: 4 additions & 12 deletions lib/classes/database.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,12 @@ class DatabaseManager {
Future<void> insert(DbFile file) async {
switch (file.fileStatus) {
case DbFileStatus.upload:
await _db.insert("uploaded", {
"name": file.name,
"type": file.fileType?.name,
"time": file.timeEpoch,
"path": file.path
});
await _db.insert("uploaded",
{"name": file.name, "time": file.timeEpoch, "path": file.path});
break;
case DbFileStatus.download:
await _db.insert("downloaded", {
"name": file.name,
"type": file.fileType?.name,
"time": file.timeEpoch,
"path": file.path
});
await _db.insert("downloaded",
{"name": file.name, "time": file.timeEpoch, "path": file.path});
break;
}
}
Expand Down
3 changes: 2 additions & 1 deletion lib/classes/exceptions.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import 'package:flutter_gen/gen_l10n/app_localizations.dart';

///Base class for FileDrop exceptions.
///
///Has [getErrorMessage] method for localised error messages.
///Use [getErrorMessage] method for localised error messages.
abstract class FileDropException implements Exception {
///Returns localised simple error message for end user.
String getErrorMessage(AppLocalizations appLocalizations);
}

Expand Down
11 changes: 6 additions & 5 deletions lib/classes/receiver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class Receiver {
final int? port;

///[onDownloadStart] will be called when starting to download first time.
final void Function(int fileCount)? onDownloadStart;
final void Function()? onDownloadStart;

///[onFileDownloaded] will be called when a file downloaded succesfully.
final void Function(DbFile file)? onFileDownloaded;
Expand Down Expand Up @@ -126,16 +126,16 @@ class Receiver {
MediaType.parse(request.headers['content-type']!)
.parameters["boundary"]!)
.bind(request.read());
onDownloadStart?.call(await stream.length);
onDownloadStart?.call();
final db = DatabaseManager();
if (useDb) {
await db.open();
}
await for (var mime in stream) {
String filename =
final filename =
HeaderValue.parse(mime.headers['content-disposition']!)
.parameters["filename"]!;
late File file;
File file;
if ((Platform.isLinux || Platform.isWindows)) {
//Saving to downloads because these platforms don't require any permission
final dir = Directory(join(
Expand All @@ -152,7 +152,7 @@ class Receiver {
final totalBytesPer100 = request.contentLength! / 100;
int downloadedBytesto100 = 0;
await for (var bytes in mime) {
file.writeAsBytesSync(bytes, mode: FileMode.writeOnlyAppend);
file.writeAsBytesSync(bytes, mode: FileMode.writeOnly);

downloadedBytesto100 += bytes.length;
if (downloadedBytesto100 >= totalBytesPer100) {
Expand Down Expand Up @@ -190,6 +190,7 @@ class Receiver {
if (useDb) {
await db.close();
}
log("Recived file(s) $_files", name: "Receive server");
return Response.ok(null);
} catch (_) {
rethrow;
Expand Down
7 changes: 5 additions & 2 deletions lib/constants.dart
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ class Appbars {
static AppBar appBarWithSettings(
{required bool isDark,
required BuildContext context,
required PackageInfo packageInfo}) =>
required PackageInfo packageInfo,
required SharedPreferences sharedPreferences}) =>
AppBar(actions: [
_themeSwitch(isDark),
IconButton(
Expand All @@ -51,7 +52,9 @@ class Appbars {
context,
MaterialPageRoute(
builder: (context) => SettingsPage(
isDark: isDark, packageInfo: packageInfo)));
isDark: isDark,
packageInfo: packageInfo,
sharedPreferences: sharedPreferences)));
},
icon: const Icon(Icons.settings)),
]);
Expand Down
3 changes: 3 additions & 0 deletions lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
"aboutFiledrop":"About FileDrop",
"publicGithubRepo":"Public Github repo",
"advancedSettings":"Advanced",
"crashReporting":"Crash Reporing",
"crashReportingNotAvailable":"Crash reporting not available for desktop",
"crashRepostingDescription":"Automatically send crash reports to improve FileDrop.",
"version":"Version",
"buildNumber":"Build Number"
}
3 changes: 3 additions & 0 deletions lib/l10n/app_tr.arb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
"aboutFiledrop":"FileDrop Hakkında",
"publicGithubRepo":"Açık Github deposu",
"advancedSettings":"Gelişmiş",
"crashReporting":"Hata Raporlama",
"crashReportingNotAvailable":"Hata raporlama masaüstü platformlarında mevcut değil",
"crashRepostingDescription":"FileDrop'u iyileştirmek için otomatik olarak hata raporlarını gönderir.",
"version":"Sürüm",
"buildNumber":"Derleme Numarası"
}
87 changes: 33 additions & 54 deletions lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import 'package:flutter/material.dart';
import 'firebase_options.dart';
import 'screens/receive_page.dart';
import 'screens/send_page.dart';
import 'classes/database.dart';
import 'models.dart';
import 'screens/files_page.dart';
import 'constants.dart';
Expand All @@ -18,36 +17,46 @@ import 'package:package_info_plus/package_info_plus.dart';

Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
final sharedPrefences = await SharedPreferences.getInstance();
if (kReleaseMode && (Platform.isAndroid || Platform.isIOS)) {
await Firebase.initializeApp(
options: DefaultFirebaseOptions.currentPlatform,
);
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;
PlatformDispatcher.instance.onError = (error, stack) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true;
};
final useCrashReporting =
sharedPrefences.getBool("crashRepostsEnable") ?? true;
FlutterError.onError = useCrashReporting
? FirebaseCrashlytics.instance.recordFlutterFatalError
: null;
PlatformDispatcher.instance.onError = useCrashReporting
? (error, stack) {
FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
return true;
}
: null;
}
final packageInfo = await PackageInfo.fromPlatform();
final sharedPrefences = await SharedPreferences.getInstance();
final isDark = sharedPrefences.getBool("isDark") == true;

final isDark = sharedPrefences.getBool("isDark") ?? false;
runApp(MaterialAppWidget(
title: "FileDrop",
isDarkDefault: isDark,
packageInfo: packageInfo,
sharedPreferences: sharedPrefences,
));
}

class MaterialAppWidget extends StatelessWidget {
final String title;
final bool isDarkDefault;
final PackageInfo packageInfo;
final SharedPreferences sharedPreferences;
static late ValueNotifier<ThemeMode> valueNotifier;
const MaterialAppWidget(
{super.key,
required this.title,
required this.isDarkDefault,
required this.packageInfo});
required this.packageInfo,
required this.sharedPreferences});
@override
Widget build(BuildContext context) {
valueNotifier =
Expand Down Expand Up @@ -90,9 +99,9 @@ class MaterialAppWidget extends StatelessWidget {
.merge(Typography().white)
.apply(fontSizeDelta: 1, fontSizeFactor: 1.1)),
home: _MainWidget(
isDark: (valueNotifier.value == ThemeMode.dark),
packageInfo: packageInfo,
),
isDark: (valueNotifier.value == ThemeMode.dark),
packageInfo: packageInfo,
sharedPreferences: sharedPreferences),
);
},
);
Expand All @@ -104,62 +113,32 @@ List<DbFile> allFiles = [];
class _MainWidget extends StatefulWidget {
final bool isDark;
final PackageInfo packageInfo;
const _MainWidget({required this.isDark, required this.packageInfo});
final SharedPreferences sharedPreferences;
const _MainWidget(
{required this.isDark,
required this.packageInfo,
required this.sharedPreferences});

@override
State<_MainWidget> createState() => _MainWidgetState();
}

class _MainWidgetState extends State<_MainWidget> {
final db = DatabaseManager();

late Future<void> dbFuture;
bool loaded = false;
bool dbError = false;

@override
void initState() {
dbFuture = db.open().then((_) async {
final allFilesTmp = await db.files;
setState(() {
allFiles = allFilesTmp;
loaded = true;
});
}).catchError((_) {
setState(() {
dbError = true;
loaded = true;
});
});
super.initState();
}

@override
void dispose() {
dbFuture.ignore();
db.close();
super.dispose();
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: Appbars.appBarWithSettings(
isDark: widget.isDark,
context: context,
packageInfo: widget.packageInfo,
),
isDark: widget.isDark,
context: context,
packageInfo: widget.packageInfo,
sharedPreferences: widget.sharedPreferences),
body: Column(
children: [
Expanded(
const Expanded(
flex: 3,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Dosyalar(
allFiles: allFiles,
loaded: loaded,
dbError: dbError,
),
padding: EdgeInsets.all(8.0),
child: Dosyalar(),
),
),
Expanded(
Expand Down
21 changes: 2 additions & 19 deletions lib/models.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import 'constants.dart';
import 'package:flutter/material.dart';
import 'package:open_filex/open_filex.dart';

Expand All @@ -13,12 +12,6 @@ class DbFile {
///"Status" of the file. Should set `upload` if file sent or `download` if file got.
final DbFileStatus fileStatus;

@Deprecated("No longer depend to file type for opening file")

///It is type of the file as image, video, audio or text.
///It can be `null` if type of the file is unknown.
final DbFileType? fileType;

///It is full path of the file. It's using to open the file.
final String path;

Expand All @@ -31,16 +24,11 @@ class DbFile {
///
///[fileStatus] should set `upload` if file sent or `download` if file got.
///
///[fileType] is type of the file as image, video, audio or text.
///It can be `null` if type of the file is unknown.
///
///[path] is full path of the file. It's using to open the file.
///
///[time] is the time when file operation is completed.
const DbFile(
{required this.name,
@Deprecated("No longer depend to file type for opening file")
this.fileType,
required this.path,
required this.time,
required this.fileStatus});
Expand All @@ -49,17 +37,13 @@ class DbFile {
DbFile.uploadedFromMap(Map<String, dynamic> map)
: name = map["name"],
fileStatus = DbFileStatus.upload,
fileType = DbFileType.values
.singleWhere((element) => element.name == map["type"]),
time = DateTime.fromMillisecondsSinceEpoch(map["time"]),
path = map["path"];

///Use this constructor for load an downloaded file infos from database.
DbFile.downloadedFromMap(Map<String, dynamic> map)
: name = map["name"],
fileStatus = DbFileStatus.download,
fileType = DbFileType.values
.singleWhere((element) => element.name == map["type"]),
time = DateTime.fromMillisecondsSinceEpoch(map["time"]),
path = map["path"];

Expand All @@ -86,7 +70,7 @@ class DbFile {
///dbFile{name: [name], fileType: [fileType].name, time: [time], fileStatus: [fileStatus].name}
@override
String toString() =>
"dbFile{name: $name, fileType: ${fileType?.name}, time: $time, fileStatus: ${fileStatus.name}}";
"dbFile{name: $name, time: $time, fileStatus: ${fileStatus.name}}";
}

class Device {
Expand All @@ -108,8 +92,7 @@ class Device {
///see same code each devices.
///
///[port] is the port number of device. Should not set unless testing.
const Device(
{required this.adress, required this.code, this.port = Constants.port});
const Device({required this.adress, required this.code, required this.port});

///Uri object for device.
///
Expand Down
Loading

0 comments on commit 06122c3

Please sign in to comment.