From a435f56f2eccce10f7590a3796a6dee92b847e6a Mon Sep 17 00:00:00 2001 From: Kima Date: Thu, 1 Feb 2024 23:46:36 +0100 Subject: [PATCH] ahhhhhhh --- .../settings/submenu/edit_subject.dart | 346 +++++++++++++++++- .../settings/submenu/edit_subject.i18n.dart | 42 +++ .../settings/submenu/personalize_screen.dart | 81 ++-- 3 files changed, 444 insertions(+), 25 deletions(-) create mode 100644 filcnaplo_mobile_ui/lib/screens/settings/submenu/edit_subject.i18n.dart diff --git a/filcnaplo_mobile_ui/lib/screens/settings/submenu/edit_subject.dart b/filcnaplo_mobile_ui/lib/screens/settings/submenu/edit_subject.dart index 4ea5391..65aa95b 100644 --- a/filcnaplo_mobile_ui/lib/screens/settings/submenu/edit_subject.dart +++ b/filcnaplo_mobile_ui/lib/screens/settings/submenu/edit_subject.dart @@ -1,24 +1,48 @@ +// ignore_for_file: use_build_context_synchronously + +import 'package:filcnaplo/api/providers/database_provider.dart'; +import 'package:filcnaplo/api/providers/user_provider.dart'; import 'package:filcnaplo/models/settings.dart'; import 'package:filcnaplo/theme/colors/colors.dart'; import 'package:filcnaplo/utils/format.dart'; import 'package:filcnaplo_kreta_api/models/subject.dart'; -import 'package:flutter/cupertino.dart'; +import 'package:filcnaplo_kreta_api/models/teacher.dart'; +import 'package:filcnaplo_kreta_api/providers/absence_provider.dart'; +import 'package:filcnaplo_kreta_api/providers/grade_provider.dart'; +import 'package:filcnaplo_kreta_api/providers/timetable_provider.dart'; +import 'package:filcnaplo_mobile_ui/common/panel/panel_button.dart'; +import 'package:filcnaplo_mobile_ui/common/splitted_panel/splitted_panel.dart'; +import 'package:filcnaplo_mobile_ui/screens/settings/settings_helper.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_feather_icons/flutter_feather_icons.dart'; import 'package:provider/provider.dart'; +import 'edit_subject.i18n.dart'; + class EditSubjectScreen extends StatefulWidget { - const EditSubjectScreen({super.key, required this.subject}); + const EditSubjectScreen( + {super.key, required this.subject, required this.teacher}); final GradeSubject subject; + final Teacher teacher; @override EditSubjectScreenState createState() => EditSubjectScreenState(); } class EditSubjectScreenState extends State { + late SettingsProvider settingsProvider; + late DatabaseProvider databaseProvider; + late UserProvider user; + + final _subjectName = TextEditingController(); + final _teacherName = TextEditingController(); + @override Widget build(BuildContext context) { - SettingsProvider settingsProvider = Provider.of(context); + settingsProvider = Provider.of(context); + databaseProvider = Provider.of(context); + user = Provider.of(context); return Scaffold( appBar: AppBar( @@ -36,17 +60,331 @@ class EditSubjectScreenState extends State { : FontStyle.normal, ), ), + actions: [ + IconButton( + onPressed: () async { + Map subs = await databaseProvider.userQuery + .renamedSubjects(userId: user.id!); + subs.remove(widget.subject.id); + databaseProvider.userStore + .storeRenamedSubjects(subs, userId: user.id!); + + Map teach = await databaseProvider.userQuery + .renamedTeachers(userId: user.id!); + teach.remove(widget.teacher.id); + databaseProvider.userStore + .storeRenamedTeachers(teach, userId: user.id!); + + updateProviders(); + + setState(() {}); + Navigator.of(context).pop(); + }, + icon: const Icon(FeatherIcons.trash2), + ), + const SizedBox( + width: 8.0, + ), + ], ), body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 24.0), child: Column( children: [ - + // rename subject + SplittedPanel( + padding: const EdgeInsets.only(top: 8.0), + cardPadding: const EdgeInsets.all(4.0), + isSeparated: true, + children: [ + PanelButton( + onPressed: () { + showSubjectRenameDialog(); + }, + title: Text("rename_it".i18n), + leading: Icon( + FeatherIcons.penTool, + size: 22.0, + color: AppColors.of(context).text.withOpacity(0.95), + ), + borderRadius: const BorderRadius.vertical( + top: Radius.circular(12.0), + bottom: Radius.circular(12.0), + ), + ), + ], + ), + // rename teacher + SplittedPanel( + padding: const EdgeInsets.only(top: 9.0), + cardPadding: const EdgeInsets.all(4.0), + isSeparated: true, + children: [ + PanelButton( + onPressed: () { + showTeacherRenameDialog(); + }, + title: Text("rename_te".i18n), + leading: Icon( + FeatherIcons.user, + size: 22.0, + color: AppColors.of(context).text.withOpacity(0.95), + ), + borderRadius: const BorderRadius.vertical( + top: Radius.circular(12.0), + bottom: Radius.circular(12.0), + ), + ), + ], + ), + // edit rounding + SplittedPanel( + padding: const EdgeInsets.only(top: 9.0), + cardPadding: const EdgeInsets.all(4.0), + isSeparated: true, + children: [ + PanelButton( + onPressed: () { + SettingsHelper.rounding(context); + setState(() {}); + }, + title: Text( + "rounding".i18n, + style: TextStyle( + color: AppColors.of(context).text.withOpacity(.95), + ), + ), + leading: Icon( + FeatherIcons.gitCommit, + size: 22.0, + color: AppColors.of(context).text.withOpacity(.95), + ), + trailing: Text( + (settingsProvider.rounding / 10).toStringAsFixed(1), + style: const TextStyle(fontSize: 14.0), + ), + borderRadius: const BorderRadius.vertical( + top: Radius.circular(12.0), + bottom: Radius.circular(12.0), + ), + ), + ], + ), ], ), ), ), ); } + + // rename dialogs + void showSubjectRenameDialog() { + _subjectName.text = widget.subject.renamedTo ?? ''; + + showDialog( + context: context, + builder: (context) => StatefulBuilder(builder: (context, setS) { + return AlertDialog( + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(14.0))), + title: Text("rename_subject".i18n), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.background, + borderRadius: + const BorderRadius.all(Radius.circular(12.0))), + padding: const EdgeInsets.symmetric(vertical: 10.0), + child: Center( + child: Text( + widget.subject.name, + style: const TextStyle( + fontWeight: FontWeight.w500, fontSize: 16.0), + ), + ), + ), + const Padding( + padding: EdgeInsets.symmetric(vertical: 8.0), + child: Icon(FeatherIcons.arrowDown, size: 32), + ), + TextField( + controller: _subjectName, + decoration: InputDecoration( + border: OutlineInputBorder( + borderSide: + const BorderSide(color: Colors.grey, width: 1.5), + borderRadius: BorderRadius.circular(12.0), + ), + focusedBorder: OutlineInputBorder( + borderSide: + const BorderSide(color: Colors.grey, width: 1.5), + borderRadius: BorderRadius.circular(12.0), + ), + contentPadding: const EdgeInsets.symmetric(horizontal: 12.0), + hintText: "modified_name".i18n, + suffixIcon: IconButton( + icon: const Icon( + FeatherIcons.x, + color: Colors.grey, + ), + onPressed: () { + setState(() { + _subjectName.text = ""; + }); + }, + ), + ), + ), + ], + ), + actions: [ + TextButton( + child: Text( + "cancel".i18n, + style: const TextStyle(fontWeight: FontWeight.w500), + ), + onPressed: () { + Navigator.of(context).maybePop(); + }, + ), + TextButton( + child: Text( + "done".i18n, + style: const TextStyle(fontWeight: FontWeight.w500), + ), + onPressed: () async { + Map renamedSubjs = await databaseProvider + .userQuery + .renamedSubjects(userId: user.id!); + + renamedSubjs[widget.subject.id] = _subjectName.text; + + await databaseProvider.userStore + .storeRenamedSubjects(renamedSubjs, userId: user.id!); + + updateProviders(); + + Navigator.of(context).pop(); + setState(() {}); + }, + ), + ], + ); + }), + ).then((val) { + _subjectName.text = ""; + }); + } + + void showTeacherRenameDialog() { + _teacherName.text = widget.teacher.renamedTo ?? ''; + + showDialog( + context: context, + builder: (context) => StatefulBuilder(builder: (context, setS) { + return AlertDialog( + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.all(Radius.circular(14.0))), + title: Text("rename_teacher".i18n), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Container( + decoration: BoxDecoration( + color: Theme.of(context).colorScheme.background, + borderRadius: + const BorderRadius.all(Radius.circular(12.0))), + padding: const EdgeInsets.symmetric(vertical: 10.0), + child: Center( + child: Text( + widget.teacher.name, + style: const TextStyle( + fontWeight: FontWeight.w500, fontSize: 16.0), + ), + ), + ), + const Padding( + padding: EdgeInsets.symmetric(vertical: 8.0), + child: Icon(FeatherIcons.arrowDown, size: 32), + ), + TextField( + controller: _teacherName, + decoration: InputDecoration( + border: OutlineInputBorder( + borderSide: + const BorderSide(color: Colors.grey, width: 1.5), + borderRadius: BorderRadius.circular(12.0), + ), + focusedBorder: OutlineInputBorder( + borderSide: + const BorderSide(color: Colors.grey, width: 1.5), + borderRadius: BorderRadius.circular(12.0), + ), + contentPadding: const EdgeInsets.symmetric(horizontal: 12.0), + hintText: "modified_name".i18n, + suffixIcon: IconButton( + icon: const Icon( + FeatherIcons.x, + color: Colors.grey, + ), + onPressed: () { + setState(() { + _teacherName.text = ""; + }); + }, + ), + ), + ), + ], + ), + actions: [ + TextButton( + child: Text( + "cancel".i18n, + style: const TextStyle(fontWeight: FontWeight.w500), + ), + onPressed: () { + Navigator.of(context).maybePop(); + }, + ), + TextButton( + child: Text( + "done".i18n, + style: const TextStyle(fontWeight: FontWeight.w500), + ), + onPressed: () async { + Map renamedTeach = await databaseProvider + .userQuery + .renamedTeachers(userId: user.id!); + + renamedTeach[widget.teacher.id] = _teacherName.text; + + await databaseProvider.userStore + .storeRenamedTeachers(renamedTeach, userId: user.id!); + + updateProviders(); + + Navigator.of(context).pop(); + setState(() {}); + }, + ), + ], + ); + }), + ).then((val) { + _teacherName.text = ""; + }); + } + + void updateProviders() async { + await Provider.of(context, listen: false) + .convertBySettings(); + await Provider.of(context, listen: false) + .convertBySettings(); + await Provider.of(context, listen: false) + .convertBySettings(); + } } diff --git a/filcnaplo_mobile_ui/lib/screens/settings/submenu/edit_subject.i18n.dart b/filcnaplo_mobile_ui/lib/screens/settings/submenu/edit_subject.i18n.dart new file mode 100644 index 0000000..300517a --- /dev/null +++ b/filcnaplo_mobile_ui/lib/screens/settings/submenu/edit_subject.i18n.dart @@ -0,0 +1,42 @@ +import 'package:i18n_extension/i18n_extension.dart'; + +extension SettingsLocalization on String { + static final _t = Translations.byLocale("hu_hu") + + { + "en_en": { + "rename_it": "Rename Subject", + "rename_te": "Rename Teacher", + "rounding": "Rounding", + "gs_mode": "Good Student Mode", + "rename_subject": "Rename Subject", + "modified_name": "Modified Name", + "cancel": "Cancel", + "done": "Done", + }, + "hu_hu": { + "rename_it": "Tantárgy átnevezése", + "rename_te": "Tanár átnevezése", + "rounding": "Kerekítés", + "gs_mode": "Jó tanuló mód", + "rename_subject": "Tantárgy átnevezése", + "modified_name": "Módosított név", + "cancel": "Mégse", + "done": "Kész", + }, + "de_de": { + "rename_it": "Betreff umbenennen", + "rename_te": "Lehrer umbenennen", + "rounding": "Rundung", + "gs_mode": "Guter Student Modus", + "rename_subject": "Fach umbenennen", + "modified_name": "Geänderter Name", + "cancel": "Abbrechen", + "done": "Erledigt", + }, + }; + + String get i18n => localize(this, _t); + String fill(List params) => localizeFill(this, params); + String plural(int value) => localizePlural(value, this, _t); + String version(Object modifier) => localizeVersion(modifier, this, _t); +} diff --git a/filcnaplo_mobile_ui/lib/screens/settings/submenu/personalize_screen.dart b/filcnaplo_mobile_ui/lib/screens/settings/submenu/personalize_screen.dart index 779d44f..bd51c76 100644 --- a/filcnaplo_mobile_ui/lib/screens/settings/submenu/personalize_screen.dart +++ b/filcnaplo_mobile_ui/lib/screens/settings/submenu/personalize_screen.dart @@ -5,7 +5,7 @@ import 'package:filcnaplo/helpers/subject.dart'; import 'package:filcnaplo/models/settings.dart'; import 'package:filcnaplo/theme/colors/colors.dart'; import 'package:filcnaplo/utils/format.dart'; -import 'package:filcnaplo_kreta_api/models/subject.dart'; +import 'package:filcnaplo_kreta_api/models/grade.dart'; import 'package:filcnaplo_kreta_api/providers/absence_provider.dart'; import 'package:filcnaplo_kreta_api/providers/grade_provider.dart'; import 'package:filcnaplo_kreta_api/providers/timetable_provider.dart'; @@ -65,8 +65,8 @@ class PersonalizeSettingsScreenState extends State late AnimationController _hideContainersController; - late List editedSubjects; - late List otherSubjects; + late List editedShit; + late List otherShit; late List tiles; @@ -74,21 +74,49 @@ class PersonalizeSettingsScreenState extends State void initState() { super.initState(); - editedSubjects = Provider.of(context, listen: false) + editedShit = Provider.of(context, listen: false) .grades .where((e) => e.teacher.isRenamed || e.subject.isRenamed) - .map((e) => e.subject) + // .map((e) => e.subject) .toSet() .toList() - ..sort((a, b) => a.name.compareTo(b.name)); + ..sort((a, b) => a.subject.name.compareTo(b.subject.name)); - otherSubjects = Provider.of(context, listen: false) + List other = Provider.of(context, listen: false) .grades .where((e) => !e.teacher.isRenamed && !e.subject.isRenamed) - .map((e) => e.subject) .toSet() .toList() - ..sort((a, b) => a.name.compareTo(b.name)); + ..sort((a, b) => a.subject.name.compareTo(b.subject.name)); + + otherShit = []; + var addedOthers = []; + + for (var e in other) { + if (addedOthers.contains(e.subject.id)) continue; + addedOthers.add(e.subject.id); + + otherShit.add(e); + } + + otherShit = otherShit + ..sort((a, b) => + a.subject.name.compareTo(b.subject.name)); // just cuz why not + + // editedTeachers = Provider.of(context, listen: false) + // .grades + // .where((e) => e.teacher.isRenamed || e.subject.isRenamed) + // .map((e) => e.teacher) + // .toSet() + // .toList(); + // // ..sort((a, b) => a.name.compareTo(b.name)); + // otherTeachers = Provider.of(context, listen: false) + // .grades + // .where((e) => !e.teacher.isRenamed && !e.subject.isRenamed) + // .map((e) => e.teacher) + // .toSet() + // .toList(); + // ..sort((a, b) => a.name.compareTo(b.name)); _hideContainersController = AnimationController( vsync: this, duration: const Duration(milliseconds: 200)); @@ -97,19 +125,25 @@ class PersonalizeSettingsScreenState extends State void buildSubjectTiles() { List subjectTiles = []; + var added = []; var i = 0; - for (var s in editedSubjects) { + for (var s in editedShit) { + if (added.contains(s.subject.id)) continue; + Widget widget = PanelButton( onPressed: () => Navigator.of(context, rootNavigator: true).push( CupertinoPageRoute( - builder: (context) => EditSubjectScreen(subject: s), + builder: (context) => EditSubjectScreen( + subject: s.subject, + teacher: s.teacher, // not sure why, but it works tho + ), ), ), title: Text( - (s.isRenamed && settingsProvider.renamedSubjectsEnabled - ? s.renamedTo - : s.name.capital()) ?? + (s.subject.isRenamed && settingsProvider.renamedSubjectsEnabled + ? s.subject.renamedTo + : s.subject.name.capital()) ?? '', style: TextStyle( color: AppColors.of(context).text.withOpacity(.95), @@ -119,7 +153,7 @@ class PersonalizeSettingsScreenState extends State ), ), leading: Icon( - SubjectIcon.resolveVariant(context: context, subject: s), + SubjectIcon.resolveVariant(context: context, subject: s.subject), size: 22.0, color: AppColors.of(context).text.withOpacity(.95), ), @@ -130,12 +164,13 @@ class PersonalizeSettingsScreenState extends State ), borderRadius: BorderRadius.vertical( top: Radius.circular(i == 0 ? 12.0 : 4.0), - bottom: Radius.circular(i + 1 == editedSubjects.length ? 12.0 : 4.0), + bottom: Radius.circular(i + 1 == editedShit.length ? 12.0 : 4.0), ), ); i += 1; subjectTiles.add(widget); + added.add(s.subject.id); } tiles = subjectTiles; @@ -468,11 +503,11 @@ class PersonalizeSettingsScreenState extends State isTransparent: true, children: [ DropdownButton2( - items: otherSubjects + items: otherShit .map((item) => DropdownMenuItem( - value: item.id, + value: item.subject.id, child: Text( - item.name, + item.subject.name, style: TextStyle( fontSize: 14, fontWeight: FontWeight.bold, @@ -486,8 +521,12 @@ class PersonalizeSettingsScreenState extends State Navigator.of(context, rootNavigator: true).push( CupertinoPageRoute( builder: (context) => EditSubjectScreen( - subject: - otherSubjects.firstWhere((e) => e.id == v), + subject: otherShit + .firstWhere((e) => e.subject.id == v) + .subject, + teacher: otherShit + .firstWhere((e) => e.subject.id == v) + .teacher, ), ), );