wip: bloc for files
This commit is contained in:
		| @@ -97,7 +97,7 @@ class _AppState extends State<App> with WidgetsBindingObserver { | ||||
|     controller: Main.bottomNavigator, | ||||
|     navBarOverlap: const NavBarOverlap.none(), | ||||
|     backgroundColor: Theme.of(context).colorScheme.primary, | ||||
|     handleAndroidBackButtonPress: false, | ||||
|     handleAndroidBackButtonPress: true, | ||||
|  | ||||
|     screenTransitionAnimation: const ScreenTransitionAnimation(curve: Curves.easeOutQuad, duration: Duration(milliseconds: 200)), | ||||
|     tabs: [ | ||||
|   | ||||
| @@ -17,13 +17,16 @@ class LoadableStateConsumer<TController extends Bloc<LoadableHydratedBlocEvent<T | ||||
|   final Widget Function(TState state, bool loading) child; | ||||
|   final void Function(TState state)? onLoad; | ||||
|   final bool wrapWithScrollView; | ||||
|   const LoadableStateConsumer({required this.child, this.onLoad, this.wrapWithScrollView = false, super.key}); | ||||
|   final TController? controllerByValue; | ||||
|   const LoadableStateConsumer({required this.child, this.onLoad, this.wrapWithScrollView = false, this.controllerByValue = null, super.key}); | ||||
|  | ||||
|   static Duration animationDuration = const Duration(milliseconds: 200); | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) { | ||||
|     var loadableState = context.watch<TController>().state; | ||||
|     var loadableState = controllerByValue != null | ||||
|         ? controllerByValue!.state | ||||
|         : context.watch<TController>().state; | ||||
|  | ||||
|     if(!loadableState.isLoading && onLoad != null) { | ||||
|       WidgetsBinding.instance.addPostFrameCallback((timeStamp) => onLoad!(loadableState.data)); | ||||
|   | ||||
| @@ -1,6 +1,8 @@ | ||||
|  | ||||
| import 'dart:developer'; | ||||
|  | ||||
| import 'package:sorted/sorted.dart'; | ||||
|  | ||||
| import '../../../infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc.dart'; | ||||
| import '../../../infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc_event.dart'; | ||||
| import '../repository/files_repository.dart'; | ||||
| @@ -36,6 +38,10 @@ class FilesBloc extends LoadableHydratedBloc<FilesEvent, FilesState, FilesReposi | ||||
|     return pathSegments.join(basePath) + basePath; | ||||
|   } | ||||
|  | ||||
|   List currentSortConfiguration() => [ | ||||
|     SortedComparable<File, DateTime>((file) => file.updatedAt ?? DateTime.now()), | ||||
|   ]; | ||||
|  | ||||
|   @override | ||||
|   FilesState fromNothing() => const FilesState(currentFolder: basePath, files: {}); | ||||
|  | ||||
|   | ||||
| @@ -1,17 +1,9 @@ | ||||
| import 'dart:developer'; | ||||
|  | ||||
| import 'package:filesize/filesize.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:jiffy/jiffy.dart'; | ||||
|  | ||||
| import '../../../../../widget/centeredLeading.dart'; | ||||
| import '../../../../../widget/list_view_util.dart'; | ||||
| import '../../../infrastructure/loadableState/loadable_state.dart'; | ||||
| import '../../../infrastructure/loadableState/view/loadable_state_consumer.dart'; | ||||
| import '../../../infrastructure/utilityWidgets/bloc_module.dart'; | ||||
| import '../bloc/files_bloc.dart'; | ||||
| import '../bloc/files_event.dart'; | ||||
| import '../bloc/files_state.dart'; | ||||
| import 'folder_view.dart'; | ||||
|  | ||||
| class FilesView extends StatelessWidget { | ||||
|   const FilesView({super.key}); | ||||
| @@ -20,48 +12,6 @@ class FilesView extends StatelessWidget { | ||||
|   Widget build(BuildContext context) => BlocModule<FilesBloc, LoadableState<FilesState>>( | ||||
|     create: (context) => FilesBloc(), | ||||
|     autoRebuild: true, | ||||
|     child: (context, bloc, state) { | ||||
|       var goBackButton = !bloc.canGoBack() ? null : IconButton( | ||||
|         icon: const Icon(Icons.arrow_back), | ||||
|         onPressed: () { | ||||
|           bloc.add(EnterFolder(bloc.goBackLocation())); | ||||
|         }, | ||||
|       ); | ||||
|       return PopScope( | ||||
|         canPop: false, | ||||
|         onPopInvoked: (didPop) => bloc.add(EnterFolder(bloc.goBackLocation())), | ||||
|         child: Scaffold( | ||||
|             appBar: AppBar( | ||||
|               leading: goBackButton, | ||||
|               title: Text(bloc.getCurrentFolderName()), | ||||
|  | ||||
|  | ||||
|               actions: [ | ||||
|                 IconButton(onPressed: () { | ||||
|                   log(bloc.innerState?.toJson().toString() ?? 'leer'); | ||||
|                 }, icon: const Icon(Icons.bug_report)), | ||||
|                 IconButton(onPressed: () { | ||||
|                   bloc.add(EnterFolder('/')); | ||||
|                 }, icon: const Icon(Icons.home)), | ||||
|               ], | ||||
|             ), | ||||
|             body: LoadableStateConsumer<FilesBloc, FilesState>( | ||||
|                 child: (state, loading) => ListViewUtil.fromList<File>(bloc.getVisibleFiles(), (file) => ListTile( | ||||
|                   leading: CenteredLeading(Icon(file.isFolder ? Icons.folder : Icons.description_outlined)), | ||||
|                   title: Text(file.name), | ||||
|                   subtitle: file.isFolder | ||||
|                       ? Text('geändert ${Jiffy.parseFromDateTime(file.updatedAt ?? DateTime.now()).fromNow()}') | ||||
|                       : Text('${filesize(file.size)}, ${Jiffy.parseFromDateTime(file.updatedAt ?? DateTime.now()).fromNow()}'), | ||||
|                   trailing: Icon(file.isFolder ? Icons.arrow_right : null), | ||||
|                   onTap: () { | ||||
|                     log(file.path); | ||||
|                     if(!file.isFolder) return; | ||||
|                     bloc.add(EnterFolder(file.path)); | ||||
|                   }, | ||||
|                 )) | ||||
|             ) | ||||
|         ), | ||||
|       ); | ||||
|     }, | ||||
|     child: (context, bloc, state) => FolderView(bloc), | ||||
|   ); | ||||
| } | ||||
|   | ||||
							
								
								
									
										57
									
								
								lib/state/app/modules/files/view/folder_view.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								lib/state/app/modules/files/view/folder_view.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,57 @@ | ||||
| import 'dart:developer'; | ||||
|  | ||||
| import 'package:filesize/filesize.dart'; | ||||
| import 'package:flutter/material.dart'; | ||||
| import 'package:jiffy/jiffy.dart'; | ||||
|  | ||||
| import '../../../../../widget/centeredLeading.dart'; | ||||
| import '../../../../../widget/list_view_util.dart'; | ||||
| import '../../../infrastructure/loadableState/view/loadable_state_consumer.dart'; | ||||
| import '../bloc/files_bloc.dart'; | ||||
| import '../bloc/files_event.dart'; | ||||
| import '../bloc/files_state.dart'; | ||||
|  | ||||
| class FolderView extends StatelessWidget { | ||||
|   final FilesBloc bloc; | ||||
|   const FolderView(this.bloc, {super.key}); | ||||
|  | ||||
|   @override | ||||
|   Widget build(BuildContext context) => Scaffold( | ||||
|         appBar: AppBar( | ||||
|           leading: !bloc.canGoBack() ? null : IconButton( | ||||
|             icon: const Icon(Icons.arrow_back), | ||||
|             onPressed: () { | ||||
|               bloc.add(EnterFolder(bloc.goBackLocation())); | ||||
|               Navigator.of(context).pop(); | ||||
|             }, | ||||
|           ), | ||||
|           title: Text(bloc.getCurrentFolderName()), | ||||
|  | ||||
|           actions: [ | ||||
|             IconButton(onPressed: () { | ||||
|               log(bloc.innerState?.toJson().toString() ?? 'leer'); | ||||
|             }, icon: const Icon(Icons.bug_report)), | ||||
|             IconButton(onPressed: () { | ||||
|               bloc.add(EnterFolder('/')); | ||||
|             }, icon: const Icon(Icons.home)), | ||||
|           ], | ||||
|         ), | ||||
|         body: LoadableStateConsumer<FilesBloc, FilesState>( | ||||
|           controllerByValue: bloc, | ||||
|             child: (state, loading) => ListViewUtil.fromList<File>(bloc.getVisibleFiles(), (file) => ListTile( | ||||
|               leading: CenteredLeading(Icon(file.isFolder ? Icons.folder : Icons.description_outlined)), | ||||
|               title: Text(file.name), | ||||
|               subtitle: file.isFolder | ||||
|                   ? Text('geändert ${Jiffy.parseFromDateTime(file.updatedAt ?? DateTime.now()).fromNow()}') | ||||
|                   : Text('${filesize(file.size)}, ${Jiffy.parseFromDateTime(file.updatedAt ?? DateTime.now()).fromNow()}'), | ||||
|               trailing: Icon(file.isFolder ? Icons.arrow_right : null), | ||||
|               onTap: () { | ||||
|                 log(file.path); | ||||
|                 if(!file.isFolder) return; | ||||
|                 Navigator.of(context).push(MaterialPageRoute(builder: (context) => FolderView(bloc))); | ||||
|                 bloc.add(EnterFolder(file.path)); | ||||
|               }, | ||||
|             )) | ||||
|         ) | ||||
|     ); | ||||
| } | ||||
| @@ -8,6 +8,6 @@ class LightAppTheme { | ||||
|     colorScheme: ColorScheme.fromSeed(seedColor: marianumRed), | ||||
|     floatingActionButtonTheme: const FloatingActionButtonThemeData( | ||||
|       foregroundColor: Colors.white | ||||
|     ) | ||||
|     ), | ||||
|   ); | ||||
| } | ||||
|   | ||||
| @@ -104,6 +104,7 @@ dependencies: | ||||
|   connectivity_plus: ^6.0.3 | ||||
|   hydrated_bloc: ^9.1.5 | ||||
|   dio: ^4.0.6 | ||||
|   sorted: ^2.1.0 | ||||
|  | ||||
| dev_dependencies: | ||||
|   flutter_test: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user