// GCG.MeinCantor - Die Schulplattform für Cantorianer. // Copyright (C) 2021-2022 Georg-Cantor-Gymnasium Halle (Saale) // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published // by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . import 'package:meincantor/presets/teachers.dart'; import 'package:meincantor/presets/subjects.dart'; import 'package:meincantor/presets/colors.dart'; import 'package:flutter/material.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'Settings/Pages/plan_settings.dart'; class ClassTimetableBuilder { final RefreshIndicator view; ClassTimetableBuilder({required this.view}); factory ClassTimetableBuilder.buildView( Map json, BuildContext context) { List list = LessonsListBuilder.buildList(json).lessons; String info = TimetableInfo.fromJson(json).info; if (info.isNotEmpty) { list.insert( 0, ListTile( title: const Text("Informationen"), leading: const Icon(MdiIcons.information), onTap: () { showModalBottomSheet( isScrollControlled: true, shape: const RoundedRectangleBorder( borderRadius: BorderRadius.only( topLeft: Radius.circular(25.0), topRight: Radius.circular(25.0)), ), context: context, builder: (BuildContext context) { return SizedBox( height: 400, child: ListView( children: [ ListTile( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(25.0)), title: const Text("Informationen", style: TextStyle(fontWeight: FontWeight.bold)), leading: const Icon(Icons.arrow_back), onTap: () { Navigator.of(context).pop(); }, ), Padding( padding: const EdgeInsets.all(20), child: Text(info), ), ], ), ); }, ); }, )); } return ClassTimetableBuilder( view: RefreshIndicator( onRefresh: () { return Future.delayed(const Duration(seconds: 1)); }, child: ListView( physics: const AlwaysScrollableScrollPhysics(), children: list, ), )); } } Future buildLessonColor(String lesson) async { SharedPreferences prefs = await SharedPreferences.getInstance(); if (!prefs.containsKey("color$lesson")) { Color lessonPresetColor = colors[lesson] ?? Colors.grey[700]; prefs.setInt("color$lesson", lessonPresetColor.value); } Color lessonColor = Color(prefs.getInt("color$lesson")!); return lessonColor; } class LessonsListBuilder { final List lessons; LessonsListBuilder({required this.lessons}); factory LessonsListBuilder.buildList(Map json, {int count = 0}) { List children = []; for (var element in ClassTimetable.fromJson(json).timetable) { List cardChildren = []; if (element.count.toString() == count.toString() || count == 0) { cardChildren.add(ListTile( title: Text(element.count.toString() + '.' + ' ' + element.name, style: TextStyle(color: element.fontColor)), subtitle: Row(children: [ Icon(Icons.person_outline, color: element.fontColor), const SizedBox(width: 5), Text(element.teacher, style: TextStyle(color: element.fontColor)), const Spacer(), Icon(MdiIcons.door, color: element.fontColor), const SizedBox(width: 5), Text(element.room, style: TextStyle(color: element.fontColor)) ]), leading: Icon(MdiIcons.clockOutline, color: element.fontColor))); if (element.info != '') { cardChildren.add(ListTile( title: Text(element.info, style: TextStyle(color: element.fontColor)))); } Widget card = FutureBuilder( future: buildBlacklist(), builder: (context, snapshot) { if (snapshot.hasData) { if (!((snapshot.data as List).contains(element.id))) { return FutureBuilder( future: element.color, builder: (context, snapshot) { if (snapshot.hasData) { return Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15.0), ), color: snapshot.data as Color, child: Column( children: cardChildren, )); } else { return (const Center( child: CircularProgressIndicator())); } }, ); } else { return const SizedBox.shrink(); } } else { return const LinearProgressIndicator(); } }); children.add(card); } } return LessonsListBuilder(lessons: children); } } class TimetableInfo { final String info; TimetableInfo({required this.info}); factory TimetableInfo.fromJson(Map json) { return TimetableInfo(info: json['info']); } } class ClassTimetable { final List timetable; ClassTimetable({required this.timetable}); factory ClassTimetable.fromJson(Map json) { List lessons = []; json['courses'].forEach((value) { String subject; String teacher; String room; String info; Color fontColor; if (value['Fa'].runtimeType != String) { subject = value['Fa']['#text']; } else { subject = value['Fa']; } if (value['Le'].runtimeType != String) { teacher = value['Le']['#text']; } else { teacher = value['Le']; } if (value['Ra'].runtimeType != String && value['Ra'].runtimeType != int) { if (value['Ra']['#text'] == ' ' || value['Ra']['#text'] == null) { room = ''; } else { room = value['Ra']['#text'].toString(); } } else if (value['Ra'] == ' ') { room = ''; } else { room = value['Ra'].toString(); } if (subject == '---') { fontColor = Colors.red; } else { fontColor = Colors.white; } if (value['If'].runtimeType != String) { info = ''; } else { info = value['If']; } Future lessonColor = buildLessonColor(subject); lessons.add(TimetableLesson( value['St'], value["Nr"] ?? 0, subject == ' ' ? "---" : subjects[subject] ?? subject.toString(), teachers[teacher] ?? teacher.toString(), room.toString(), lessonColor, fontColor, info)); }); return ClassTimetable(timetable: lessons); } } class TimetableLesson { final int count; final int id; final String name; final String teacher; final String room; final Future color; final Color fontColor; final String info; const TimetableLesson(this.count, this.id, this.name, this.teacher, this.room, this.color, this.fontColor, this.info); }