diff --git a/.env b/.env
new file mode 100644
index 0000000..b0c15c7
--- /dev/null
+++ b/.env
@@ -0,0 +1,7 @@
+apiKey=
+appId=
+messagingSenderId=
+projectId=
+storageBucket=
+iosClientId=
+iosBundleId=
diff --git a/README.md b/README.md
index 377efff..250c862 100644
--- a/README.md
+++ b/README.md
@@ -14,6 +14,9 @@ The project is a flutter application for ruTorrent web interface. The app commun
Additionally, you can also stream torrents from your server (or seedbox) and download them locally to your mobile device (a save offline feature), which makes torrenting a seamless experience for ruTorrent users.
+## Download App
+
+
## ruTorrent and rtorrent
diff --git a/assets/icon/documents.svg b/assets/icon/documents.svg
new file mode 100644
index 0000000..f98e2b3
--- /dev/null
+++ b/assets/icon/documents.svg
@@ -0,0 +1,50 @@
+
+
+
+
diff --git a/assets/icon/games.svg b/assets/icon/games.svg
new file mode 100644
index 0000000..a8b2d08
--- /dev/null
+++ b/assets/icon/games.svg
@@ -0,0 +1,5948 @@
+
+
+
+
+
+
+
+
+
+
+]>
+
diff --git a/assets/icon/movies.svg b/assets/icon/movies.svg
new file mode 100644
index 0000000..a9aed2f
--- /dev/null
+++ b/assets/icon/movies.svg
@@ -0,0 +1,291 @@
+
+
+
diff --git a/assets/icon/movies3d.svg b/assets/icon/movies3d.svg
new file mode 100644
index 0000000..7234953
--- /dev/null
+++ b/assets/icon/movies3d.svg
@@ -0,0 +1,2596 @@
+
+
+
+
+
+
+
+
+
+
+]>
+
diff --git a/assets/icon/music.svg b/assets/icon/music.svg
new file mode 100644
index 0000000..41f488d
--- /dev/null
+++ b/assets/icon/music.svg
@@ -0,0 +1,43 @@
+
+
+
+
diff --git a/assets/icon/pictures.svg b/assets/icon/pictures.svg
new file mode 100644
index 0000000..552cb1c
--- /dev/null
+++ b/assets/icon/pictures.svg
@@ -0,0 +1,5938 @@
+
+
+
+
+
+
+
+
+
+
+]>
+
diff --git a/assets/icon/software.svg b/assets/icon/software.svg
new file mode 100644
index 0000000..dc048ee
--- /dev/null
+++ b/assets/icon/software.svg
@@ -0,0 +1,92 @@
+
+
+
+
diff --git a/assets/icon/videos.svg b/assets/icon/videos.svg
new file mode 100644
index 0000000..0a213fd
--- /dev/null
+++ b/assets/icon/videos.svg
@@ -0,0 +1,63 @@
+
+
+
+
diff --git a/assets/icons/documents.png b/assets/icons/documents.png
new file mode 100644
index 0000000..58269ed
Binary files /dev/null and b/assets/icons/documents.png differ
diff --git a/assets/icons/games.png b/assets/icons/games.png
new file mode 100644
index 0000000..e2247e9
Binary files /dev/null and b/assets/icons/games.png differ
diff --git a/assets/icons/movies.png b/assets/icons/movies.png
new file mode 100644
index 0000000..189b36a
Binary files /dev/null and b/assets/icons/movies.png differ
diff --git a/assets/icons/movies3d.png b/assets/icons/movies3d.png
new file mode 100644
index 0000000..1070a1b
Binary files /dev/null and b/assets/icons/movies3d.png differ
diff --git a/assets/icons/music.png b/assets/icons/music.png
new file mode 100644
index 0000000..1057437
Binary files /dev/null and b/assets/icons/music.png differ
diff --git a/assets/icons/pictures.png b/assets/icons/pictures.png
new file mode 100644
index 0000000..85b8963
Binary files /dev/null and b/assets/icons/pictures.png differ
diff --git a/assets/icons/software.png b/assets/icons/software.png
new file mode 100644
index 0000000..801308a
Binary files /dev/null and b/assets/icons/software.png differ
diff --git a/assets/icons/videos.png b/assets/icons/videos.png
new file mode 100644
index 0000000..24b9b84
Binary files /dev/null and b/assets/icons/videos.png differ
diff --git a/lib/app/constants.dart b/lib/app/constants.dart
index 876921c..2eff59b 100644
--- a/lib/app/constants.dart
+++ b/lib/app/constants.dart
@@ -25,6 +25,18 @@ Map sortMapHistoryList = {
Sort.size_descending: 'Size - Large to Small',
};
+/// Default Asset Paths for the project
+class DefaultPaths {
+ /// Default Labels icons path
+ static const String defaultLabelIcons = 'assets/icons/';
+
+ /// Default Logos path
+ static const String defaultLogos = 'assets/logo/';
+
+ /// Default Animations path
+ static const String defaultAnimations = 'assets/animations/';
+}
+
/// APP RELEASE INFO
const String BUILD_NUMBER = '2';
const String RELEASE_DATE = '28.02.20';
diff --git a/lib/enums/enums.dart b/lib/enums/enums.dart
index ef8f2b2..eef0c17 100644
--- a/lib/enums/enums.dart
+++ b/lib/enums/enums.dart
@@ -44,3 +44,16 @@ enum IrssiButtons {
version,
none,
}
+
+/// Default Labels for Torrents
+enum DefaultLabelsEnum {
+ videos,
+ games,
+ music,
+ software,
+ movies,
+ documents,
+ pictures,
+ movies3d,
+ nolabel
+}
diff --git a/lib/main.dart b/lib/main.dart
index 06b8634..84463dd 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -4,7 +4,6 @@ import 'dart:async';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/material.dart';
-import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:hive/hive.dart';
import 'package:injectable/injectable.dart';
import 'package:path_provider/path_provider.dart';
@@ -15,8 +14,6 @@ import 'package:rutorrentflutter/services/state_services/user_preferences_servic
import 'package:rutorrentflutter/theme/app_state_notifier.dart';
import 'package:rutorrentflutter/theme/app_theme.dart';
import 'package:rutorrentflutter/ui/widgets/smart_widgets/bottom_sheets/bottom_sheet_setup.dart';
-import 'package:firebase_core/firebase_core.dart';
-import 'firebase_options.dart';
import 'package:stacked/stacked.dart';
import 'package:stacked_services/stacked_services.dart';
@@ -29,17 +26,18 @@ void main() async {
Hive.init(appDir.path);
await Hive.openBox('DB');
//To work in development environment, simply change the environment to Environment.dev below
- setupLocator(environment: Environment.prod);
+ await setupLocator(environment: Environment.prod);
//Setting custom Bottom Sheet
setUpBottomSheetUi();
//Setting up Services
- locator().init();
+ await locator().init();
await locator().init();
//Setting up Firebase
- await dotenv.load(fileName: ".env");
- await Firebase.initializeApp(
- options: DefaultFirebaseOptions.currentPlatform,
- );
+ //Comment this when you want to enter development mode
+ // await dotenv.load(fileName: ".env");
+ // await Firebase.initializeApp(
+ // options: DefaultFirebaseOptions.currentPlatform,
+ // );
// Make sure to comment out this line in development to see Errors
// FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterFatalError;
diff --git a/lib/models/mode.dart b/lib/models/mode.dart
index 8b46e0c..bf838a4 100644
--- a/lib/models/mode.dart
+++ b/lib/models/mode.dart
@@ -1,10 +1,10 @@
import 'package:flutter/foundation.dart';
class Mode extends ChangeNotifier {
- bool _darkMode = false;
+ static bool _darkMode = false;
- get isDarkMode => _darkMode;
- get isLightMode => !_darkMode;
+ static bool get isDarkMode => _darkMode;
+ static bool get isLightMode => !_darkMode;
toggleMode() {
_darkMode = !_darkMode;
diff --git a/lib/services/state_services/torrent_service.dart b/lib/services/state_services/torrent_service.dart
index c7e52d1..1db74a7 100644
--- a/lib/services/state_services/torrent_service.dart
+++ b/lib/services/state_services/torrent_service.dart
@@ -37,6 +37,7 @@ class TorrentService extends ChangeNotifier {
get selectedLabel => _selectedLabel;
get selectedFilter => _selectedFilter;
get sortPreference => _sortPreference;
+ Map get torrentCount => _countTorrents();
ValueNotifier> get listOfLabels => _listOfLabels;
ValueNotifier> get activeDownloads => _activeDownloads;
@@ -91,6 +92,7 @@ class TorrentService extends ChangeNotifier {
/// Updates display list of [Torrent]s Display List
updateTorrentDisplayList({String? searchText}) {
List displayList = torrentsList.value;
+
//Sorting: sorting data on basis of sortPreference
displayList = _sortList(displayList, sortPreference)!;
@@ -116,6 +118,37 @@ class TorrentService extends ChangeNotifier {
_torrentsDisplayList.notifyListeners();
}
+ Map _countTorrents() {
+ return {
+ Filter.All: torrentsList.value.length,
+ Filter.Downloading: torrentsList.value
+ .where((torrent) =>
+ torrent.status == Status.downloading ||
+ (torrent.status == Status.paused &&
+ torrent.status != Status.completed))
+ .toList()
+ .length,
+ Filter.Completed: torrentsList.value
+ .where((torrent) => torrent.status == Status.completed)
+ .toList()
+ .length,
+ Filter.Active: torrentsList.value
+ .where((torrent) => torrent.ulSpeed! > 0 || torrent.dlSpeed! > 0)
+ .toList()
+ .length,
+ Filter.Inactive: torrentsList.value
+ .where((torrent) => torrent.ulSpeed == 0 && torrent.dlSpeed == 0)
+ .toList()
+ .length,
+ Filter.Error: torrentsList.value
+ .where((torrent) =>
+ torrent.msg!.length > 0 &&
+ torrent.msg != 'Tracker: [Tried all trackers.]')
+ .toList()
+ .length,
+ };
+ }
+
List? _sortList(List? torrentsList, Sort? sort) {
switch (sort) {
case Sort.name_ascending:
diff --git a/lib/ui/views/History/history_view.dart b/lib/ui/views/History/history_view.dart
index 60ea6ab..0f7efc5 100644
--- a/lib/ui/views/History/history_view.dart
+++ b/lib/ui/views/History/history_view.dart
@@ -4,6 +4,7 @@ import 'package:flutter_svg/svg.dart';
import 'package:intl/intl.dart';
import 'package:rutorrentflutter/enums/enums.dart';
import 'package:rutorrentflutter/models/history_item.dart';
+import 'package:rutorrentflutter/models/mode.dart';
import 'package:rutorrentflutter/theme/app_state_notifier.dart';
import 'package:rutorrentflutter/ui/shared/shared_styles.dart';
import 'package:rutorrentflutter/ui/views/history/history_viewmodel.dart';
@@ -124,7 +125,7 @@ class HistoryView extends StatelessWidget {
})
: Center(
child: SvgPicture.asset(
- Theme.of(context).brightness == Brightness.light
+ Mode.isDarkMode
? 'assets/logo/empty.svg'
: 'assets/logo/empty_dark.svg',
width: 120,
diff --git a/lib/ui/widgets/dumb_widgets/filter_tile_list_widgets.dart b/lib/ui/widgets/dumb_widgets/filter_tile_list_widgets.dart
index 502ae86..074c120 100644
--- a/lib/ui/widgets/dumb_widgets/filter_tile_list_widgets.dart
+++ b/lib/ui/widgets/dumb_widgets/filter_tile_list_widgets.dart
@@ -8,8 +8,13 @@ class FilterTile extends StatelessWidget {
final DrawerViewModel model;
final Filter filter;
final IconData icon;
+ final int count;
- FilterTile({required this.model, required this.filter, required this.icon});
+ FilterTile(
+ {required this.model,
+ required this.filter,
+ required this.icon,
+ required this.count});
@override
Widget build(BuildContext context) {
@@ -27,6 +32,16 @@ class FilterTile extends StatelessWidget {
? Colors.black
: Colors.white,
),
+ trailing: Text(
+ '( $count )',
+ style: TextStyle(
+ color: isSelected
+ ? Colors.white
+ : !AppStateNotifier.isDarkModeOn
+ ? Colors.black
+ : Colors.white,
+ ),
+ ),
title: Text(
filter.toString().substring(filter.toString().indexOf('.') + 1),
style: TextStyle(
diff --git a/lib/ui/widgets/dumb_widgets/label_tile_widget.dart b/lib/ui/widgets/dumb_widgets/label_tile_widget.dart
index d3a0d2e..af0adf2 100644
--- a/lib/ui/widgets/dumb_widgets/label_tile_widget.dart
+++ b/lib/ui/widgets/dumb_widgets/label_tile_widget.dart
@@ -1,27 +1,45 @@
import 'package:flutter/material.dart';
+
+import 'package:rutorrentflutter/app/constants.dart';
+import 'package:rutorrentflutter/enums/enums.dart';
import 'package:rutorrentflutter/theme/app_state_notifier.dart';
import 'package:rutorrentflutter/ui/widgets/smart_widgets/Drawer/drawer_viewmodel.dart';
class LabelTile extends StatelessWidget {
final DrawerViewModel model;
final String label;
- LabelTile({required this.model, required this.label});
+ final Widget? icon;
+ LabelTile({
+ required this.model,
+ required this.label,
+ this.icon,
+ });
@override
Widget build(BuildContext context) {
bool isSelected = model.selectedLabel == label && model.isLabelSelected;
+
return Container(
color: isSelected ? Theme.of(context).colorScheme.secondary : null,
child: ListTile(
dense: true,
- leading: Icon(
- Icons.label_important_outline,
- color: isSelected
- ? Colors.white
- : !AppStateNotifier.isDarkModeOn
- ? Colors.black
- : Colors.white,
- ),
+ leading: DefaultLabelsEnum.values
+ .map((element) => element.name)
+ .toList()
+ .contains(label.replaceAll('_', '').replaceAll(' ', ''))
+ ? Image.asset(
+ '${DefaultPaths.defaultLabelIcons}${label.toLowerCase()}.png',
+ alignment: Alignment.centerLeft,
+ width: IconTheme.of(context).size,
+ )
+ : Icon(
+ Icons.label_important_outline,
+ color: isSelected
+ ? Colors.white
+ : !AppStateNotifier.isDarkModeOn
+ ? Colors.black
+ : Colors.white,
+ ),
title: Text(
label,
style: TextStyle(
diff --git a/lib/ui/widgets/smart_widgets/drawer/drawer_view.dart b/lib/ui/widgets/smart_widgets/drawer/drawer_view.dart
index 5d3f695..35e2929 100644
--- a/lib/ui/widgets/smart_widgets/drawer/drawer_view.dart
+++ b/lib/ui/widgets/smart_widgets/drawer/drawer_view.dart
@@ -11,7 +11,7 @@ import 'package:stacked/stacked.dart';
class DrawerView extends StatelessWidget {
final PackageInfo? packageInfo;
- DrawerView({this.packageInfo});
+ const DrawerView({this.packageInfo});
@override
Widget build(BuildContext context) {
@@ -28,8 +28,10 @@ class DrawerView extends StatelessWidget {
children: [
Image(
image: !AppStateNotifier.isDarkModeOn
- ? AssetImage('assets/logo/light_mode.png')
- : AssetImage('assets/logo/dark_mode.png'),
+ ? AssetImage(
+ '${DefaultPaths.defaultLogos}light_mode.png')
+ : AssetImage(
+ '${DefaultPaths.defaultLogos}dark_mode.png'),
),
SizedBox(height: 20),
Text(
diff --git a/lib/ui/widgets/smart_widgets/drawer/drawer_viewmodel.dart b/lib/ui/widgets/smart_widgets/drawer/drawer_viewmodel.dart
index 764a03a..74f9ba5 100644
--- a/lib/ui/widgets/smart_widgets/drawer/drawer_viewmodel.dart
+++ b/lib/ui/widgets/smart_widgets/drawer/drawer_viewmodel.dart
@@ -142,17 +142,22 @@ class DrawerViewModel extends BaseViewModel {
}
List _getFilterTileList(model) {
+ Map map = _torrentService!.torrentCount;
// ignore: unnecessary_cast
return filterTileIcons
.asMap()
.map((index, icon) =>
- MapEntry(index, _getFilterTile(index, icon, model)))
+ MapEntry(index, _getFilterTile(index, icon, model, map)))
.values
.toList() as List;
}
- FilterTile _getFilterTile(int index, icon, model) {
- return FilterTile(model: model, filter: Filter.values[index], icon: icon);
+ FilterTile _getFilterTile(int index, icon, model, map) {
+ return FilterTile(
+ model: model,
+ filter: Filter.values[index],
+ icon: icon,
+ count: map[Filter.values[index]]);
}
navigateToHistoryScreen() {
diff --git a/pubspec.yaml b/pubspec.yaml
index 1ee82dc..faa31ec 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -70,6 +70,7 @@ flutter:
assets:
- assets/logo/
- assets/animation/
+ - assets/icons/
# uncomment the below line when building a release for Playstore (app bundle or apk)
# - .env
diff --git a/test/helpers/test_helpers.mocks.dart b/test/helpers/test_helpers.mocks.dart
index dadad72..dd66cd8 100644
--- a/test/helpers/test_helpers.mocks.dart
+++ b/test/helpers/test_helpers.mocks.dart
@@ -56,8 +56,8 @@ import 'package:shared_preferences/shared_preferences.dart' as _i24;
// ignore_for_file: unnecessary_parenthesis
// ignore_for_file: camel_case_types
-class _FakeValueNotifier_0 extends _i1.Fake implements _i2.ValueNotifier {
-}
+class _FakeValueNotifier_0 extends _i1.Fake
+ implements _i2.ValueNotifier {}
class _FakeDiskSpace_1 extends _i1.Fake implements _i3.DiskSpace {}