From 676c219e3e6da54afa9891a65716c620594c75c9 Mon Sep 17 00:00:00 2001 From: Mohammed Mohsin Date: Tue, 1 Jun 2021 16:08:39 +0530 Subject: [PATCH] migrated to null safety --- example/lib/main.dart | 33 +++++-------- example/pubspec.yaml | 9 ++-- lib/src/bloc.dart | 80 +++++++++++++++--------------- lib/src/commands.dart | 2 +- lib/src/filex.dart | 89 +++++++++++++++++----------------- lib/src/models/actions.dart | 14 +++--- lib/src/models/filesystem.dart | 15 +++--- pubspec.yaml | 19 ++++---- 8 files changed, 125 insertions(+), 136 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index a7bff1c..ab5ace1 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -1,30 +1,20 @@ import 'dart:async'; -import 'dart:io'; import 'package:filex/filex.dart'; import 'package:flutter/material.dart'; import 'package:path_provider/path_provider.dart'; -import 'package:permission/permission.dart'; class _FileExplorerState extends State { var _ready = false; - FilexController controller; + FilexController? controller; - String _dirPath; + String _dirPath = ''; final _onReady = Completer(); Future getDir() async { //dir = await getApplicationDocumentsDirectory(); - final dir = await getExternalStorageDirectory(); - switch (Platform.isAndroid) { - case true: - _dirPath = dir.path - .replaceFirst("Android/data/com.example.filex_example/files", ""); - break; - default: - _dirPath = dir.path; - } - + final dir = await getApplicationDocumentsDirectory(); + _dirPath = dir.path; print("Storage dir: $_dirPath"); _onReady.complete(); } @@ -32,12 +22,13 @@ class _FileExplorerState extends State { @override void initState() { getDir(); + if (_onReady.isCompleted) { + controller = FilexController(path: _dirPath); + setState(() { + _ready = true; + }); + } super.initState(); - Permission.requestPermissions([PermissionName.Storage]) - .then((_) => _onReady.future.then((_) { - controller = FilexController(path: _dirPath); - setState(() => _ready = true); - })); } @override @@ -48,13 +39,13 @@ class _FileExplorerState extends State { actions: [ IconButton( icon: const Icon(Icons.add), - onPressed: () => controller.addDirectory(context), + onPressed: () => controller!.addDirectory(context), ) ], ), body: _ready ? Filex( - controller: controller, + controller: controller!, actions: [PredefinedAction.delete], ) : const Center(child: CircularProgressIndicator()), diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 18750f3..9a86de2 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -18,15 +18,14 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: ">=2.7.0 <3.0.0" + sdk: ">=2.12.2 <3.0.0" dependencies: - flutter: - sdk: flutter filex: path: ../ - path_provider: ^1.6.24 - permission: ^0.1.7 + flutter: + sdk: flutter + path_provider: ^2.0.2 dev_dependencies: flutter_test: diff --git a/lib/src/bloc.dart b/lib/src/bloc.dart index 394745d..ef2315b 100644 --- a/lib/src/bloc.dart +++ b/lib/src/bloc.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'dart:io'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:rxdart/rxdart.dart' as rx; @@ -11,40 +10,40 @@ import "models/filesystem.dart"; /// The main controller class FilexController { /// Provide a path - FilexController({@required this.path}) { + FilexController({required this.path}) { _bloc = _FilexBloc(path: path, itemController: _itemStream); directory = Directory(path); assert( - directory.existsSync(), "Directory ${directory.path} does not exist"); + directory!.existsSync(), "Directory ${directory!.path} does not exist"); } /// Current directory - Directory directory; + Directory? directory; /// The current path to use final String path; - _FilexBloc _bloc; + _FilexBloc? _bloc; final _itemStream = rx.ReplaySubject>(); /// Setter for show only dirs setting - set showOnlyDirectories(bool v) => _bloc.showOnlyDirectories = v; + set showOnlyDirectories(bool v) => _bloc!.showOnlyDirectories = v; /// Setter for show hidden files setting - set showHiddenFiles(bool v) => _bloc.showHiddenFiles = v; + set showHiddenFiles(bool v) => _bloc!.showHiddenFiles = v; /// Stream of directory items Stream> get changefeed => _itemStream.stream; /// Delete a file or directory - Future delete(DirectoryItem item) async => _bloc.deleteItem(item); + Future delete(DirectoryItem item) async => _bloc!.deleteItem(item); /// Create a directory Future createDirectory(String name) async => - _bloc.createDir(directory, name); + _bloc!.createDir(directory!, name); /// List a directory content - Future ls() async => _bloc.lsDir(directory); + Future ls() async => _bloc!.lsDir(directory!); /// Dispose the controller when finished using void dispose() { @@ -58,45 +57,46 @@ class FilexController { builder: (BuildContext context) { final _addDirController = TextEditingController(); return AlertDialog( - title: const Text("Create a directory"), - actions: [ - FlatButton( - child: const Text("Cancel"), - onPressed: () { - Navigator.of(context).pop(); - }, - ), - FlatButton( - child: const Text("Create"), - onPressed: () { - createDirectory(_addDirController.text); - Navigator.of(context).pop(); - }, - ), - ], - content: SingleChildScrollView( - child: ListBody( - children: [ - TextField( - controller: _addDirController, - autofocus: true, - autocorrect: false, - ), - ], - ), - )); + title: const Text("Create a directory"), + actions: [ + TextButton( + child: const Text("Cancel"), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + TextButton( + child: const Text("Create"), + onPressed: () { + createDirectory(_addDirController.text); + Navigator.of(context).pop(); + }, + ), + ], + content: SingleChildScrollView( + child: ListBody( + children: [ + TextField( + controller: _addDirController, + autofocus: true, + autocorrect: false, + ), + ], + ), + ), + ); }, ); } } class _FilexBloc { - _FilexBloc({@required this.path, @required this.itemController}); + _FilexBloc({required this.path, required this.itemController}); final String path; final StreamController> itemController; - bool showOnlyDirectories; - bool showHiddenFiles; + bool showOnlyDirectories = false; + bool showHiddenFiles = false; Future deleteItem(DirectoryItem item) async { try { diff --git a/lib/src/commands.dart b/lib/src/commands.dart index 4f690e4..217fa77 100644 --- a/lib/src/commands.dart +++ b/lib/src/commands.dart @@ -29,7 +29,7 @@ Future mkdir(Directory currentDir, String name) async { /// List items in directory ListedDirectory getListedDirectory(Directory dir, - {bool showHiddenFiles, bool showOnlyDirectories}) { + {bool showHiddenFiles = false, bool showOnlyDirectories = false}) { //print("LIST DIR ${dir.path}"); final contents = dir.listSync()..sort((a, b) => a.path.compareTo(b.path)); final dirs = []; diff --git a/lib/src/filex.dart b/lib/src/filex.dart index 3fa5a2c..fe1a454 100644 --- a/lib/src/filex.dart +++ b/lib/src/filex.dart @@ -1,5 +1,4 @@ import 'dart:io'; - import 'package:flutter/material.dart'; import 'package:flutter_slidable/flutter_slidable.dart'; import 'package:open_file/open_file.dart'; @@ -11,9 +10,9 @@ import "models/filesystem.dart"; class _FilexState extends State { _FilexState( - {@required this.controller, - this.showHiddenFiles, - this.showOnlyDirectories, + {required this.controller, + this.showHiddenFiles = false, + this.showOnlyDirectories = false, this.fileTrailingBuilder, this.directoryTrailingBuilder, this.fileLeadingBuilder, @@ -21,7 +20,7 @@ class _FilexState extends State { this.compact, this.actions, this.extraActions}) { - _initialDirectory = controller.directory; + _initialDirectory = controller.directory!; controller ..showOnlyDirectories = showOnlyDirectories ..showHiddenFiles = showHiddenFiles @@ -30,19 +29,19 @@ class _FilexState extends State { final bool showHiddenFiles; final bool showOnlyDirectories; - final FilexActionBuilder fileLeadingBuilder; - final FilexActionBuilder fileTrailingBuilder; - final FilexActionBuilder directoryTrailingBuilder; - final FilexActionBuilder directoryLeadingBuilder; - final bool compact; - final List actions; - final List extraActions; + final FilexActionBuilder? fileLeadingBuilder; + final FilexActionBuilder? fileTrailingBuilder; + final FilexActionBuilder? directoryTrailingBuilder; + final FilexActionBuilder? directoryLeadingBuilder; + final bool? compact; + final List? actions; + final List? extraActions; final FilexController controller; - SlidableController _slidableController; + SlidableController? _slidableController; final ScrollController _scrollController = ScrollController(); bool _isBuilt = false; - Directory _initialDirectory; + late Directory _initialDirectory; @override Widget build(BuildContext context) { @@ -57,24 +56,24 @@ class _FilexState extends State { final builder = ListView.builder( controller: _scrollController, shrinkWrap: true, - itemCount: snapshot.data.length, + itemCount: snapshot.data!.length, itemBuilder: (BuildContext context, int index) { - final item = snapshot.data[index]; + final item = snapshot.data![index]; Widget w; - if (actions.isNotEmpty) { + if (actions!.isNotEmpty) { w = Slidable( key: Key(item.filename), controller: _slidableController, direction: Axis.horizontal, actionPane: const SlidableDrawerActionPane(), actionExtentRatio: 0.25, - child: compact + child: compact! ? _buildCompactVerticalListItem(context, item) : _buildVerticalListItem(context, item), actions: _getSlideIconActions(context, item), ); } else { - if (compact) { + if (compact!) { w = _buildCompactVerticalListItem(context, item); } else { w = _buildVerticalListItem(context, item); @@ -82,13 +81,13 @@ class _FilexState extends State { } return w; }); - if (controller.directory.path != _initialDirectory.path) { + if (controller.directory!.path != _initialDirectory.path) { _isBuilt = true; return Column( - children: [ - _topNavigation(), - Expanded(child: builder) - ] + children: [ + _topNavigation(), + Expanded(child: builder), + ], ); } else { _isBuilt = true; @@ -96,10 +95,12 @@ class _FilexState extends State { } } else { return Center( - child: Padding( - padding: EdgeInsets.only( - top: MediaQuery.of(context).size.height / 0.8), - child: const CircularProgressIndicator())); + child: Padding( + padding: EdgeInsets.only( + top: MediaQuery.of(context).size.height / 0.8), + child: const CircularProgressIndicator(), + ), + ); } }, ); @@ -112,7 +113,7 @@ class _FilexState extends State { title: Text("..", textScaleFactor: 1.5), ), onTap: () { - final li = controller.directory.path.split("/")..removeLast(); + final li = controller.directory!.path.split("/")..removeLast(); controller.directory = Directory(li.join("/")); unawaited(controller.ls()); }, @@ -146,7 +147,7 @@ class _FilexState extends State { void _onTapDirectory(DirectoryItem item) { if (item.isDirectory) { - final p = controller.directory.path + "/" + item.filename; + final p = controller.directory!.path + "/" + item.filename; controller ..directory = Directory(p) ..ls(); @@ -160,12 +161,12 @@ class _FilexState extends State { if (item.isDirectory) { switch (directoryLeadingBuilder != null) { case true: - w = directoryLeadingBuilder(context, item); + w = directoryLeadingBuilder!(context, item); } } else { switch (fileLeadingBuilder != null) { case true: - w = fileLeadingBuilder(context, item); + w = fileLeadingBuilder!(context, item); break; default: } @@ -178,14 +179,14 @@ class _FilexState extends State { switch (item.isDirectory) { case true: if (directoryTrailingBuilder != null) { - w = directoryTrailingBuilder(context, item); + w = directoryTrailingBuilder!(context, item); } else { w = const Text(""); } break; default: if (fileTrailingBuilder != null) { - w = fileTrailingBuilder(context, item); + w = fileTrailingBuilder!(context, item); } else { w = Text("${item.filesize}"); } @@ -195,7 +196,7 @@ class _FilexState extends State { List _getSlideIconActions(BuildContext context, DirectoryItem item) { final ic = []; - if (actions.contains(PredefinedAction.delete)) { + if (actions!.contains(PredefinedAction.delete)) { ic.add(IconSlideAction( caption: 'Delete', color: Colors.red, @@ -203,8 +204,8 @@ class _FilexState extends State { onTap: () => _confirmDeleteDialog(context, item), )); } - if (extraActions.isNotEmpty) { - for (final action in extraActions) { + if (extraActions!.isNotEmpty) { + for (final action in extraActions!) { ic.add(IconSlideAction( caption: action.name, color: action.color, @@ -223,15 +224,15 @@ class _FilexState extends State { return AlertDialog( title: Text("Delete ${item.filename}?"), actions: [ - FlatButton( + TextButton( child: const Text("Cancel"), onPressed: () { Navigator.of(context).pop(); }, ), - FlatButton( + TextButton( child: const Text("Delete"), - color: Colors.red, + style: TextButton.styleFrom(backgroundColor: Colors.red), onPressed: () { controller.delete(item).then((_) { Navigator.of(context).pop(); @@ -260,7 +261,7 @@ class _FilexState extends State { class Filex extends StatefulWidget { /// Provide a directory to start from const Filex( - {@required this.controller, + {/*required*/ required this.controller, this.showHiddenFiles = false, this.showOnlyDirectories = false, this.fileTrailingBuilder, @@ -283,13 +284,13 @@ class Filex extends StatefulWidget { final bool showOnlyDirectories; /// Trailing builder for files - final FilexActionBuilder fileTrailingBuilder; + final FilexActionBuilder? fileTrailingBuilder; /// Trailing builder for directory - final FilexActionBuilder directoryTrailingBuilder; + final FilexActionBuilder? directoryTrailingBuilder; /// Leading builder for directory - final FilexActionBuilder directoryLeadingBuilder; + final FilexActionBuilder? directoryLeadingBuilder; /// Extra slidable actions final List extraActions; diff --git a/lib/src/models/actions.dart b/lib/src/models/actions.dart index b76dada..e5b163b 100644 --- a/lib/src/models/actions.dart +++ b/lib/src/models/actions.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter/foundation.dart'; import 'filesystem.dart'; /// Actions on slidable @@ -9,20 +8,21 @@ enum PredefinedAction { } /// Action builder for leading and trailing widgets -typedef Widget FilexActionBuilder(BuildContext context, DirectoryItem item); +typedef FilexActionBuilder = Widget Function( + BuildContext context, DirectoryItem item); /// Action builder for slidable actions -typedef void FilexSlidableActionBuilder( +typedef FilexSlidableActionBuilder = void Function( BuildContext context, DirectoryItem item); /// Action for slidable class FilexSlidableAction { /// Default constructor FilexSlidableAction( - {@required this.color, - @required this.iconData, - @required this.name, - @required this.onTap}); + {required this.color, + required this.iconData, + required this.name, + required this.onTap}); final Color color; final IconData iconData; diff --git a/lib/src/models/filesystem.dart b/lib/src/models/filesystem.dart index 885f131..1ca56fa 100644 --- a/lib/src/models/filesystem.dart +++ b/lib/src/models/filesystem.dart @@ -1,7 +1,6 @@ import 'dart:io'; import 'package:path/path.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/foundation.dart'; import 'package:filesize/filesize.dart' as fs; import '../file_icons.dart'; @@ -9,9 +8,9 @@ import '../file_icons.dart'; class ListedDirectory { /// Default constructor ListedDirectory( - {@required this.directory, - @required this.listedDirectories, - @required this.listedFiles}) { + {required this.directory, + required this.listedDirectories, + required this.listedFiles}) { _getItems(); } @@ -24,7 +23,7 @@ class ListedDirectory { /// The files in the directory final List listedFiles; - List _items; + late List _items; /// All the directory items List get items => _items; @@ -45,7 +44,7 @@ class ListedDirectory { /// A subdirectory item: file or directory class DirectoryItem { /// Default constructor - DirectoryItem({@required this.item}) { + DirectoryItem({required this.item}) { _filesize = _getFilesize(item); _filename = basename(item.path); _icon = _setIcon(item, _filename); @@ -54,8 +53,8 @@ class DirectoryItem { /// The subdirectory or file final FileSystemEntity item; - String _filename; - Icon _icon; + late String _filename; + late Icon _icon; String _filesize = ""; /// The icon too display diff --git a/pubspec.yaml b/pubspec.yaml index eff49db..558d830 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -5,20 +5,19 @@ homepage: https://github.com/synw/filex version: 0.3.0 environment: - sdk: ">=2.3.0 <3.0.0" + sdk: ">=2.12.2 <3.0.0" dependencies: + extra_pedantic: ^1.5.0 + filesize: ^2.0.1 flutter: sdk: flutter - extra_pedantic: ^1.2.0 - filesize: ^1.0.4 - flutter_slidable: ^0.5.7 - open_file: ^3.0.3 - path: ^1.7.0 - path_provider: ^1.6.24 - pedantic: ^1.9.2 - permission: ^0.1.7 - rxdart: ^0.25.0 + flutter_slidable: ^0.6.0 + open_file: ^3.2.1 + path: ^1.8.0 + path_provider: ^2.0.2 + pedantic: ^1.11.0 + rxdart: ^0.27.1 dev_dependencies: flutter_test: