Skip to content

Commit

Permalink
feat: Create rating system hydrated bloc
Browse files Browse the repository at this point in the history
  • Loading branch information
0niel committed Jan 6, 2024
1 parent 5bb7883 commit e7ec9ec
Show file tree
Hide file tree
Showing 15 changed files with 603 additions and 140 deletions.
49 changes: 30 additions & 19 deletions lib/presentation/core/routes/routes.dart
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,9 @@ import 'package:rtu_mirea_app/presentation/pages/profile/profile_scores_page.dar
import 'package:rtu_mirea_app/presentation/pages/profile/profile_page.dart';
import 'package:rtu_mirea_app/presentation/pages/profile/profile_settings_page.dart';
import 'package:rtu_mirea_app/presentation/widgets/images_view_gallery.dart';
import 'package:rtu_mirea_app/rating_system_calculator/models/models.dart';
import 'package:rtu_mirea_app/rating_system_calculator/view/about_rating_system_page.dart';
import 'package:rtu_mirea_app/rating_system_calculator/view/subject_page.dart';
import 'package:rtu_mirea_app/schedule/view/schedule_details_page.dart';
import 'package:rtu_mirea_app/rating_system_calculator/view/rating_system_calculator_page.dart';
import 'package:rtu_mirea_app/schedule/view/schedule_page.dart';
Expand Down Expand Up @@ -108,25 +110,34 @@ GoRouter createRouter() => GoRouter(
],
),
]),
StatefulShellBranch(navigatorKey: _servicesNavigatorKey, routes: [
GoRoute(
path: '/services',
builder: (context, state) => const ServicesPage(),
routes: [
GoRoute(
path: 'rating-system-calculator',
builder: (context, state) =>
const RatingSystemCalculatorPage(),
routes: [
GoRoute(
path: 'about',
builder: (context, state) =>
const AboutRatingSystemPage(),
),
]),
],
),
]),
StatefulShellBranch(
navigatorKey: _servicesNavigatorKey,
routes: [
GoRoute(
path: '/services',
builder: (context, state) => const ServicesPage(),
routes: [
GoRoute(
path: 'rating-system-calculator',
builder: (context, state) =>
const RatingSystemCalculatorPage(),
routes: [
GoRoute(
path: 'about',
builder: (context, state) =>
const AboutRatingSystemPage(),
),
GoRoute(
path: 'subject',
builder: (context, state) => SubjectPage(
subject: state.extra as Subject,
),
),
]),
],
),
],
),
StatefulShellBranch(navigatorKey: _profileNavigatorKey, routes: [
GoRoute(
path: '/profile',
Expand Down
62 changes: 62 additions & 0 deletions lib/rating_system_calculator/bloc/rating_system_bloc.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import 'package:equatable/equatable.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:rtu_mirea_app/rating_system_calculator/models/models.dart';

part 'rating_system_bloc.g.dart';
part 'rating_system_event.dart';
part 'rating_system_state.dart';

typedef Group = String;

class RatingSystemBloc
extends HydratedBloc<RatingSystemEvent, RatingSystemState> {
RatingSystemBloc() : super(const RatingSystemState()) {
on<UpdateSubjectsByCurrentSchedule>(_onUpdateSubjectsByCurrentSchedule);
}

void _onUpdateSubjectsByCurrentSchedule(
UpdateSubjectsByCurrentSchedule event,
Emitter<RatingSystemState> emit,
) {
final actualSubjects = event.subjects;

final newSubjects = <(Group, Subject)>[];

for (final actualSubject in actualSubjects) {
final index = state.subjects.indexWhere(
(element) =>
element.$2.name == actualSubject.name && element.$1 == event.group,
);

if (index == -1) {
newSubjects.add(
(event.group, actualSubject),
);
} else {
final subject = state.subjects[index];

if (actualSubject.mainScore == 0 &&
actualSubject.additionalScore == 0 &&
actualSubject.classScore == 0) {
state.subjects.removeAt(index);
} else {
newSubjects.add(subject);
}
}
}

emit(
state.copyWith(
subjects: newSubjects,
),
);
}

@override
RatingSystemState? fromJson(Map<String, dynamic> json) =>
RatingSystemState.fromJson(json);

@override
Map<String, dynamic>? toJson(RatingSystemState state) => state.toJson();
}
19 changes: 19 additions & 0 deletions lib/rating_system_calculator/bloc/rating_system_bloc.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 18 additions & 0 deletions lib/rating_system_calculator/bloc/rating_system_event.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
part of 'rating_system_bloc.dart';

abstract class RatingSystemEvent extends Equatable {
const RatingSystemEvent();
}

class UpdateSubjectsByCurrentSchedule extends RatingSystemEvent {
const UpdateSubjectsByCurrentSchedule({
required this.group,
required this.subjects,
});

final Group group;
final List<Subject> subjects;

@override
List<Object> get props => [group, subjects];
}
55 changes: 55 additions & 0 deletions lib/rating_system_calculator/bloc/rating_system_state.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
part of 'rating_system_bloc.dart';

@JsonSerializable()
class RatingSystemState extends Equatable {
const RatingSystemState({
this.subjects = const [],
});

@SubjectsConverter()
final List<(Group, Subject)> subjects;

factory RatingSystemState.fromJson(Map<String, dynamic> json) =>
_$RatingSystemStateFromJson(json);

Map<String, dynamic> toJson() => _$RatingSystemStateToJson(this);

RatingSystemState copyWith({
List<(Group, Subject)>? subjects,
}) {
return RatingSystemState(
subjects: subjects ?? this.subjects,
);
}

@override
List<Object?> get props => [
subjects,
];
}

class SubjectsConverter
implements JsonConverter<List<(Group, Subject)>, List<dynamic>> {
const SubjectsConverter();

@override
List<(Group, Subject)> fromJson(List<dynamic> json) {
return json
.map(
(dynamic e) => (e['group'] as String, Subject.fromJson(e)),
)
.toList();
}

@override
List<dynamic> toJson(List<(Group, Subject)> object) {
return object
.map(
(e) => {
'group': e.$1,
...e.$2.toJson(),
},
)
.toList();
}
}
1 change: 1 addition & 0 deletions lib/rating_system_calculator/models/models.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export 'subject.dart';
70 changes: 70 additions & 0 deletions lib/rating_system_calculator/models/subject.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import 'package:equatable/equatable.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

part 'subject.g.dart';

@immutable
@JsonSerializable()
class Subject extends Equatable {
const Subject({
required this.name,
required this.dates,
this.mainScore,
this.additionalScore,
this.classScore,
this.visitedDays,
});

/// {@macro from_json}
factory Subject.fromJson(Map<String, dynamic> json) =>
_$SubjectFromJson(json);

/// {@macro to_json}
Map<String, dynamic> toJson() => _$SubjectToJson(this);

/// Название предмета.
final String name;

/// Даты занятия.
final List<DateTime> dates;

/// Основные баллы.
final double? mainScore;

/// Дополнительные баллы.
final double? additionalScore;

/// Баллы за работу на занятиях.
final double? classScore;

/// Посещенные дни.
final List<DateTime>? visitedDays;

Subject copyWith({
String? name,
List<DateTime>? dates,
double? mainScore,
double? additionalScore,
double? classScore,
List<DateTime>? visitedDays,
}) {
return Subject(
name: name ?? this.name,
dates: dates ?? this.dates,
mainScore: mainScore ?? this.mainScore,
additionalScore: additionalScore ?? this.additionalScore,
classScore: classScore ?? this.classScore,
visitedDays: visitedDays ?? this.visitedDays,
);
}

@override
List<Object?> get props => [
name,
dates,
mainScore,
additionalScore,
classScore,
visitedDays,
];
}
30 changes: 30 additions & 0 deletions lib/rating_system_calculator/models/subject.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:rtu_mirea_app/presentation/theme.dart';
import 'package:rtu_mirea_app/presentation/typography.dart';
import 'package:rtu_mirea_app/presentation/widgets/buttons/primary_button.dart';
import 'package:rtu_mirea_app/rating_system_calculator/rating_system_calculator.dart';
import 'package:rtu_mirea_app/rating_system_calculator/widgets/scores_table.dart';
import 'package:unicons/unicons.dart';

class AboutRatingSystemPage extends StatelessWidget {
Expand Down
Loading

0 comments on commit e7ec9ec

Please sign in to comment.