wip: bloc for files
This commit is contained in:
		| @@ -8,6 +8,7 @@ import '../../../view/pages/more/roomplan/roomplan.dart'; | ||||
| import '../../../view/pages/talk/chatList.dart'; | ||||
| import '../../../view/pages/timetable/timetable.dart'; | ||||
| import '../../../widget/centeredLeading.dart'; | ||||
| import 'files/view/files_view.dart'; | ||||
| import 'gradeAverages/view/grade_averages_view.dart'; | ||||
| import 'holidays/view/holidays_view.dart'; | ||||
| import 'marianumMessage/view/marianum_message_list_view.dart'; | ||||
| @@ -23,6 +24,7 @@ class AppModule { | ||||
|     Modules.timetable: AppModule('Vertretung', Icons.calendar_month, Timetable.new), | ||||
|     Modules.talk: AppModule('Talk', Icons.chat, ChatList.new), | ||||
|     Modules.files: AppModule('Files', Icons.folder, Files.new), | ||||
|     Modules.blocFiles: AppModule('BlocFiles', Icons.folder, FilesView.new), | ||||
|     Modules.marianumMessage: AppModule('Marianum Message', Icons.newspaper, MarianumMessageListView.new), | ||||
|     Modules.roomPlan: AppModule('Raumplan', Icons.location_pin, Roomplan.new), | ||||
|     Modules.gradeAveragesCalculator: AppModule('Notendurschnittsrechner', Icons.calculate, GradeAveragesView.new), | ||||
| @@ -53,6 +55,7 @@ enum Modules { | ||||
|   timetable, | ||||
|   talk, | ||||
|   files, | ||||
|   blocFiles, | ||||
|   marianumMessage, | ||||
|   roomPlan, | ||||
|   gradeAveragesCalculator, | ||||
|   | ||||
							
								
								
									
										65
									
								
								lib/state/app/modules/files/bloc/files_bloc.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								lib/state/app/modules/files/bloc/files_bloc.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,65 @@ | ||||
|  | ||||
| import 'dart:developer'; | ||||
|  | ||||
| import '../../../infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc.dart'; | ||||
| import '../../../infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc_event.dart'; | ||||
| import '../repository/files_repository.dart'; | ||||
| import 'files_event.dart'; | ||||
| import 'files_state.dart'; | ||||
|  | ||||
| class FilesBloc extends LoadableHydratedBloc<FilesEvent, FilesState, FilesRepository> { | ||||
|   static const String basePath = '/'; | ||||
|  | ||||
|   FilesBloc() { | ||||
|     add(Emit((state) => state.copyWith(currentFolder: basePath))); | ||||
|     on<EnterFolder>((event, emit) { | ||||
|       add(Emit((state) { | ||||
|         log('setFolder'); | ||||
|         return state.copyWith(currentFolder: event.absolutePath); | ||||
|       }, fetch: true)); | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   List<File>? getVisibleFiles() => innerState?.files[innerState?.currentFolder]; | ||||
|   String getCurrentFolder() => innerState?.currentFolder ?? basePath; | ||||
|   String getCurrentFolderName() { | ||||
|     var folder = innerState?.currentFolder.split('/').reversed.elementAt(1); | ||||
|     return folder!.isEmpty ? 'Dateien' : folder; | ||||
|   } | ||||
|   bool canGoBack() => innerState?.currentFolder != basePath; | ||||
|   String goBackLocation() { | ||||
|     var pathSegments = innerState?.currentFolder.split(basePath) ?? []; | ||||
|     if (pathSegments.isNotEmpty) { | ||||
|       pathSegments.removeLast(); | ||||
|       pathSegments.removeLast(); | ||||
|     } | ||||
|     return pathSegments.join(basePath) + basePath; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   FilesState fromNothing() => const FilesState(currentFolder: basePath, files: {}); | ||||
|  | ||||
|   @override | ||||
|   FilesState fromStorage(Map<String, dynamic> json) => FilesState.fromJson(json); | ||||
|  | ||||
|   @override | ||||
|   Future<void> gatherData() async { | ||||
|     var fetchFolder = getCurrentFolder(); | ||||
|     log(fetchFolder); | ||||
|     var files = await repo.getFileList(fetchFolder); | ||||
|     var newFileMap = Map.of(innerState?.files ?? <String, List<File>>{}); | ||||
|     newFileMap[fetchFolder] = files; | ||||
|     if(fetchFolder != getCurrentFolder()) { | ||||
|       log('Fetch aborted due to folder change (expected "$fetchFolder" got "${getCurrentFolder()}")'); | ||||
|       return; | ||||
|     } | ||||
|     add(DataGathered((state) => state.copyWith(files: newFileMap))); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   FilesRepository repository() => FilesRepository(); | ||||
|  | ||||
|   @override | ||||
|   Map<String, dynamic>? toStorage(FilesState state) => state.toJson(); | ||||
|  | ||||
| } | ||||
							
								
								
									
										10
									
								
								lib/state/app/modules/files/bloc/files_event.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								lib/state/app/modules/files/bloc/files_event.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
|  | ||||
| import '../../../infrastructure/utilityWidgets/loadableHydratedBloc/loadable_hydrated_bloc_event.dart'; | ||||
| import 'files_state.dart'; | ||||
|  | ||||
| sealed class FilesEvent extends LoadableHydratedBlocEvent<FilesState> {} | ||||
| class EnterFolder extends FilesEvent { | ||||
|   String absolutePath; | ||||
|   EnterFolder(this.absolutePath); | ||||
| } | ||||
|  | ||||
							
								
								
									
										29
									
								
								lib/state/app/modules/files/bloc/files_state.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								lib/state/app/modules/files/bloc/files_state.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
| import 'package:freezed_annotation/freezed_annotation.dart'; | ||||
|  | ||||
| part 'files_state.freezed.dart'; | ||||
| part 'files_state.g.dart'; | ||||
|  | ||||
| @freezed | ||||
| class FilesState with _$FilesState { | ||||
|   const factory FilesState({ | ||||
|     required String currentFolder, | ||||
|     required Map<String, List<File>> files, | ||||
|   }) = _FilesState; | ||||
|  | ||||
|   factory FilesState.fromJson(Map<String, Object?> json) => _$FilesStateFromJson(json); | ||||
| } | ||||
|  | ||||
| @freezed | ||||
| class File with _$File { | ||||
|   const factory File({ | ||||
|     required String path, | ||||
|     required bool isFolder, | ||||
|     required String name, | ||||
|     required DateTime? createdAt, | ||||
|     required DateTime? updatedAt, | ||||
|     required int? size, | ||||
|     required String? mimeType, | ||||
|   }) = _File; | ||||
|  | ||||
|   factory File.fromJson(Map<String, Object?> json) => _$FileFromJson(json); | ||||
| } | ||||
							
								
								
									
										439
									
								
								lib/state/app/modules/files/bloc/files_state.freezed.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										439
									
								
								lib/state/app/modules/files/bloc/files_state.freezed.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,439 @@ | ||||
| // coverage:ignore-file | ||||
| // GENERATED CODE - DO NOT MODIFY BY HAND | ||||
| // ignore_for_file: type=lint | ||||
| // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark | ||||
|  | ||||
| part of 'files_state.dart'; | ||||
|  | ||||
| // ************************************************************************** | ||||
| // FreezedGenerator | ||||
| // ************************************************************************** | ||||
|  | ||||
| T _$identity<T>(T value) => value; | ||||
|  | ||||
| final _privateConstructorUsedError = UnsupportedError( | ||||
|     'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); | ||||
|  | ||||
| FilesState _$FilesStateFromJson(Map<String, dynamic> json) { | ||||
|   return _FilesState.fromJson(json); | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| mixin _$FilesState { | ||||
|   String get currentFolder => throw _privateConstructorUsedError; | ||||
|   Map<String, List<File>> get files => throw _privateConstructorUsedError; | ||||
|  | ||||
|   Map<String, dynamic> toJson() => throw _privateConstructorUsedError; | ||||
|   @JsonKey(ignore: true) | ||||
|   $FilesStateCopyWith<FilesState> get copyWith => | ||||
|       throw _privateConstructorUsedError; | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| abstract class $FilesStateCopyWith<$Res> { | ||||
|   factory $FilesStateCopyWith( | ||||
|           FilesState value, $Res Function(FilesState) then) = | ||||
|       _$FilesStateCopyWithImpl<$Res, FilesState>; | ||||
|   @useResult | ||||
|   $Res call({String currentFolder, Map<String, List<File>> files}); | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| class _$FilesStateCopyWithImpl<$Res, $Val extends FilesState> | ||||
|     implements $FilesStateCopyWith<$Res> { | ||||
|   _$FilesStateCopyWithImpl(this._value, this._then); | ||||
|  | ||||
|   // ignore: unused_field | ||||
|   final $Val _value; | ||||
|   // ignore: unused_field | ||||
|   final $Res Function($Val) _then; | ||||
|  | ||||
|   @pragma('vm:prefer-inline') | ||||
|   @override | ||||
|   $Res call({ | ||||
|     Object? currentFolder = null, | ||||
|     Object? files = null, | ||||
|   }) { | ||||
|     return _then(_value.copyWith( | ||||
|       currentFolder: null == currentFolder | ||||
|           ? _value.currentFolder | ||||
|           : currentFolder // ignore: cast_nullable_to_non_nullable | ||||
|               as String, | ||||
|       files: null == files | ||||
|           ? _value.files | ||||
|           : files // ignore: cast_nullable_to_non_nullable | ||||
|               as Map<String, List<File>>, | ||||
|     ) as $Val); | ||||
|   } | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| abstract class _$$FilesStateImplCopyWith<$Res> | ||||
|     implements $FilesStateCopyWith<$Res> { | ||||
|   factory _$$FilesStateImplCopyWith( | ||||
|           _$FilesStateImpl value, $Res Function(_$FilesStateImpl) then) = | ||||
|       __$$FilesStateImplCopyWithImpl<$Res>; | ||||
|   @override | ||||
|   @useResult | ||||
|   $Res call({String currentFolder, Map<String, List<File>> files}); | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| class __$$FilesStateImplCopyWithImpl<$Res> | ||||
|     extends _$FilesStateCopyWithImpl<$Res, _$FilesStateImpl> | ||||
|     implements _$$FilesStateImplCopyWith<$Res> { | ||||
|   __$$FilesStateImplCopyWithImpl( | ||||
|       _$FilesStateImpl _value, $Res Function(_$FilesStateImpl) _then) | ||||
|       : super(_value, _then); | ||||
|  | ||||
|   @pragma('vm:prefer-inline') | ||||
|   @override | ||||
|   $Res call({ | ||||
|     Object? currentFolder = null, | ||||
|     Object? files = null, | ||||
|   }) { | ||||
|     return _then(_$FilesStateImpl( | ||||
|       currentFolder: null == currentFolder | ||||
|           ? _value.currentFolder | ||||
|           : currentFolder // ignore: cast_nullable_to_non_nullable | ||||
|               as String, | ||||
|       files: null == files | ||||
|           ? _value._files | ||||
|           : files // ignore: cast_nullable_to_non_nullable | ||||
|               as Map<String, List<File>>, | ||||
|     )); | ||||
|   } | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| @JsonSerializable() | ||||
| class _$FilesStateImpl implements _FilesState { | ||||
|   const _$FilesStateImpl( | ||||
|       {required this.currentFolder, | ||||
|       required final Map<String, List<File>> files}) | ||||
|       : _files = files; | ||||
|  | ||||
|   factory _$FilesStateImpl.fromJson(Map<String, dynamic> json) => | ||||
|       _$$FilesStateImplFromJson(json); | ||||
|  | ||||
|   @override | ||||
|   final String currentFolder; | ||||
|   final Map<String, List<File>> _files; | ||||
|   @override | ||||
|   Map<String, List<File>> get files { | ||||
|     if (_files is EqualUnmodifiableMapView) return _files; | ||||
|     // ignore: implicit_dynamic_type | ||||
|     return EqualUnmodifiableMapView(_files); | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   String toString() { | ||||
|     return 'FilesState(currentFolder: $currentFolder, files: $files)'; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   bool operator ==(Object other) { | ||||
|     return identical(this, other) || | ||||
|         (other.runtimeType == runtimeType && | ||||
|             other is _$FilesStateImpl && | ||||
|             (identical(other.currentFolder, currentFolder) || | ||||
|                 other.currentFolder == currentFolder) && | ||||
|             const DeepCollectionEquality().equals(other._files, _files)); | ||||
|   } | ||||
|  | ||||
|   @JsonKey(ignore: true) | ||||
|   @override | ||||
|   int get hashCode => Object.hash( | ||||
|       runtimeType, currentFolder, const DeepCollectionEquality().hash(_files)); | ||||
|  | ||||
|   @JsonKey(ignore: true) | ||||
|   @override | ||||
|   @pragma('vm:prefer-inline') | ||||
|   _$$FilesStateImplCopyWith<_$FilesStateImpl> get copyWith => | ||||
|       __$$FilesStateImplCopyWithImpl<_$FilesStateImpl>(this, _$identity); | ||||
|  | ||||
|   @override | ||||
|   Map<String, dynamic> toJson() { | ||||
|     return _$$FilesStateImplToJson( | ||||
|       this, | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|  | ||||
| abstract class _FilesState implements FilesState { | ||||
|   const factory _FilesState( | ||||
|       {required final String currentFolder, | ||||
|       required final Map<String, List<File>> files}) = _$FilesStateImpl; | ||||
|  | ||||
|   factory _FilesState.fromJson(Map<String, dynamic> json) = | ||||
|       _$FilesStateImpl.fromJson; | ||||
|  | ||||
|   @override | ||||
|   String get currentFolder; | ||||
|   @override | ||||
|   Map<String, List<File>> get files; | ||||
|   @override | ||||
|   @JsonKey(ignore: true) | ||||
|   _$$FilesStateImplCopyWith<_$FilesStateImpl> get copyWith => | ||||
|       throw _privateConstructorUsedError; | ||||
| } | ||||
|  | ||||
| File _$FileFromJson(Map<String, dynamic> json) { | ||||
|   return _File.fromJson(json); | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| mixin _$File { | ||||
|   String get path => throw _privateConstructorUsedError; | ||||
|   bool get isFolder => throw _privateConstructorUsedError; | ||||
|   String get name => throw _privateConstructorUsedError; | ||||
|   DateTime? get createdAt => throw _privateConstructorUsedError; | ||||
|   DateTime? get updatedAt => throw _privateConstructorUsedError; | ||||
|   int? get size => throw _privateConstructorUsedError; | ||||
|   String? get mimeType => throw _privateConstructorUsedError; | ||||
|  | ||||
|   Map<String, dynamic> toJson() => throw _privateConstructorUsedError; | ||||
|   @JsonKey(ignore: true) | ||||
|   $FileCopyWith<File> get copyWith => throw _privateConstructorUsedError; | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| abstract class $FileCopyWith<$Res> { | ||||
|   factory $FileCopyWith(File value, $Res Function(File) then) = | ||||
|       _$FileCopyWithImpl<$Res, File>; | ||||
|   @useResult | ||||
|   $Res call( | ||||
|       {String path, | ||||
|       bool isFolder, | ||||
|       String name, | ||||
|       DateTime? createdAt, | ||||
|       DateTime? updatedAt, | ||||
|       int? size, | ||||
|       String? mimeType}); | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| class _$FileCopyWithImpl<$Res, $Val extends File> | ||||
|     implements $FileCopyWith<$Res> { | ||||
|   _$FileCopyWithImpl(this._value, this._then); | ||||
|  | ||||
|   // ignore: unused_field | ||||
|   final $Val _value; | ||||
|   // ignore: unused_field | ||||
|   final $Res Function($Val) _then; | ||||
|  | ||||
|   @pragma('vm:prefer-inline') | ||||
|   @override | ||||
|   $Res call({ | ||||
|     Object? path = null, | ||||
|     Object? isFolder = null, | ||||
|     Object? name = null, | ||||
|     Object? createdAt = freezed, | ||||
|     Object? updatedAt = freezed, | ||||
|     Object? size = freezed, | ||||
|     Object? mimeType = freezed, | ||||
|   }) { | ||||
|     return _then(_value.copyWith( | ||||
|       path: null == path | ||||
|           ? _value.path | ||||
|           : path // ignore: cast_nullable_to_non_nullable | ||||
|               as String, | ||||
|       isFolder: null == isFolder | ||||
|           ? _value.isFolder | ||||
|           : isFolder // ignore: cast_nullable_to_non_nullable | ||||
|               as bool, | ||||
|       name: null == name | ||||
|           ? _value.name | ||||
|           : name // ignore: cast_nullable_to_non_nullable | ||||
|               as String, | ||||
|       createdAt: freezed == createdAt | ||||
|           ? _value.createdAt | ||||
|           : createdAt // ignore: cast_nullable_to_non_nullable | ||||
|               as DateTime?, | ||||
|       updatedAt: freezed == updatedAt | ||||
|           ? _value.updatedAt | ||||
|           : updatedAt // ignore: cast_nullable_to_non_nullable | ||||
|               as DateTime?, | ||||
|       size: freezed == size | ||||
|           ? _value.size | ||||
|           : size // ignore: cast_nullable_to_non_nullable | ||||
|               as int?, | ||||
|       mimeType: freezed == mimeType | ||||
|           ? _value.mimeType | ||||
|           : mimeType // ignore: cast_nullable_to_non_nullable | ||||
|               as String?, | ||||
|     ) as $Val); | ||||
|   } | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| abstract class _$$FileImplCopyWith<$Res> implements $FileCopyWith<$Res> { | ||||
|   factory _$$FileImplCopyWith( | ||||
|           _$FileImpl value, $Res Function(_$FileImpl) then) = | ||||
|       __$$FileImplCopyWithImpl<$Res>; | ||||
|   @override | ||||
|   @useResult | ||||
|   $Res call( | ||||
|       {String path, | ||||
|       bool isFolder, | ||||
|       String name, | ||||
|       DateTime? createdAt, | ||||
|       DateTime? updatedAt, | ||||
|       int? size, | ||||
|       String? mimeType}); | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| class __$$FileImplCopyWithImpl<$Res> | ||||
|     extends _$FileCopyWithImpl<$Res, _$FileImpl> | ||||
|     implements _$$FileImplCopyWith<$Res> { | ||||
|   __$$FileImplCopyWithImpl(_$FileImpl _value, $Res Function(_$FileImpl) _then) | ||||
|       : super(_value, _then); | ||||
|  | ||||
|   @pragma('vm:prefer-inline') | ||||
|   @override | ||||
|   $Res call({ | ||||
|     Object? path = null, | ||||
|     Object? isFolder = null, | ||||
|     Object? name = null, | ||||
|     Object? createdAt = freezed, | ||||
|     Object? updatedAt = freezed, | ||||
|     Object? size = freezed, | ||||
|     Object? mimeType = freezed, | ||||
|   }) { | ||||
|     return _then(_$FileImpl( | ||||
|       path: null == path | ||||
|           ? _value.path | ||||
|           : path // ignore: cast_nullable_to_non_nullable | ||||
|               as String, | ||||
|       isFolder: null == isFolder | ||||
|           ? _value.isFolder | ||||
|           : isFolder // ignore: cast_nullable_to_non_nullable | ||||
|               as bool, | ||||
|       name: null == name | ||||
|           ? _value.name | ||||
|           : name // ignore: cast_nullable_to_non_nullable | ||||
|               as String, | ||||
|       createdAt: freezed == createdAt | ||||
|           ? _value.createdAt | ||||
|           : createdAt // ignore: cast_nullable_to_non_nullable | ||||
|               as DateTime?, | ||||
|       updatedAt: freezed == updatedAt | ||||
|           ? _value.updatedAt | ||||
|           : updatedAt // ignore: cast_nullable_to_non_nullable | ||||
|               as DateTime?, | ||||
|       size: freezed == size | ||||
|           ? _value.size | ||||
|           : size // ignore: cast_nullable_to_non_nullable | ||||
|               as int?, | ||||
|       mimeType: freezed == mimeType | ||||
|           ? _value.mimeType | ||||
|           : mimeType // ignore: cast_nullable_to_non_nullable | ||||
|               as String?, | ||||
|     )); | ||||
|   } | ||||
| } | ||||
|  | ||||
| /// @nodoc | ||||
| @JsonSerializable() | ||||
| class _$FileImpl implements _File { | ||||
|   const _$FileImpl( | ||||
|       {required this.path, | ||||
|       required this.isFolder, | ||||
|       required this.name, | ||||
|       required this.createdAt, | ||||
|       required this.updatedAt, | ||||
|       required this.size, | ||||
|       required this.mimeType}); | ||||
|  | ||||
|   factory _$FileImpl.fromJson(Map<String, dynamic> json) => | ||||
|       _$$FileImplFromJson(json); | ||||
|  | ||||
|   @override | ||||
|   final String path; | ||||
|   @override | ||||
|   final bool isFolder; | ||||
|   @override | ||||
|   final String name; | ||||
|   @override | ||||
|   final DateTime? createdAt; | ||||
|   @override | ||||
|   final DateTime? updatedAt; | ||||
|   @override | ||||
|   final int? size; | ||||
|   @override | ||||
|   final String? mimeType; | ||||
|  | ||||
|   @override | ||||
|   String toString() { | ||||
|     return 'File(path: $path, isFolder: $isFolder, name: $name, createdAt: $createdAt, updatedAt: $updatedAt, size: $size, mimeType: $mimeType)'; | ||||
|   } | ||||
|  | ||||
|   @override | ||||
|   bool operator ==(Object other) { | ||||
|     return identical(this, other) || | ||||
|         (other.runtimeType == runtimeType && | ||||
|             other is _$FileImpl && | ||||
|             (identical(other.path, path) || other.path == path) && | ||||
|             (identical(other.isFolder, isFolder) || | ||||
|                 other.isFolder == isFolder) && | ||||
|             (identical(other.name, name) || other.name == name) && | ||||
|             (identical(other.createdAt, createdAt) || | ||||
|                 other.createdAt == createdAt) && | ||||
|             (identical(other.updatedAt, updatedAt) || | ||||
|                 other.updatedAt == updatedAt) && | ||||
|             (identical(other.size, size) || other.size == size) && | ||||
|             (identical(other.mimeType, mimeType) || | ||||
|                 other.mimeType == mimeType)); | ||||
|   } | ||||
|  | ||||
|   @JsonKey(ignore: true) | ||||
|   @override | ||||
|   int get hashCode => Object.hash( | ||||
|       runtimeType, path, isFolder, name, createdAt, updatedAt, size, mimeType); | ||||
|  | ||||
|   @JsonKey(ignore: true) | ||||
|   @override | ||||
|   @pragma('vm:prefer-inline') | ||||
|   _$$FileImplCopyWith<_$FileImpl> get copyWith => | ||||
|       __$$FileImplCopyWithImpl<_$FileImpl>(this, _$identity); | ||||
|  | ||||
|   @override | ||||
|   Map<String, dynamic> toJson() { | ||||
|     return _$$FileImplToJson( | ||||
|       this, | ||||
|     ); | ||||
|   } | ||||
| } | ||||
|  | ||||
| abstract class _File implements File { | ||||
|   const factory _File( | ||||
|       {required final String path, | ||||
|       required final bool isFolder, | ||||
|       required final String name, | ||||
|       required final DateTime? createdAt, | ||||
|       required final DateTime? updatedAt, | ||||
|       required final int? size, | ||||
|       required final String? mimeType}) = _$FileImpl; | ||||
|  | ||||
|   factory _File.fromJson(Map<String, dynamic> json) = _$FileImpl.fromJson; | ||||
|  | ||||
|   @override | ||||
|   String get path; | ||||
|   @override | ||||
|   bool get isFolder; | ||||
|   @override | ||||
|   String get name; | ||||
|   @override | ||||
|   DateTime? get createdAt; | ||||
|   @override | ||||
|   DateTime? get updatedAt; | ||||
|   @override | ||||
|   int? get size; | ||||
|   @override | ||||
|   String? get mimeType; | ||||
|   @override | ||||
|   @JsonKey(ignore: true) | ||||
|   _$$FileImplCopyWith<_$FileImpl> get copyWith => | ||||
|       throw _privateConstructorUsedError; | ||||
| } | ||||
							
								
								
									
										50
									
								
								lib/state/app/modules/files/bloc/files_state.g.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								lib/state/app/modules/files/bloc/files_state.g.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | ||||
| // GENERATED CODE - DO NOT MODIFY BY HAND | ||||
|  | ||||
| part of 'files_state.dart'; | ||||
|  | ||||
| // ************************************************************************** | ||||
| // JsonSerializableGenerator | ||||
| // ************************************************************************** | ||||
|  | ||||
| _$FilesStateImpl _$$FilesStateImplFromJson(Map<String, dynamic> json) => | ||||
|     _$FilesStateImpl( | ||||
|       currentFolder: json['currentFolder'] as String, | ||||
|       files: (json['files'] as Map<String, dynamic>).map( | ||||
|         (k, e) => MapEntry( | ||||
|             k, | ||||
|             (e as List<dynamic>) | ||||
|                 .map((e) => File.fromJson(e as Map<String, dynamic>)) | ||||
|                 .toList()), | ||||
|       ), | ||||
|     ); | ||||
|  | ||||
| Map<String, dynamic> _$$FilesStateImplToJson(_$FilesStateImpl instance) => | ||||
|     <String, dynamic>{ | ||||
|       'currentFolder': instance.currentFolder, | ||||
|       'files': instance.files, | ||||
|     }; | ||||
|  | ||||
| _$FileImpl _$$FileImplFromJson(Map<String, dynamic> json) => _$FileImpl( | ||||
|       path: json['path'] as String, | ||||
|       isFolder: json['isFolder'] as bool, | ||||
|       name: json['name'] as String, | ||||
|       createdAt: json['createdAt'] == null | ||||
|           ? null | ||||
|           : DateTime.parse(json['createdAt'] as String), | ||||
|       updatedAt: json['updatedAt'] == null | ||||
|           ? null | ||||
|           : DateTime.parse(json['updatedAt'] as String), | ||||
|       size: (json['size'] as num?)?.toInt(), | ||||
|       mimeType: json['mimeType'] as String?, | ||||
|     ); | ||||
|  | ||||
| Map<String, dynamic> _$$FileImplToJson(_$FileImpl instance) => | ||||
|     <String, dynamic>{ | ||||
|       'path': instance.path, | ||||
|       'isFolder': instance.isFolder, | ||||
|       'name': instance.name, | ||||
|       'createdAt': instance.createdAt?.toIso8601String(), | ||||
|       'updatedAt': instance.updatedAt?.toIso8601String(), | ||||
|       'size': instance.size, | ||||
|       'mimeType': instance.mimeType, | ||||
|     }; | ||||
							
								
								
									
										31
									
								
								lib/state/app/modules/files/repository/files_repository.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								lib/state/app/modules/files/repository/files_repository.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
|  | ||||
| import 'package:nextcloud/nextcloud.dart'; | ||||
|  | ||||
| import '../../../../../api/marianumcloud/webdav/webdavApi.dart'; | ||||
| import '../../../infrastructure/repository/repository.dart'; | ||||
| import '../bloc/files_state.dart'; | ||||
|  | ||||
| class FilesRepository extends Repository<FilesState> { | ||||
|   Future<List<File>> getFileList(String path) async { | ||||
|     var webdav = await WebdavApi.webdav; | ||||
|     var response = await webdav.propfind(PathUri.parse(path)); // TODO move to custom data loader | ||||
|     var davFiles = response.toWebDavFiles(); | ||||
|  | ||||
|     davFiles.removeWhere((file) { | ||||
|       var filePath = file.path.path; | ||||
|       return filePath.isEmpty || filePath == path; | ||||
|     }); | ||||
|  | ||||
|     var files = davFiles.map((davFile) => File( | ||||
|       path: davFile.path.path, | ||||
|       isFolder: davFile.isDirectory, | ||||
|       name: davFile.name, | ||||
|       createdAt: davFile.createdDate, | ||||
|       updatedAt: davFile.lastModified, | ||||
|       size: davFile.size, | ||||
|       mimeType: davFile.mimeType | ||||
|     )); | ||||
|  | ||||
|     return files.toList(); | ||||
|   } | ||||
| } | ||||
							
								
								
									
										67
									
								
								lib/state/app/modules/files/view/files_view.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										67
									
								
								lib/state/app/modules/files/view/files_view.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,67 @@ | ||||
| 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'; | ||||
|  | ||||
| class FilesView extends StatelessWidget { | ||||
|   const FilesView({super.key}); | ||||
|  | ||||
|   @override | ||||
|   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)); | ||||
|                   }, | ||||
|                 )) | ||||
|             ) | ||||
|         ), | ||||
|       ); | ||||
|     }, | ||||
|   ); | ||||
| } | ||||
| @@ -11,7 +11,9 @@ _$GradeAveragesStateImpl _$$GradeAveragesStateImplFromJson( | ||||
|     _$GradeAveragesStateImpl( | ||||
|       gradingSystem: $enumDecode( | ||||
|           _$GradeAveragesGradingSystemEnumMap, json['gradingSystem']), | ||||
|       grades: (json['grades'] as List<dynamic>).map((e) => e as int).toList(), | ||||
|       grades: (json['grades'] as List<dynamic>) | ||||
|           .map((e) => (e as num).toInt()) | ||||
|           .toList(), | ||||
|     ); | ||||
|  | ||||
| Map<String, dynamic> _$$GradeAveragesStateImplToJson( | ||||
|   | ||||
| @@ -26,7 +26,7 @@ _$HolidayImpl _$$HolidayImplFromJson(Map<String, dynamic> json) => | ||||
|     _$HolidayImpl( | ||||
|       start: json['start'] as String, | ||||
|       end: json['end'] as String, | ||||
|       year: json['year'] as int, | ||||
|       year: (json['year'] as num).toInt(), | ||||
|       stateCode: json['stateCode'] as String, | ||||
|       name: json['name'] as String, | ||||
|       slug: json['slug'] as String, | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import 'package:dio/dio.dart'; | ||||
|  | ||||
| import '../../../basis/dataloader/holiday_data_loader.dart'; | ||||
| import '../../../infrastructure/dataLoader/data_loader.dart'; | ||||
| import '../../../infrastructure/dataLoader/http_data_loader.dart'; | ||||
| import '../bloc/holidays_state.dart'; | ||||
|  | ||||
| class HolidaysGetHolidays extends HolidayDataLoader<List<Holiday>> { | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| import 'package:dio/dio.dart'; | ||||
|  | ||||
| import '../../../infrastructure/dataLoader/data_loader.dart'; | ||||
| import '../../../infrastructure/dataLoader/http_data_loader.dart'; | ||||
| import '../../../basis/dataloader/mhsl_data_loader.dart'; | ||||
| import '../bloc/marianum_message_state.dart'; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user