From afdc02f2a4a40a46fa6d2d7d666ba5b7dcd83dbb Mon Sep 17 00:00:00 2001
From: Pupsi28 <larslukasneuhaus@gmx.de>
Date: Sat, 30 Mar 2024 18:26:33 +0100
Subject: [PATCH 1/4] added connected double lessons with own setting

---
 lib/storage/timetable/timetableSettings.dart  |  4 ++-
 .../timetable/timetableSettings.g.dart        |  8 +++--
 lib/view/pages/timetable/timetable.dart       | 36 ++++++++++++++++++-
 lib/view/settings/defaultSettings.dart        |  4 ++-
 lib/view/settings/settings.dart               | 13 +++++++
 5 files changed, 60 insertions(+), 5 deletions(-)

diff --git a/lib/storage/timetable/timetableSettings.dart b/lib/storage/timetable/timetableSettings.dart
index 69d0729..cd1098d 100644
--- a/lib/storage/timetable/timetableSettings.dart
+++ b/lib/storage/timetable/timetableSettings.dart
@@ -4,7 +4,9 @@ part 'timetableSettings.g.dart';
 
 @JsonSerializable()
 class TimetableSettings {
-  TimetableSettings();
+  bool connectDoubleLessons;
+
+  TimetableSettings({required this.connectDoubleLessons});
 
   factory TimetableSettings.fromJson(Map<String, dynamic> json) => _$TimetableSettingsFromJson(json);
   Map<String, dynamic> toJson() => _$TimetableSettingsToJson(this);
diff --git a/lib/storage/timetable/timetableSettings.g.dart b/lib/storage/timetable/timetableSettings.g.dart
index 03f2db8..29c7e48 100644
--- a/lib/storage/timetable/timetableSettings.g.dart
+++ b/lib/storage/timetable/timetableSettings.g.dart
@@ -7,7 +7,11 @@ part of 'timetableSettings.dart';
 // **************************************************************************
 
 TimetableSettings _$TimetableSettingsFromJson(Map<String, dynamic> json) =>
-    TimetableSettings();
+    TimetableSettings(
+      connectDoubleLessons: json['connectDoubleLessons'] as bool,
+    );
 
 Map<String, dynamic> _$TimetableSettingsToJson(TimetableSettings instance) =>
-    <String, dynamic>{};
+    <String, dynamic>{
+      'connectDoubleLessons': instance.connectDoubleLessons,
+    };
diff --git a/lib/view/pages/timetable/timetable.dart b/lib/view/pages/timetable/timetable.dart
index d0c9614..58e93c2 100644
--- a/lib/view/pages/timetable/timetable.dart
+++ b/lib/view/pages/timetable/timetable.dart
@@ -243,9 +243,43 @@ class _TimetableState extends State<Timetable> {
     ];
   }
 
+  List<GetTimetableResponseObject> _removeDuplicates(TimetableProps data, Duration maxTimeBetweenDouble) {
+
+    List<GetTimetableResponseObject> timetableList = data.getTimetableResponse.result.toList();
+
+    if(timetableList.isEmpty){ return timetableList; }
+
+    timetableList.sort((a, b) => _parseWebuntisTimestamp(a.date, a.startTime).compareTo(_parseWebuntisTimestamp(b.date, b.startTime)));
+
+    GetTimetableResponseObject previousElement = timetableList.first;
+    for (var i = 1; i < timetableList.length; i++) {
+      GetTimetableResponseObject currentElement = timetableList.elementAt(i);
+
+      bool isSameSubject() => (currentElement.su.firstOrNull?.id ?? 1) == (previousElement.su.firstOrNull?.id ?? 2);
+      bool isNotSeparated() => _parseWebuntisTimestamp(previousElement.date, previousElement.endTime).add(maxTimeBetweenDouble).add(const Duration(seconds: 1))
+          .isAfter(_parseWebuntisTimestamp(currentElement.date, currentElement.startTime));
+
+      if(isSameSubject() && isNotSeparated()){
+        previousElement.endTime = currentElement.endTime;
+        timetableList.remove(currentElement);
+        i--;
+      }else{
+        previousElement = currentElement;
+      }
+    }
+
+    return timetableList;
+  }
+
   TimetableEvents _buildTableEvents(TimetableProps data) {
 
-    List<Appointment> appointments = data.getTimetableResponse.result.map((element) {
+    List<GetTimetableResponseObject> timetableList = data.getTimetableResponse.result.toList();
+
+    if(settings.val().timetableSettings.connectDoubleLessons){
+      timetableList = _removeDuplicates(data, const Duration(minutes: 5));
+    }
+
+    List<Appointment> appointments = timetableList.map((element) {
 
       GetRoomsResponse rooms = data.getRoomsResponse;
       GetSubjectsResponse subjects = data.getSubjectsResponse;
diff --git a/lib/view/settings/defaultSettings.dart b/lib/view/settings/defaultSettings.dart
index 1b99f8d..e26034e 100644
--- a/lib/view/settings/defaultSettings.dart
+++ b/lib/view/settings/defaultSettings.dart
@@ -22,7 +22,9 @@ class DefaultSettings {
           askedForPreferredGradeSystem: false,
           inputs: []
       ),
-      timetableSettings: TimetableSettings(),
+      timetableSettings: TimetableSettings(
+        connectDoubleLessons: false,
+      ),
       talkSettings: TalkSettings(
         sortFavoritesToTop: true,
         sortUnreadToTop: false,
diff --git a/lib/view/settings/settings.dart b/lib/view/settings/settings.dart
index ecdacd8..7d546e8 100644
--- a/lib/view/settings/settings.dart
+++ b/lib/view/settings/settings.dart
@@ -98,6 +98,19 @@ class _SettingsState extends State<Settings> {
 
             const Divider(),
 
+            ListTile(
+              leading: const Icon(Icons.calendar_view_day_outlined),
+              title: const Text("Doppelstunden als eine Stunde anzeigen"),
+              trailing: Checkbox(
+                value: settings.val().timetableSettings.connectDoubleLessons,
+                onChanged: (e) {
+                  settings.val(write: true).timetableSettings.connectDoubleLessons = e!;
+                },
+              ),
+            ),
+
+            const Divider(),
+
             ListTile(
               leading: const Icon(Icons.star_border),
               title: const Text("Favoriten im Talk nach oben sortieren"),

From a0c025b58be404fd345123d87be37cb3c6e97891 Mon Sep 17 00:00:00 2001
From: Pupsi28 <larslukasneuhaus@gmx.de>
Date: Sat, 30 Mar 2024 23:01:37 +0100
Subject: [PATCH 2/4] code fixes, added isSameOrAfter for DateTime objects,
 added check for teacher room and status

---
 lib/extensions/dateTime.dart            | 11 ++++++
 lib/view/pages/timetable/timetable.dart | 45 +++++++++++++++++++------
 lib/view/settings/settings.dart         |  4 ++-
 3 files changed, 48 insertions(+), 12 deletions(-)

diff --git a/lib/extensions/dateTime.dart b/lib/extensions/dateTime.dart
index 5ae297c..ebfda66 100644
--- a/lib/extensions/dateTime.dart
+++ b/lib/extensions/dateTime.dart
@@ -16,4 +16,15 @@ extension IsSameDay on DateTime {
   TimeOfDay toTimeOfDay() {
     return TimeOfDay(hour: hour, minute: minute);
   }
+
+  bool isSameDateTime(DateTime other) {
+    bool isSameDay = this.isSameDay(other);
+    bool isSameTimeOfDay = (toTimeOfDay() == other.toTimeOfDay());
+
+    return isSameDay && isSameTimeOfDay;
+  }
+
+  bool isSameOrAfter(DateTime other) {
+    return isSameDateTime(other) || isAfter(other);
+  }
 }
\ No newline at end of file
diff --git a/lib/view/pages/timetable/timetable.dart b/lib/view/pages/timetable/timetable.dart
index d14e4bf..3709368 100644
--- a/lib/view/pages/timetable/timetable.dart
+++ b/lib/view/pages/timetable/timetable.dart
@@ -246,9 +246,9 @@ class _TimetableState extends State<Timetable> {
 
   List<GetTimetableResponseObject> _removeDuplicates(TimetableProps data, Duration maxTimeBetweenDouble) {
 
-    List<GetTimetableResponseObject> timetableList = data.getTimetableResponse.result.toList();
+    List<GetTimetableResponseObject> timetableList = data.getTimetableResponse.result.toList( );
 
-    if(timetableList.isEmpty){ return timetableList; }
+    if ( timetableList.isEmpty ) return timetableList;
 
     timetableList.sort((a, b) => _parseWebuntisTimestamp(a.date, a.startTime).compareTo(_parseWebuntisTimestamp(b.date, b.startTime)));
 
@@ -256,15 +256,38 @@ class _TimetableState extends State<Timetable> {
     for (var i = 1; i < timetableList.length; i++) {
       GetTimetableResponseObject currentElement = timetableList.elementAt(i);
 
-      bool isSameSubject() => (currentElement.su.firstOrNull?.id ?? 1) == (previousElement.su.firstOrNull?.id ?? 2);
-      bool isNotSeparated() => _parseWebuntisTimestamp(previousElement.date, previousElement.endTime).add(maxTimeBetweenDouble).add(const Duration(seconds: 1))
-          .isAfter(_parseWebuntisTimestamp(currentElement.date, currentElement.startTime));
+      bool isSameLesson() {
+        int? currentSubjectId = currentElement.su.firstOrNull?.id;
+        int? previousSubjectId = previousElement.su.firstOrNull?.id;
 
-      if(isSameSubject() && isNotSeparated()){
+        if( currentSubjectId == null || previousSubjectId == null || currentSubjectId != previousSubjectId ) return false;
+
+        int? currentRoomId = currentElement.ro.firstOrNull?.id;
+        int? previousRoomId = previousElement.ro.firstOrNull?.id;
+
+        if( currentRoomId != previousRoomId ) return false;
+
+        int? currentTeacherId = currentElement.te.firstOrNull?.id;
+        int? previousTeacherId = previousElement.te.firstOrNull?.id;
+
+        if( currentTeacherId != previousTeacherId ) return false;
+
+        String? currentStatusCode = currentElement.code;
+        String? previousStatusCode = previousElement.code;
+
+        if( currentStatusCode != previousStatusCode ) return false;
+
+        return true;
+      }
+
+      bool isNotSeparated() =>  _parseWebuntisTimestamp( previousElement.date, previousElement.endTime ).add( maxTimeBetweenDouble )
+          .isSameOrAfter( _parseWebuntisTimestamp( currentElement.date, currentElement.startTime ) );
+
+      if ( isSameLesson() && isNotSeparated() ) {
         previousElement.endTime = currentElement.endTime;
-        timetableList.remove(currentElement);
+        timetableList.remove( currentElement );
         i--;
-      }else{
+      } else {
         previousElement = currentElement;
       }
     }
@@ -274,10 +297,10 @@ class _TimetableState extends State<Timetable> {
 
   TimetableEvents _buildTableEvents(TimetableProps data) {
 
-    List<GetTimetableResponseObject> timetableList = data.getTimetableResponse.result.toList();
+    List<GetTimetableResponseObject> timetableList = data.getTimetableResponse.result.toList( );
 
-    if(settings.val().timetableSettings.connectDoubleLessons){
-      timetableList = _removeDuplicates(data, const Duration(minutes: 5));
+    if( settings.val().timetableSettings.connectDoubleLessons ){
+      timetableList = _removeDuplicates( data, const Duration(minutes: 5) );
     }
 
     List<Appointment> appointments = timetableList.map((element) {
diff --git a/lib/view/settings/settings.dart b/lib/view/settings/settings.dart
index a8c4869..fc3473a 100644
--- a/lib/view/settings/settings.dart
+++ b/lib/view/settings/settings.dart
@@ -8,6 +8,7 @@ import 'package:provider/provider.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 
 import '../../model/accountData.dart';
+import '../../model/timetable/timetableProps.dart';
 import '../../notification/notifyUpdater.dart';
 import '../../storage/base/settingsProvider.dart';
 import '../../theming/appTheme.dart';
@@ -100,11 +101,12 @@ class _SettingsState extends State<Settings> {
 
             ListTile(
               leading: const Icon(Icons.calendar_view_day_outlined),
-              title: const Text("Doppelstunden als eine Stunde anzeigen"),
+              title: const Text('Doppelstunden zusammenhängend anzeigen'),
               trailing: Checkbox(
                 value: settings.val().timetableSettings.connectDoubleLessons,
                 onChanged: (e) {
                   settings.val(write: true).timetableSettings.connectDoubleLessons = e!;
+                  Provider.of<TimetableProps>(context, listen: false).run(renew: false);
                 },
               ),
             ),

From 681b5e42c3fbc91a249e86dc510b1108ec1d18e4 Mon Sep 17 00:00:00 2001
From: Pupsi28 <larslukasneuhaus@gmx.de>
Date: Sun, 31 Mar 2024 12:31:53 +0200
Subject: [PATCH 3/4] removed spaces

---
 lib/view/pages/timetable/timetable.dart | 28 ++++++++++++-------------
 1 file changed, 14 insertions(+), 14 deletions(-)

diff --git a/lib/view/pages/timetable/timetable.dart b/lib/view/pages/timetable/timetable.dart
index 3709368..0475af6 100644
--- a/lib/view/pages/timetable/timetable.dart
+++ b/lib/view/pages/timetable/timetable.dart
@@ -246,46 +246,46 @@ class _TimetableState extends State<Timetable> {
 
   List<GetTimetableResponseObject> _removeDuplicates(TimetableProps data, Duration maxTimeBetweenDouble) {
 
-    List<GetTimetableResponseObject> timetableList = data.getTimetableResponse.result.toList( );
+    List<GetTimetableResponseObject> timetableList = data.getTimetableResponse.result.toList();
 
-    if ( timetableList.isEmpty ) return timetableList;
+    if(timetableList.isEmpty) return timetableList;
 
     timetableList.sort((a, b) => _parseWebuntisTimestamp(a.date, a.startTime).compareTo(_parseWebuntisTimestamp(b.date, b.startTime)));
 
     GetTimetableResponseObject previousElement = timetableList.first;
-    for (var i = 1; i < timetableList.length; i++) {
+    for(var i = 1; i < timetableList.length; i++) {
       GetTimetableResponseObject currentElement = timetableList.elementAt(i);
 
       bool isSameLesson() {
         int? currentSubjectId = currentElement.su.firstOrNull?.id;
         int? previousSubjectId = previousElement.su.firstOrNull?.id;
 
-        if( currentSubjectId == null || previousSubjectId == null || currentSubjectId != previousSubjectId ) return false;
+        if(currentSubjectId == null || previousSubjectId == null || currentSubjectId != previousSubjectId) return false;
 
         int? currentRoomId = currentElement.ro.firstOrNull?.id;
         int? previousRoomId = previousElement.ro.firstOrNull?.id;
 
-        if( currentRoomId != previousRoomId ) return false;
+        if(currentRoomId != previousRoomId) return false;
 
         int? currentTeacherId = currentElement.te.firstOrNull?.id;
         int? previousTeacherId = previousElement.te.firstOrNull?.id;
 
-        if( currentTeacherId != previousTeacherId ) return false;
+        if(currentTeacherId != previousTeacherId) return false;
 
         String? currentStatusCode = currentElement.code;
         String? previousStatusCode = previousElement.code;
 
-        if( currentStatusCode != previousStatusCode ) return false;
+        if(currentStatusCode != previousStatusCode) return false;
 
         return true;
       }
 
-      bool isNotSeparated() =>  _parseWebuntisTimestamp( previousElement.date, previousElement.endTime ).add( maxTimeBetweenDouble )
-          .isSameOrAfter( _parseWebuntisTimestamp( currentElement.date, currentElement.startTime ) );
+      bool isNotSeparated() => _parseWebuntisTimestamp(previousElement.date, previousElement.endTime).add(maxTimeBetweenDouble)
+          .isSameOrAfter(_parseWebuntisTimestamp(currentElement.date, currentElement.startTime));
 
-      if ( isSameLesson() && isNotSeparated() ) {
+      if(isSameLesson() && isNotSeparated()) {
         previousElement.endTime = currentElement.endTime;
-        timetableList.remove( currentElement );
+        timetableList.remove(currentElement);
         i--;
       } else {
         previousElement = currentElement;
@@ -297,10 +297,10 @@ class _TimetableState extends State<Timetable> {
 
   TimetableEvents _buildTableEvents(TimetableProps data) {
 
-    List<GetTimetableResponseObject> timetableList = data.getTimetableResponse.result.toList( );
+    List<GetTimetableResponseObject> timetableList = data.getTimetableResponse.result.toList();
 
-    if( settings.val().timetableSettings.connectDoubleLessons ){
-      timetableList = _removeDuplicates( data, const Duration(minutes: 5) );
+    if(settings.val().timetableSettings.connectDoubleLessons) {
+      timetableList = _removeDuplicates(data, const Duration(minutes: 5));
     }
 
     List<Appointment> appointments = timetableList.map((element) {

From a1ad6aa58253f95992ac606ff02c65515126eee3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Elias=20M=C3=BCller?= <elias@elias-mueller.com>
Date: Sun, 31 Mar 2024 14:37:08 +0200
Subject: [PATCH 4/4] updated version and dependencies

---
 pubspec.yaml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pubspec.yaml b/pubspec.yaml
index 3d5c121..2bce963 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -17,7 +17,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
 # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
 # In Windows, build-name is used as the major, minor, and patch parts
 # of the product and file versions while build-number is used as the build suffix.
-version: 0.0.7+33
+version: 0.0.8+34
 
 environment:
   sdk: '>3.0.0'