implemented new loadable state concept
This commit is contained in:
parent
f58a2ec8cd
commit
6ad8203b6a
4
lib/state/app/infrastructure/dataLoader/data_loader.dart
Normal file
4
lib/state/app/infrastructure/dataLoader/data_loader.dart
Normal file
@ -0,0 +1,4 @@
|
||||
abstract class DataLoader<TResult> {
|
||||
|
||||
Future<TResult> fetch();
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
|
||||
import '../../../../infrastructure/controller.dart';
|
||||
import 'error_bar_state.dart';
|
||||
import 'loadable_state_state.dart';
|
||||
|
||||
class ErrorBarController extends Controller<ErrorBarState> {
|
||||
class LoadableStateBloc extends Bloc<void, LoadableStateState> {
|
||||
late StreamSubscription<List<ConnectivityResult>> _updateStream;
|
||||
|
||||
ErrorBarController() : super(const ErrorBarState(connections: null)) {
|
||||
LoadableStateBloc() : super(const LoadableStateState(connections: null)) {
|
||||
emitState(List<ConnectivityResult> v) => emit(state.copyWith(connections: v));
|
||||
|
||||
Connectivity().checkConnectivity().then(emitState);
|
@ -1,11 +1,11 @@
|
||||
import 'package:connectivity_plus/connectivity_plus.dart';
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'error_bar_state.freezed.dart';
|
||||
part 'loadable_state_state.freezed.dart';
|
||||
|
||||
@freezed
|
||||
class ErrorBarState with _$ErrorBarState {
|
||||
const factory ErrorBarState({
|
||||
class LoadableStateState with _$LoadableStateState {
|
||||
const factory LoadableStateState({
|
||||
required List<ConnectivityResult>? connections,
|
||||
}) = _ErrorBarState;
|
||||
}) = _LoadableStateState;
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
// 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 'error_bar_state.dart';
|
||||
part of 'loadable_state_state.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// FreezedGenerator
|
||||
@ -15,28 +15,28 @@ 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');
|
||||
|
||||
/// @nodoc
|
||||
mixin _$ErrorBarState {
|
||||
mixin _$LoadableStateState {
|
||||
List<ConnectivityResult>? get connections =>
|
||||
throw _privateConstructorUsedError;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
$ErrorBarStateCopyWith<ErrorBarState> get copyWith =>
|
||||
$LoadableStateStateCopyWith<LoadableStateState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $ErrorBarStateCopyWith<$Res> {
|
||||
factory $ErrorBarStateCopyWith(
|
||||
ErrorBarState value, $Res Function(ErrorBarState) then) =
|
||||
_$ErrorBarStateCopyWithImpl<$Res, ErrorBarState>;
|
||||
abstract class $LoadableStateStateCopyWith<$Res> {
|
||||
factory $LoadableStateStateCopyWith(
|
||||
LoadableStateState value, $Res Function(LoadableStateState) then) =
|
||||
_$LoadableStateStateCopyWithImpl<$Res, LoadableStateState>;
|
||||
@useResult
|
||||
$Res call({List<ConnectivityResult>? connections});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$ErrorBarStateCopyWithImpl<$Res, $Val extends ErrorBarState>
|
||||
implements $ErrorBarStateCopyWith<$Res> {
|
||||
_$ErrorBarStateCopyWithImpl(this._value, this._then);
|
||||
class _$LoadableStateStateCopyWithImpl<$Res, $Val extends LoadableStateState>
|
||||
implements $LoadableStateStateCopyWith<$Res> {
|
||||
_$LoadableStateStateCopyWithImpl(this._value, this._then);
|
||||
|
||||
// ignore: unused_field
|
||||
final $Val _value;
|
||||
@ -58,22 +58,22 @@ class _$ErrorBarStateCopyWithImpl<$Res, $Val extends ErrorBarState>
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$ErrorBarStateImplCopyWith<$Res>
|
||||
implements $ErrorBarStateCopyWith<$Res> {
|
||||
factory _$$ErrorBarStateImplCopyWith(
|
||||
_$ErrorBarStateImpl value, $Res Function(_$ErrorBarStateImpl) then) =
|
||||
__$$ErrorBarStateImplCopyWithImpl<$Res>;
|
||||
abstract class _$$LoadableStateStateImplCopyWith<$Res>
|
||||
implements $LoadableStateStateCopyWith<$Res> {
|
||||
factory _$$LoadableStateStateImplCopyWith(_$LoadableStateStateImpl value,
|
||||
$Res Function(_$LoadableStateStateImpl) then) =
|
||||
__$$LoadableStateStateImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({List<ConnectivityResult>? connections});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$ErrorBarStateImplCopyWithImpl<$Res>
|
||||
extends _$ErrorBarStateCopyWithImpl<$Res, _$ErrorBarStateImpl>
|
||||
implements _$$ErrorBarStateImplCopyWith<$Res> {
|
||||
__$$ErrorBarStateImplCopyWithImpl(
|
||||
_$ErrorBarStateImpl _value, $Res Function(_$ErrorBarStateImpl) _then)
|
||||
class __$$LoadableStateStateImplCopyWithImpl<$Res>
|
||||
extends _$LoadableStateStateCopyWithImpl<$Res, _$LoadableStateStateImpl>
|
||||
implements _$$LoadableStateStateImplCopyWith<$Res> {
|
||||
__$$LoadableStateStateImplCopyWithImpl(_$LoadableStateStateImpl _value,
|
||||
$Res Function(_$LoadableStateStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@ -81,7 +81,7 @@ class __$$ErrorBarStateImplCopyWithImpl<$Res>
|
||||
$Res call({
|
||||
Object? connections = freezed,
|
||||
}) {
|
||||
return _then(_$ErrorBarStateImpl(
|
||||
return _then(_$LoadableStateStateImpl(
|
||||
connections: freezed == connections
|
||||
? _value._connections
|
||||
: connections // ignore: cast_nullable_to_non_nullable
|
||||
@ -92,8 +92,8 @@ class __$$ErrorBarStateImplCopyWithImpl<$Res>
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$ErrorBarStateImpl implements _ErrorBarState {
|
||||
const _$ErrorBarStateImpl(
|
||||
class _$LoadableStateStateImpl implements _LoadableStateState {
|
||||
const _$LoadableStateStateImpl(
|
||||
{required final List<ConnectivityResult>? connections})
|
||||
: _connections = connections;
|
||||
|
||||
@ -109,14 +109,14 @@ class _$ErrorBarStateImpl implements _ErrorBarState {
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'ErrorBarState(connections: $connections)';
|
||||
return 'LoadableStateState(connections: $connections)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$ErrorBarStateImpl &&
|
||||
other is _$LoadableStateStateImpl &&
|
||||
const DeepCollectionEquality()
|
||||
.equals(other._connections, _connections));
|
||||
}
|
||||
@ -128,19 +128,20 @@ class _$ErrorBarStateImpl implements _ErrorBarState {
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$ErrorBarStateImplCopyWith<_$ErrorBarStateImpl> get copyWith =>
|
||||
__$$ErrorBarStateImplCopyWithImpl<_$ErrorBarStateImpl>(this, _$identity);
|
||||
_$$LoadableStateStateImplCopyWith<_$LoadableStateStateImpl> get copyWith =>
|
||||
__$$LoadableStateStateImplCopyWithImpl<_$LoadableStateStateImpl>(
|
||||
this, _$identity);
|
||||
}
|
||||
|
||||
abstract class _ErrorBarState implements ErrorBarState {
|
||||
const factory _ErrorBarState(
|
||||
abstract class _LoadableStateState implements LoadableStateState {
|
||||
const factory _LoadableStateState(
|
||||
{required final List<ConnectivityResult>? connections}) =
|
||||
_$ErrorBarStateImpl;
|
||||
_$LoadableStateStateImpl;
|
||||
|
||||
@override
|
||||
List<ConnectivityResult>? get connections;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$ErrorBarStateImplCopyWith<_$ErrorBarStateImpl> get copyWith =>
|
||||
_$$LoadableStateStateImplCopyWith<_$LoadableStateStateImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
||||
|
||||
import '../repository/repository.dart';
|
||||
import 'loadable_state.dart';
|
||||
|
||||
sealed class LoadableHydratedBlocEvent {}
|
||||
class DataRecieved extends LoadableHydratedBlocEvent {}
|
||||
|
||||
abstract class LoadableHydratedBloc<TEvent, TState> extends HydratedBloc<TEvent, LoadableState<TState>> {
|
||||
LoadableHydratedBloc() : super(const LoadableState()) {
|
||||
repository().load();
|
||||
|
||||
}
|
||||
|
||||
Repository repository();
|
||||
|
||||
|
||||
@override
|
||||
fromJson(Map<String, dynamic> json) => LoadableState(isLoading: true, data: fromStorage(json));
|
||||
@override
|
||||
Map<String, dynamic>? toJson(state) => state.data.toJson();
|
||||
|
||||
TState fromStorage(Map<String, dynamic> json);
|
||||
Map<String, dynamic>? toStorage(TState state);
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'loadable_state.freezed.dart';
|
||||
|
||||
@freezed
|
||||
class LoadableState<TState> with _$LoadableState {
|
||||
const LoadableState._();
|
||||
|
||||
const factory LoadableState({
|
||||
@Default(true) bool isLoading,
|
||||
@Default(null) TState? data,
|
||||
}) = _LoadableState;
|
||||
|
||||
bool showPrimaryLoading() => isLoading && data == null;
|
||||
bool showBackgroundLoading() => isLoading && data != null;
|
||||
bool showError() => !isLoading && data == null;
|
||||
bool showContent() => data != null;
|
||||
}
|
@ -0,0 +1,158 @@
|
||||
// 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 'loadable_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');
|
||||
|
||||
/// @nodoc
|
||||
mixin _$LoadableState<TState> {
|
||||
bool get isLoading => throw _privateConstructorUsedError;
|
||||
TState? get data => throw _privateConstructorUsedError;
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
$LoadableStateCopyWith<TState, LoadableState<TState>> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $LoadableStateCopyWith<TState, $Res> {
|
||||
factory $LoadableStateCopyWith(LoadableState<TState> value,
|
||||
$Res Function(LoadableState<TState>) then) =
|
||||
_$LoadableStateCopyWithImpl<TState, $Res, LoadableState<TState>>;
|
||||
@useResult
|
||||
$Res call({bool isLoading, TState? data});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$LoadableStateCopyWithImpl<TState, $Res,
|
||||
$Val extends LoadableState<TState>>
|
||||
implements $LoadableStateCopyWith<TState, $Res> {
|
||||
_$LoadableStateCopyWithImpl(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? isLoading = null,
|
||||
Object? data = freezed,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
isLoading: null == isLoading
|
||||
? _value.isLoading
|
||||
: isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
data: freezed == data
|
||||
? _value.data
|
||||
: data // ignore: cast_nullable_to_non_nullable
|
||||
as TState?,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$LoadableStateImplCopyWith<TState, $Res>
|
||||
implements $LoadableStateCopyWith<TState, $Res> {
|
||||
factory _$$LoadableStateImplCopyWith(_$LoadableStateImpl<TState> value,
|
||||
$Res Function(_$LoadableStateImpl<TState>) then) =
|
||||
__$$LoadableStateImplCopyWithImpl<TState, $Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({bool isLoading, TState? data});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$LoadableStateImplCopyWithImpl<TState, $Res>
|
||||
extends _$LoadableStateCopyWithImpl<TState, $Res,
|
||||
_$LoadableStateImpl<TState>>
|
||||
implements _$$LoadableStateImplCopyWith<TState, $Res> {
|
||||
__$$LoadableStateImplCopyWithImpl(_$LoadableStateImpl<TState> _value,
|
||||
$Res Function(_$LoadableStateImpl<TState>) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? isLoading = null,
|
||||
Object? data = freezed,
|
||||
}) {
|
||||
return _then(_$LoadableStateImpl<TState>(
|
||||
isLoading: null == isLoading
|
||||
? _value.isLoading
|
||||
: isLoading // ignore: cast_nullable_to_non_nullable
|
||||
as bool,
|
||||
data: freezed == data
|
||||
? _value.data
|
||||
: data // ignore: cast_nullable_to_non_nullable
|
||||
as TState?,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
|
||||
class _$LoadableStateImpl<TState> extends _LoadableState<TState> {
|
||||
const _$LoadableStateImpl({this.isLoading = true, this.data = null})
|
||||
: super._();
|
||||
|
||||
@override
|
||||
@JsonKey()
|
||||
final bool isLoading;
|
||||
@override
|
||||
@JsonKey()
|
||||
final TState? data;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'LoadableState<$TState>(isLoading: $isLoading, data: $data)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$LoadableStateImpl<TState> &&
|
||||
(identical(other.isLoading, isLoading) ||
|
||||
other.isLoading == isLoading) &&
|
||||
const DeepCollectionEquality().equals(other.data, data));
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType, isLoading, const DeepCollectionEquality().hash(data));
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$LoadableStateImplCopyWith<TState, _$LoadableStateImpl<TState>>
|
||||
get copyWith => __$$LoadableStateImplCopyWithImpl<TState,
|
||||
_$LoadableStateImpl<TState>>(this, _$identity);
|
||||
}
|
||||
|
||||
abstract class _LoadableState<TState> extends LoadableState<TState> {
|
||||
const factory _LoadableState({final bool isLoading, final TState? data}) =
|
||||
_$LoadableStateImpl<TState>;
|
||||
const _LoadableState._() : super._();
|
||||
|
||||
@override
|
||||
bool get isLoading;
|
||||
@override
|
||||
TState? get data;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$LoadableStateImplCopyWith<TState, _$LoadableStateImpl<TState>>
|
||||
get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class BackgroundLoadingIndicator extends StatelessWidget {
|
||||
class LoadableStateBackgroundLoading extends StatelessWidget {
|
||||
final bool visible;
|
||||
const BackgroundLoadingIndicator({required this.visible, super.key});
|
||||
const LoadableStateBackgroundLoading({required this.visible, super.key});
|
||||
|
||||
final Duration animationDuration = const Duration(milliseconds: 200);
|
||||
|
@ -0,0 +1,42 @@
|
||||
import 'package:bloc/bloc.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../loadable_state.dart';
|
||||
import 'loadable_state_background_loading.dart';
|
||||
import 'loadable_state_error_bar.dart';
|
||||
import 'loadable_state_primary_loading.dart';
|
||||
|
||||
// TODO might be a simpler way
|
||||
class LoadableStateConsumer<TController extends Bloc<dynamic, TWrappedState>, TWrappedState extends LoadableState<TState>, TState> extends StatelessWidget {
|
||||
final Widget Function(TState state) child;
|
||||
const LoadableStateConsumer({required this.child, super.key});
|
||||
|
||||
static Duration animationDuration = const Duration(milliseconds: 200);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var state = context.read<TController>().state as LoadableState<TState>;
|
||||
|
||||
return Column(
|
||||
children: [
|
||||
LoadableStateErrorBar(visible: state.showError()),
|
||||
Expanded(
|
||||
child: Stack(
|
||||
children: [
|
||||
LoadableStatePrimaryLoading(visible: state.showPrimaryLoading()),
|
||||
LoadableStateBackgroundLoading(visible: state.showBackgroundLoading()),
|
||||
|
||||
AnimatedOpacity(
|
||||
opacity: state.showContent() ? 1.0 : 0.0,
|
||||
duration: animationDuration,
|
||||
curve: Curves.easeInOut,
|
||||
child: state.showContent() ? child(state.data) : const SizedBox.shrink()
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
import '../../utilityWidgets/bloc_providing_builder.dart';
|
||||
import '../bloc/loadable_state_bloc.dart';
|
||||
import '../bloc/loadable_state_state.dart';
|
||||
|
||||
class LoadableStateErrorBar extends StatelessWidget {
|
||||
final bool visible;
|
||||
const LoadableStateErrorBar({required this.visible, super.key});
|
||||
|
||||
final Duration animationDuration = const Duration(milliseconds: 200);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => BlocProvidingBuilder<LoadableStateBloc, LoadableStateState>(
|
||||
create: (context) => LoadableStateBloc(),
|
||||
child: (context, state) => AnimatedSize(
|
||||
duration: animationDuration,
|
||||
child: AnimatedSwitcher(
|
||||
duration: animationDuration,
|
||||
transitionBuilder: (Widget child, Animation<double> animation) => SlideTransition(
|
||||
position: Tween<Offset>(
|
||||
begin: const Offset(0.0, -1.0),
|
||||
end: Offset.zero,
|
||||
).animate(animation),
|
||||
child: child,
|
||||
),
|
||||
child: Visibility(
|
||||
key: Key(visible.hashCode.toString()),
|
||||
visible: visible,
|
||||
replacement: const SizedBox(width: double.infinity),
|
||||
child: Builder(
|
||||
builder: (context) {
|
||||
var controller = context.watch<LoadableStateBloc>();
|
||||
var status = controller.connectivityStatusKnown() && !controller.isConnected()
|
||||
? (icon: Icons.wifi_off_outlined, text: 'Offline', color: Colors.grey.shade600)
|
||||
: (icon: Icons.wifi_find_outlined, text: 'Verbindung fehlgeschlagen', color: Theme.of(context).primaryColor);
|
||||
|
||||
return Container(
|
||||
height: 20,
|
||||
decoration: BoxDecoration(
|
||||
color: status.color,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(status.icon, size: 14),
|
||||
const SizedBox(width: 10),
|
||||
Text(status.text, style: const TextStyle(fontSize: 12))
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
)
|
||||
)
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class PrimaryLoadingIndicator extends StatelessWidget {
|
||||
class LoadableStatePrimaryLoading extends StatelessWidget {
|
||||
final bool visible;
|
||||
const PrimaryLoadingIndicator({required this.visible, super.key});
|
||||
const LoadableStatePrimaryLoading({required this.visible, super.key});
|
||||
|
||||
final Duration animationDuration = const Duration(milliseconds: 200);
|
||||
|
13
lib/state/app/infrastructure/repository/repository.dart
Normal file
13
lib/state/app/infrastructure/repository/repository.dart
Normal file
@ -0,0 +1,13 @@
|
||||
import '../dataLoader/data_loader.dart';
|
||||
|
||||
abstract class Repository {
|
||||
final List<DataLoader> dataLoaders;
|
||||
|
||||
Repository(this.dataLoaders);
|
||||
|
||||
Future<void> load() async {
|
||||
dataLoaders.forEach((element) {
|
||||
element.fetch();
|
||||
});
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class BlocProvidingBuilder<TBloc extends StateStreamableSource<TState>, TState> extends StatelessWidget {
|
||||
final TBloc Function(BuildContext context) create;
|
||||
final Widget Function(BuildContext context, TState state) child;
|
||||
const BlocProvidingBuilder({required this.create, required this.child, super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => BlocProvider<TBloc>(create: create, child: BlocBuilder<TBloc, TState>(builder: child));
|
||||
}
|
@ -7,8 +7,8 @@ import '../bloc/grade_averages_event.dart';
|
||||
import '../bloc/grade_averages_state.dart';
|
||||
import 'grade_averages_list_view.dart';
|
||||
|
||||
class GradeAveragesScreen extends StatelessWidget {
|
||||
const GradeAveragesScreen({super.key});
|
||||
class GradeAveragesView extends StatelessWidget {
|
||||
const GradeAveragesView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => BlocProvider<GradeAveragesBloc>(
|
@ -0,0 +1,17 @@
|
||||
import '../../../infrastructure/loadableState/loadable_hydrated_bloc.dart';
|
||||
import '../../../infrastructure/repository/repository.dart';
|
||||
import '../repository/marianum_message_repository.dart';
|
||||
import 'marianum_message_state.dart';
|
||||
|
||||
class MarianumMessageBloc extends LoadableHydratedBloc<void, MarianumMessageState> {
|
||||
MarianumMessageBloc();
|
||||
|
||||
|
||||
@override
|
||||
MarianumMessageState fromStorage(Map<String, dynamic> json) => MarianumMessageState.fromJson(json);
|
||||
@override
|
||||
Map<String, dynamic>? toStorage(MarianumMessageState state) => state.toJson();
|
||||
|
||||
@override
|
||||
Repository repository() => MarianumMessageRepository(emit);
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||
|
||||
part 'marianum_message_state.freezed.dart';
|
||||
part 'marianum_message_state.g.dart';
|
||||
|
||||
|
||||
@freezed
|
||||
class MarianumMessageState with _$MarianumMessageState {
|
||||
const factory MarianumMessageState({
|
||||
required MarianumMessageList messageList,
|
||||
}) = _MarianumMessageState;
|
||||
|
||||
factory MarianumMessageState.fromJson(Map<String, dynamic> json) => _$MarianumMessageStateFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class MarianumMessageList with _$MarianumMessageList {
|
||||
const factory MarianumMessageList({
|
||||
required String base,
|
||||
required List<MarianumMessage> messages,
|
||||
}) = _MarianumMessageList;
|
||||
|
||||
factory MarianumMessageList.fromJson(Map<String, dynamic> json) => _$MarianumMessageListFromJson(json);
|
||||
}
|
||||
|
||||
@freezed
|
||||
class MarianumMessage with _$MarianumMessage {
|
||||
const factory MarianumMessage({
|
||||
required String name,
|
||||
required String date,
|
||||
required String url,
|
||||
}) = _MarianumMessage;
|
||||
|
||||
factory MarianumMessage.fromJson(Map<String, dynamic> json) => _$MarianumMessageFromJson(json);
|
||||
}
|
||||
|
||||
|
||||
enum GradeAveragesGradingSystem {
|
||||
highSchool,
|
||||
middleSchool,
|
||||
}
|
@ -0,0 +1,507 @@
|
||||
// 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 'marianum_message_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');
|
||||
|
||||
MarianumMessageState _$MarianumMessageStateFromJson(Map<String, dynamic> json) {
|
||||
return _MarianumMessageState.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$MarianumMessageState {
|
||||
MarianumMessageList get messageList => throw _privateConstructorUsedError;
|
||||
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$MarianumMessageStateCopyWith<MarianumMessageState> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $MarianumMessageStateCopyWith<$Res> {
|
||||
factory $MarianumMessageStateCopyWith(MarianumMessageState value,
|
||||
$Res Function(MarianumMessageState) then) =
|
||||
_$MarianumMessageStateCopyWithImpl<$Res, MarianumMessageState>;
|
||||
@useResult
|
||||
$Res call({MarianumMessageList messageList});
|
||||
|
||||
$MarianumMessageListCopyWith<$Res> get messageList;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$MarianumMessageStateCopyWithImpl<$Res,
|
||||
$Val extends MarianumMessageState>
|
||||
implements $MarianumMessageStateCopyWith<$Res> {
|
||||
_$MarianumMessageStateCopyWithImpl(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? messageList = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
messageList: null == messageList
|
||||
? _value.messageList
|
||||
: messageList // ignore: cast_nullable_to_non_nullable
|
||||
as MarianumMessageList,
|
||||
) as $Val);
|
||||
}
|
||||
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
$MarianumMessageListCopyWith<$Res> get messageList {
|
||||
return $MarianumMessageListCopyWith<$Res>(_value.messageList, (value) {
|
||||
return _then(_value.copyWith(messageList: value) as $Val);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$MarianumMessageStateImplCopyWith<$Res>
|
||||
implements $MarianumMessageStateCopyWith<$Res> {
|
||||
factory _$$MarianumMessageStateImplCopyWith(_$MarianumMessageStateImpl value,
|
||||
$Res Function(_$MarianumMessageStateImpl) then) =
|
||||
__$$MarianumMessageStateImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({MarianumMessageList messageList});
|
||||
|
||||
@override
|
||||
$MarianumMessageListCopyWith<$Res> get messageList;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$MarianumMessageStateImplCopyWithImpl<$Res>
|
||||
extends _$MarianumMessageStateCopyWithImpl<$Res, _$MarianumMessageStateImpl>
|
||||
implements _$$MarianumMessageStateImplCopyWith<$Res> {
|
||||
__$$MarianumMessageStateImplCopyWithImpl(_$MarianumMessageStateImpl _value,
|
||||
$Res Function(_$MarianumMessageStateImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? messageList = null,
|
||||
}) {
|
||||
return _then(_$MarianumMessageStateImpl(
|
||||
messageList: null == messageList
|
||||
? _value.messageList
|
||||
: messageList // ignore: cast_nullable_to_non_nullable
|
||||
as MarianumMessageList,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$MarianumMessageStateImpl implements _MarianumMessageState {
|
||||
const _$MarianumMessageStateImpl({required this.messageList});
|
||||
|
||||
factory _$MarianumMessageStateImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$MarianumMessageStateImplFromJson(json);
|
||||
|
||||
@override
|
||||
final MarianumMessageList messageList;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MarianumMessageState(messageList: $messageList)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$MarianumMessageStateImpl &&
|
||||
(identical(other.messageList, messageList) ||
|
||||
other.messageList == messageList));
|
||||
}
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, messageList);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$MarianumMessageStateImplCopyWith<_$MarianumMessageStateImpl>
|
||||
get copyWith =>
|
||||
__$$MarianumMessageStateImplCopyWithImpl<_$MarianumMessageStateImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$MarianumMessageStateImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _MarianumMessageState implements MarianumMessageState {
|
||||
const factory _MarianumMessageState(
|
||||
{required final MarianumMessageList messageList}) =
|
||||
_$MarianumMessageStateImpl;
|
||||
|
||||
factory _MarianumMessageState.fromJson(Map<String, dynamic> json) =
|
||||
_$MarianumMessageStateImpl.fromJson;
|
||||
|
||||
@override
|
||||
MarianumMessageList get messageList;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$MarianumMessageStateImplCopyWith<_$MarianumMessageStateImpl>
|
||||
get copyWith => throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
MarianumMessageList _$MarianumMessageListFromJson(Map<String, dynamic> json) {
|
||||
return _MarianumMessageList.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$MarianumMessageList {
|
||||
String get base => throw _privateConstructorUsedError;
|
||||
List<MarianumMessage> get messages => throw _privateConstructorUsedError;
|
||||
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$MarianumMessageListCopyWith<MarianumMessageList> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $MarianumMessageListCopyWith<$Res> {
|
||||
factory $MarianumMessageListCopyWith(
|
||||
MarianumMessageList value, $Res Function(MarianumMessageList) then) =
|
||||
_$MarianumMessageListCopyWithImpl<$Res, MarianumMessageList>;
|
||||
@useResult
|
||||
$Res call({String base, List<MarianumMessage> messages});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$MarianumMessageListCopyWithImpl<$Res, $Val extends MarianumMessageList>
|
||||
implements $MarianumMessageListCopyWith<$Res> {
|
||||
_$MarianumMessageListCopyWithImpl(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? base = null,
|
||||
Object? messages = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
base: null == base
|
||||
? _value.base
|
||||
: base // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
messages: null == messages
|
||||
? _value.messages
|
||||
: messages // ignore: cast_nullable_to_non_nullable
|
||||
as List<MarianumMessage>,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$MarianumMessageListImplCopyWith<$Res>
|
||||
implements $MarianumMessageListCopyWith<$Res> {
|
||||
factory _$$MarianumMessageListImplCopyWith(_$MarianumMessageListImpl value,
|
||||
$Res Function(_$MarianumMessageListImpl) then) =
|
||||
__$$MarianumMessageListImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({String base, List<MarianumMessage> messages});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$MarianumMessageListImplCopyWithImpl<$Res>
|
||||
extends _$MarianumMessageListCopyWithImpl<$Res, _$MarianumMessageListImpl>
|
||||
implements _$$MarianumMessageListImplCopyWith<$Res> {
|
||||
__$$MarianumMessageListImplCopyWithImpl(_$MarianumMessageListImpl _value,
|
||||
$Res Function(_$MarianumMessageListImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? base = null,
|
||||
Object? messages = null,
|
||||
}) {
|
||||
return _then(_$MarianumMessageListImpl(
|
||||
base: null == base
|
||||
? _value.base
|
||||
: base // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
messages: null == messages
|
||||
? _value._messages
|
||||
: messages // ignore: cast_nullable_to_non_nullable
|
||||
as List<MarianumMessage>,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$MarianumMessageListImpl implements _MarianumMessageList {
|
||||
const _$MarianumMessageListImpl(
|
||||
{required this.base, required final List<MarianumMessage> messages})
|
||||
: _messages = messages;
|
||||
|
||||
factory _$MarianumMessageListImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$MarianumMessageListImplFromJson(json);
|
||||
|
||||
@override
|
||||
final String base;
|
||||
final List<MarianumMessage> _messages;
|
||||
@override
|
||||
List<MarianumMessage> get messages {
|
||||
if (_messages is EqualUnmodifiableListView) return _messages;
|
||||
// ignore: implicit_dynamic_type
|
||||
return EqualUnmodifiableListView(_messages);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MarianumMessageList(base: $base, messages: $messages)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$MarianumMessageListImpl &&
|
||||
(identical(other.base, base) || other.base == base) &&
|
||||
const DeepCollectionEquality().equals(other._messages, _messages));
|
||||
}
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
int get hashCode => Object.hash(
|
||||
runtimeType, base, const DeepCollectionEquality().hash(_messages));
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$MarianumMessageListImplCopyWith<_$MarianumMessageListImpl> get copyWith =>
|
||||
__$$MarianumMessageListImplCopyWithImpl<_$MarianumMessageListImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$MarianumMessageListImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _MarianumMessageList implements MarianumMessageList {
|
||||
const factory _MarianumMessageList(
|
||||
{required final String base,
|
||||
required final List<MarianumMessage> messages}) =
|
||||
_$MarianumMessageListImpl;
|
||||
|
||||
factory _MarianumMessageList.fromJson(Map<String, dynamic> json) =
|
||||
_$MarianumMessageListImpl.fromJson;
|
||||
|
||||
@override
|
||||
String get base;
|
||||
@override
|
||||
List<MarianumMessage> get messages;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$MarianumMessageListImplCopyWith<_$MarianumMessageListImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
MarianumMessage _$MarianumMessageFromJson(Map<String, dynamic> json) {
|
||||
return _MarianumMessage.fromJson(json);
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
mixin _$MarianumMessage {
|
||||
String get name => throw _privateConstructorUsedError;
|
||||
String get date => throw _privateConstructorUsedError;
|
||||
String get url => throw _privateConstructorUsedError;
|
||||
|
||||
Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
|
||||
@JsonKey(ignore: true)
|
||||
$MarianumMessageCopyWith<MarianumMessage> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class $MarianumMessageCopyWith<$Res> {
|
||||
factory $MarianumMessageCopyWith(
|
||||
MarianumMessage value, $Res Function(MarianumMessage) then) =
|
||||
_$MarianumMessageCopyWithImpl<$Res, MarianumMessage>;
|
||||
@useResult
|
||||
$Res call({String name, String date, String url});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class _$MarianumMessageCopyWithImpl<$Res, $Val extends MarianumMessage>
|
||||
implements $MarianumMessageCopyWith<$Res> {
|
||||
_$MarianumMessageCopyWithImpl(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? name = null,
|
||||
Object? date = null,
|
||||
Object? url = null,
|
||||
}) {
|
||||
return _then(_value.copyWith(
|
||||
name: null == name
|
||||
? _value.name
|
||||
: name // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
date: null == date
|
||||
? _value.date
|
||||
: date // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
url: null == url
|
||||
? _value.url
|
||||
: url // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
) as $Val);
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
abstract class _$$MarianumMessageImplCopyWith<$Res>
|
||||
implements $MarianumMessageCopyWith<$Res> {
|
||||
factory _$$MarianumMessageImplCopyWith(_$MarianumMessageImpl value,
|
||||
$Res Function(_$MarianumMessageImpl) then) =
|
||||
__$$MarianumMessageImplCopyWithImpl<$Res>;
|
||||
@override
|
||||
@useResult
|
||||
$Res call({String name, String date, String url});
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
class __$$MarianumMessageImplCopyWithImpl<$Res>
|
||||
extends _$MarianumMessageCopyWithImpl<$Res, _$MarianumMessageImpl>
|
||||
implements _$$MarianumMessageImplCopyWith<$Res> {
|
||||
__$$MarianumMessageImplCopyWithImpl(
|
||||
_$MarianumMessageImpl _value, $Res Function(_$MarianumMessageImpl) _then)
|
||||
: super(_value, _then);
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
@override
|
||||
$Res call({
|
||||
Object? name = null,
|
||||
Object? date = null,
|
||||
Object? url = null,
|
||||
}) {
|
||||
return _then(_$MarianumMessageImpl(
|
||||
name: null == name
|
||||
? _value.name
|
||||
: name // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
date: null == date
|
||||
? _value.date
|
||||
: date // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
url: null == url
|
||||
? _value.url
|
||||
: url // ignore: cast_nullable_to_non_nullable
|
||||
as String,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/// @nodoc
|
||||
@JsonSerializable()
|
||||
class _$MarianumMessageImpl implements _MarianumMessage {
|
||||
const _$MarianumMessageImpl(
|
||||
{required this.name, required this.date, required this.url});
|
||||
|
||||
factory _$MarianumMessageImpl.fromJson(Map<String, dynamic> json) =>
|
||||
_$$MarianumMessageImplFromJson(json);
|
||||
|
||||
@override
|
||||
final String name;
|
||||
@override
|
||||
final String date;
|
||||
@override
|
||||
final String url;
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'MarianumMessage(name: $name, date: $date, url: $url)';
|
||||
}
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) {
|
||||
return identical(this, other) ||
|
||||
(other.runtimeType == runtimeType &&
|
||||
other is _$MarianumMessageImpl &&
|
||||
(identical(other.name, name) || other.name == name) &&
|
||||
(identical(other.date, date) || other.date == date) &&
|
||||
(identical(other.url, url) || other.url == url));
|
||||
}
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
int get hashCode => Object.hash(runtimeType, name, date, url);
|
||||
|
||||
@JsonKey(ignore: true)
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
_$$MarianumMessageImplCopyWith<_$MarianumMessageImpl> get copyWith =>
|
||||
__$$MarianumMessageImplCopyWithImpl<_$MarianumMessageImpl>(
|
||||
this, _$identity);
|
||||
|
||||
@override
|
||||
Map<String, dynamic> toJson() {
|
||||
return _$$MarianumMessageImplToJson(
|
||||
this,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
abstract class _MarianumMessage implements MarianumMessage {
|
||||
const factory _MarianumMessage(
|
||||
{required final String name,
|
||||
required final String date,
|
||||
required final String url}) = _$MarianumMessageImpl;
|
||||
|
||||
factory _MarianumMessage.fromJson(Map<String, dynamic> json) =
|
||||
_$MarianumMessageImpl.fromJson;
|
||||
|
||||
@override
|
||||
String get name;
|
||||
@override
|
||||
String get date;
|
||||
@override
|
||||
String get url;
|
||||
@override
|
||||
@JsonKey(ignore: true)
|
||||
_$$MarianumMessageImplCopyWith<_$MarianumMessageImpl> get copyWith =>
|
||||
throw _privateConstructorUsedError;
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'marianum_message_state.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
_$MarianumMessageStateImpl _$$MarianumMessageStateImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$MarianumMessageStateImpl(
|
||||
messageList: MarianumMessageList.fromJson(
|
||||
json['messageList'] as Map<String, dynamic>),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$MarianumMessageStateImplToJson(
|
||||
_$MarianumMessageStateImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'messageList': instance.messageList,
|
||||
};
|
||||
|
||||
_$MarianumMessageListImpl _$$MarianumMessageListImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$MarianumMessageListImpl(
|
||||
base: json['base'] as String,
|
||||
messages: (json['messages'] as List<dynamic>)
|
||||
.map((e) => MarianumMessage.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$MarianumMessageListImplToJson(
|
||||
_$MarianumMessageListImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'base': instance.base,
|
||||
'messages': instance.messages,
|
||||
};
|
||||
|
||||
_$MarianumMessageImpl _$$MarianumMessageImplFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
_$MarianumMessageImpl(
|
||||
name: json['name'] as String,
|
||||
date: json['date'] as String,
|
||||
url: json['url'] as String,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$$MarianumMessageImplToJson(
|
||||
_$MarianumMessageImpl instance) =>
|
||||
<String, dynamic>{
|
||||
'name': instance.name,
|
||||
'date': instance.date,
|
||||
'url': instance.url,
|
||||
};
|
@ -0,0 +1,6 @@
|
||||
import '../../../infrastructure/dataLoader/data_loader.dart';
|
||||
|
||||
class MarianumMessageGetMessages extends DataLoader {
|
||||
@override
|
||||
Future fetch() => Future(() => 'Test');
|
||||
}
|
@ -0,0 +1,9 @@
|
||||
import '../../../infrastructure/loadableState/loadable_state.dart';
|
||||
import '../../../infrastructure/repository/repository.dart';
|
||||
import '../dataProvider/marianum_message_get_messages.dart';
|
||||
|
||||
class MarianumMessageRepository<TState> extends Repository {
|
||||
MarianumMessageRepository(void Function(LoadableState<TState> content) emit) : super([
|
||||
MarianumMessageGetMessages(),
|
||||
]);
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
import 'dart:developer';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../../../api/mhsl/message/getMessages/getMessagesResponse.dart';
|
||||
import '../../../../../view/pages/more/message/messageView.dart';
|
||||
import '../../../infrastructure/loadableState/loadable_state.dart';
|
||||
import '../../../infrastructure/loadableState/view/loadable_state_consumer.dart';
|
||||
import '../../../infrastructure/utilityWidgets/bloc_providing_builder.dart';
|
||||
import '../bloc/marianum_message_bloc.dart';
|
||||
import '../bloc/marianum_message_state.dart';
|
||||
|
||||
class MarianumMessageListView extends StatelessWidget {
|
||||
const MarianumMessageListView({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('Marianum Message'),
|
||||
),
|
||||
body: BlocProvidingBuilder<MarianumMessageBloc, LoadableState<MarianumMessageState>>(
|
||||
create: (context) => MarianumMessageBloc(),
|
||||
child: (context, state) {
|
||||
// if(value.primaryLoading()) return const LoadingSpinner();
|
||||
log(state.toString());
|
||||
return LoadableStateConsumer<MarianumMessageBloc, LoadableState<MarianumMessageState>, MarianumMessageState>(
|
||||
child: (state) => ListView.builder(
|
||||
itemCount: state.messageList.messages.length,
|
||||
itemBuilder: (context, index) {
|
||||
var message = state.messageList.messages.toList()[index];
|
||||
return ListTile(
|
||||
leading: const Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [Icon(Icons.newspaper)],
|
||||
),
|
||||
title: Text(message.name, overflow: TextOverflow.ellipsis),
|
||||
subtitle: Text('vom ${message.date}'),
|
||||
trailing: const Icon(Icons.arrow_right),
|
||||
onTap: () {
|
||||
Navigator.push(context, MaterialPageRoute(builder: (context) => MessageView(basePath: state.messageList.base, message: message as GetMessagesResponseObject)));
|
||||
},
|
||||
);
|
||||
}
|
||||
),
|
||||
);
|
||||
}
|
||||
),
|
||||
);
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
// import 'package:flutter/material.dart';
|
||||
//
|
||||
// import '../../app/base/infrastructure/errorBar/error_bar_controller.dart';
|
||||
// import '../../infrastructure/state_extensions.dart';
|
||||
// import '../controller_provider.dart';
|
||||
//
|
||||
// class ErrorBar extends StatelessWidget {
|
||||
// final bool visible;
|
||||
// const ErrorBar({required this.visible, super.key});
|
||||
//
|
||||
// final Duration animationDuration = const Duration(milliseconds: 200);
|
||||
//
|
||||
// @override
|
||||
// Widget build(BuildContext context) => ControllerProvider<ErrorBarController>(
|
||||
// create: (context) => ErrorBarController(),
|
||||
// child: (context) => AnimatedSize(
|
||||
// duration: animationDuration,
|
||||
// child: AnimatedSwitcher(
|
||||
// duration: animationDuration,
|
||||
// transitionBuilder: (Widget child, Animation<double> animation) => SlideTransition(
|
||||
// position: Tween<Offset>(
|
||||
// begin: const Offset(0.0, -1.0),
|
||||
// end: Offset.zero,
|
||||
// ).animate(animation),
|
||||
// child: child,
|
||||
// ),
|
||||
// child: Visibility(
|
||||
// key: Key(visible.hashCode.toString()),
|
||||
// visible: visible,
|
||||
// replacement: const SizedBox(width: double.infinity),
|
||||
// child: Builder(
|
||||
// builder: (context) {
|
||||
// var controller = context.watchController<ErrorBarController>();
|
||||
// var status = controller.connectivityStatusKnown() && !controller.isConnected()
|
||||
// ? (icon: Icons.wifi_off_outlined, text: 'Offline', color: Colors.grey.shade600)
|
||||
// : (icon: Icons.wifi_find_outlined, text: 'Verbindung fehlgeschlagen', color: Theme.of(context).primaryColor);
|
||||
//
|
||||
// return Container(
|
||||
// height: 20,
|
||||
// decoration: BoxDecoration(
|
||||
// color: status.color,
|
||||
// ),
|
||||
// child: Row(
|
||||
// mainAxisAlignment: MainAxisAlignment.center,
|
||||
// children: [
|
||||
// Icon(status.icon, size: 14),
|
||||
// const SizedBox(width: 10),
|
||||
// Text(status.text, style: const TextStyle(fontSize: 12))
|
||||
// ],
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// )
|
||||
// )
|
||||
// ),
|
||||
// ),
|
||||
// );
|
||||
// }
|
@ -1,12 +0,0 @@
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
//
|
||||
// import '../infrastructure/controller.dart';
|
||||
//
|
||||
// class ControllerConsumer<TController extends Controller<TState>, TState> extends StatelessWidget {
|
||||
// final Widget Function(BuildContext context, TState state) child;
|
||||
// const ControllerConsumer({required this.child, super.key});
|
||||
//
|
||||
// @override
|
||||
// Widget build(BuildContext context) => BlocBuilder<TController, TState>(builder: child);
|
||||
// }
|
@ -1,21 +0,0 @@
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
// import 'package:provider/single_child_widget.dart';
|
||||
//
|
||||
// import '../infrastructure/controller.dart';
|
||||
//
|
||||
//
|
||||
// class ControllerProvider<TState extends Controller> extends SingleChildStatelessWidget {
|
||||
// final TState Function(BuildContext context) create;
|
||||
// final bool lazy;
|
||||
// final Widget Function(BuildContext context) child;
|
||||
// ControllerProvider({required this.create, this.lazy = true, required this.child, super.key})
|
||||
// : super(child: Builder(builder: child));
|
||||
//
|
||||
// @override
|
||||
// Widget buildWithChild(BuildContext context, Widget? child) => BlocProvider(
|
||||
// create: create,
|
||||
// lazy: lazy,
|
||||
// child: child,
|
||||
// );
|
||||
// }
|
@ -1,17 +0,0 @@
|
||||
//
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
//
|
||||
// import 'controller_provider.dart';
|
||||
//
|
||||
// class ControllersProvider extends StatelessWidget {
|
||||
// final List<ControllerProvider> controllers;
|
||||
// final Widget Function(BuildContext context) child;
|
||||
// const ControllersProvider({required this.controllers, required this.child, super.key});
|
||||
//
|
||||
// @override
|
||||
// Widget build(BuildContext context) => MultiBlocProvider(
|
||||
// providers: controllers,
|
||||
// child: Builder(builder: child)
|
||||
// );
|
||||
// }
|
@ -1,42 +0,0 @@
|
||||
// import 'package:flutter/material.dart';
|
||||
// import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
//
|
||||
// import '../infrastructure/controller.dart';
|
||||
// import '../infrastructure/loadable_state.dart';
|
||||
// import '../infrastructure/state_extensions.dart';
|
||||
// import 'components/background_loading_indicator.dart';
|
||||
// import 'components/error_bar.dart';
|
||||
// import 'components/primary_loading_indicator.dart';
|
||||
//
|
||||
// class LoadableControllerConsumer<TController extends Controller<TState>, TState extends LoadableState> extends StatelessWidget {
|
||||
// final Widget child;
|
||||
// const LoadableControllerConsumer({required this.child, super.key});
|
||||
//
|
||||
// final Duration animationDuration = const Duration(milliseconds: 200);
|
||||
//
|
||||
// @override
|
||||
// Widget build(BuildContext context) {
|
||||
// var state = context.readController<TController>().state;
|
||||
//
|
||||
// return Column(
|
||||
// children: [
|
||||
// // ErrorBar(visible: state.errorBarVisible()),
|
||||
// // Expanded(
|
||||
// // child: Stack(
|
||||
// // children: [
|
||||
// // PrimaryLoadingIndicator(visible: !state.hasStateData()),
|
||||
// // BackgroundLoadingIndicator(visible: state.isBackgroundLoading() && !state.errorBarVisible()),
|
||||
// //
|
||||
// // AnimatedOpacity(
|
||||
// // opacity: state.hasStateData() ? 1.0 : 0.0,
|
||||
// // duration: animationDuration,
|
||||
// // curve: Curves.easeInOut,
|
||||
// // child: state.hasStateData() ? child : const SizedBox.shrink()
|
||||
// // ),
|
||||
// // ],
|
||||
// // ),
|
||||
// // )
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
// }
|
@ -1,11 +0,0 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
|
||||
class SubSelectedControllerConsumer<TController extends Cubit<TFullState>, TFullState, TFilteredState> extends StatelessWidget {
|
||||
final Widget Function(BuildContext context, TFilteredState state) child;
|
||||
final TFilteredState Function(TFullState state) subSelect;
|
||||
const SubSelectedControllerConsumer({required this.subSelect, required this.child, super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) => BlocSelector<TController, TFullState, TFilteredState>(selector: subSelect, builder: child);
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
// import '../../../state/infrastructure/loadable_state.dart';
|
||||
// import '../../../state/infrastructure/state_extensions.dart';
|
||||
// import '../../../state/widgets/controller_consumer.dart';
|
||||
// import '../../../state/widgets/loadable_controller_consumer.dart';
|
||||
// import '../../../state/widgets/loadable_state_consumer.dart';
|
||||
// import '../../../state/widgets/sub_selected_controller_consumer.dart';
|
||||
// import '../../../state/widgets/controller_provider.dart';
|
||||
//
|
||||
|
@ -6,15 +6,14 @@ import 'package:in_app_review/in_app_review.dart';
|
||||
import '../../extensions/renderNotNull.dart';
|
||||
import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';
|
||||
|
||||
import '../../state/app/modules/gradeAverages/screens/grade_averages_view.dart';
|
||||
import '../../state/app/modules/gradeAverages/view/grade_averages_view.dart';
|
||||
import '../../state/app/modules/marianumMessage/view/marianum_message_list_view.dart';
|
||||
import '../../widget/ListItem.dart';
|
||||
import '../../widget/centeredLeading.dart';
|
||||
import '../../widget/infoDialog.dart';
|
||||
import '../settings/settings.dart';
|
||||
import 'more/feedback/feedbackDialog.dart';
|
||||
import 'more/gradeAverages/gradeAverage.dart';
|
||||
import 'more/holidays/holidays.dart';
|
||||
import 'more/message/message.dart';
|
||||
import 'more/roomplan/roomplan.dart';
|
||||
import 'more/share/selectShareTypeDialog.dart';
|
||||
|
||||
@ -31,9 +30,9 @@ class Overhang extends StatelessWidget {
|
||||
),
|
||||
body: ListView(
|
||||
children: [
|
||||
const ListItemNavigator(icon: Icons.newspaper, text: 'Marianum Message', target: Message()),
|
||||
const ListItemNavigator(icon: Icons.newspaper, text: 'Marianum Message', target: MarianumMessageListView()),
|
||||
const ListItemNavigator(icon: Icons.room, text: 'Raumplan', target: Roomplan()),
|
||||
const ListItemNavigator(icon: Icons.calculate, text: 'Notendurschnittsrechner', target: GradeAverage()),
|
||||
const ListItemNavigator(icon: Icons.calculate, text: 'Notendurschnittsrechner', target: GradeAveragesView()),
|
||||
const ListItemNavigator(icon: Icons.calendar_month, text: 'Schulferien', target: Holidays()),
|
||||
const Divider(),
|
||||
ListTile(
|
||||
@ -77,7 +76,7 @@ class Overhang extends StatelessWidget {
|
||||
),
|
||||
ListTile(
|
||||
leading: const Icon(Icons.science_outlined),
|
||||
onTap: () => pushScreen(context, withNavBar: false, screen: const GradeAveragesScreen()),
|
||||
// onTap: () => pushScreen(context, withNavBar: false, screen: const GradeAveragesScreen()),
|
||||
)
|
||||
],
|
||||
),
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
import 'package:filesize/filesize.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:hydrated_bloc/hydrated_bloc.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../storage/base/settingsProvider.dart';
|
||||
@ -109,6 +110,26 @@ class _DevToolsSettingsDialogState extends State<DevToolsSettingsDialog> {
|
||||
},
|
||||
trailing: const Icon(Icons.arrow_right),
|
||||
),
|
||||
ListTile(
|
||||
leading: const CenteredLeading(Icon(Icons.data_object)),
|
||||
title: const Text('BLOC State cache'),
|
||||
subtitle: FutureBuilder(
|
||||
future: const CacheView().totalSize(),
|
||||
builder: (context, snapshot) => Text("etwa ${snapshot.hasError ? "?" : snapshot.hasData ? filesize(snapshot.data) : "..."}\nLange tippen um zu löschen"),
|
||||
),
|
||||
onTap: () {
|
||||
// Navigator.push(context, MaterialPageRoute(builder: (context) => const CacheView()));
|
||||
},
|
||||
onLongPress: () {
|
||||
ConfirmDialog(
|
||||
title: 'BLOC-Cache löschen',
|
||||
content: 'Alle cache Einträge werden gelöscht. Der Cache wird bei Nutzung der App automatisch erneut aufgebaut',
|
||||
confirmButton: 'Unwiederruflich löschen',
|
||||
onConfirm: () => HydratedBloc.storage.clear(),
|
||||
).asDialog(context);
|
||||
},
|
||||
trailing: const Icon(Icons.arrow_right),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user