From a922e0f8ae755c9329bcf5512f25ccbfef6f4ce0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Elias=20M=C3=BCller?= <elias@elias-mueller.com>
Date: Wed, 7 Jun 2023 11:06:43 +0200
Subject: [PATCH] Added option to sort talk favorites to top

---
 .../marianumcloud/talk/room/getRoomResponse.dart |  7 ++++---
 lib/model/timetable/timetableProps.dart          |  2 +-
 lib/storage/base/settings.dart                   |  5 ++++-
 lib/storage/base/settings.g.dart                 |  3 +++
 lib/storage/base/settingsProvider.dart           |  4 ++++
 lib/storage/talk/talkSettings.dart               | 13 +++++++++++++
 lib/storage/talk/talkSettings.g.dart             | 16 ++++++++++++++++
 lib/view/pages/talk/chatList.dart                |  6 +++++-
 lib/view/settings/settings.dart                  | 15 +++++++++++++++
 9 files changed, 65 insertions(+), 6 deletions(-)
 create mode 100644 lib/storage/talk/talkSettings.dart
 create mode 100644 lib/storage/talk/talkSettings.g.dart

diff --git a/lib/api/marianumcloud/talk/room/getRoomResponse.dart b/lib/api/marianumcloud/talk/room/getRoomResponse.dart
index 7a03bdc..1e23588 100644
--- a/lib/api/marianumcloud/talk/room/getRoomResponse.dart
+++ b/lib/api/marianumcloud/talk/room/getRoomResponse.dart
@@ -14,12 +14,13 @@ class GetRoomResponse extends ApiResponse {
   factory GetRoomResponse.fromJson(Map<String, dynamic> json) => _$GetRoomResponseFromJson(json);
   Map<String, dynamic> toJson() => _$GetRoomResponseToJson(this);
 
-  List<GetRoomResponseObject> sortByLastActivity() {
+  List<GetRoomResponseObject> sortBy({bool lastActivity = true, bool favoritesToTop = false}) {
     List<GetRoomResponseObject> sorted = data.toList();
-    sorted.sort((a, b) => -a.lastActivity.compareTo(b.lastActivity));
+    if(lastActivity) sorted.sort((a, b) => -a.lastActivity.compareTo(b.lastActivity));
+    if(favoritesToTop) sorted.sort((a, b) => b.isFavorite ? 1 : -1);
+
     return sorted;
   }
-
 }
 
 @JsonSerializable(explicitToJson: true)
diff --git a/lib/model/timetable/timetableProps.dart b/lib/model/timetable/timetableProps.dart
index 1e38930..71f15d9 100644
--- a/lib/model/timetable/timetableProps.dart
+++ b/lib/model/timetable/timetableProps.dart
@@ -29,7 +29,7 @@ class TimetableProps extends DataHolder {
   late DateTime endDate = getDate(_queryWeek.add(Duration(days: DateTime.daysPerWeek - _queryWeek.weekday)));
 
   GetTimetableResponse? _getTimetableResponse;
-  GetTimetableResponse get getTimetableResponse => _getTimetableResponse!; //TODO failed null check when no cache
+  GetTimetableResponse get getTimetableResponse => _getTimetableResponse!;
 
   GetRoomsResponse? _getRoomsResponse;
   GetRoomsResponse get getRoomsResponse => _getRoomsResponse!;
diff --git a/lib/storage/base/settings.dart b/lib/storage/base/settings.dart
index a6d4401..4b12578 100644
--- a/lib/storage/base/settings.dart
+++ b/lib/storage/base/settings.dart
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
 import 'package:json_annotation/json_annotation.dart';
 
 import '../gradeAverages/gradeAveragesSettings.dart';
+import '../talk/talkSettings.dart';
 import '../timetable/timetableSettings.dart';
 
 part 'settings.g.dart';
@@ -17,12 +18,14 @@ class Settings {
 
   GradeAveragesSettings gradeAveragesSettings;
   TimetableSettings timetableSettings;
+  TalkSettings talkSettings;
 
   Settings({
     required this.appTheme,
     required this.devToolsEnabled,
     required this.gradeAveragesSettings,
-    required this.timetableSettings
+    required this.timetableSettings,
+    required this.talkSettings,
   });
 
   static String _themeToJson(ThemeMode m) => m.name;
diff --git a/lib/storage/base/settings.g.dart b/lib/storage/base/settings.g.dart
index f3be406..6794122 100644
--- a/lib/storage/base/settings.g.dart
+++ b/lib/storage/base/settings.g.dart
@@ -13,6 +13,8 @@ Settings _$SettingsFromJson(Map<String, dynamic> json) => Settings(
           json['gradeAveragesSettings'] as Map<String, dynamic>),
       timetableSettings: TimetableSettings.fromJson(
           json['timetableSettings'] as Map<String, dynamic>),
+      talkSettings:
+          TalkSettings.fromJson(json['talkSettings'] as Map<String, dynamic>),
     );
 
 Map<String, dynamic> _$SettingsToJson(Settings instance) => <String, dynamic>{
@@ -20,4 +22,5 @@ Map<String, dynamic> _$SettingsToJson(Settings instance) => <String, dynamic>{
       'devToolsEnabled': instance.devToolsEnabled,
       'gradeAveragesSettings': instance.gradeAveragesSettings.toJson(),
       'timetableSettings': instance.timetableSettings.toJson(),
+      'talkSettings': instance.talkSettings.toJson(),
     };
diff --git a/lib/storage/base/settingsProvider.dart b/lib/storage/base/settingsProvider.dart
index 253fa2d..0489d83 100644
--- a/lib/storage/base/settingsProvider.dart
+++ b/lib/storage/base/settingsProvider.dart
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
 import 'package:shared_preferences/shared_preferences.dart';
 
 import '../gradeAverages/gradeAveragesSettings.dart';
+import '../talk/talkSettings.dart';
 import '../timetable/timetableSettings.dart';
 import 'settings.dart';
 
@@ -55,6 +56,9 @@ class SettingsProvider extends ChangeNotifier {
       timetableSettings: TimetableSettings(
         zoom: 40,
       ),
+      talkSettings: TalkSettings(
+        sortFavoritesToTop: true,
+      ),
     );
   }
 }
\ No newline at end of file
diff --git a/lib/storage/talk/talkSettings.dart b/lib/storage/talk/talkSettings.dart
new file mode 100644
index 0000000..b7aece1
--- /dev/null
+++ b/lib/storage/talk/talkSettings.dart
@@ -0,0 +1,13 @@
+import 'package:json_annotation/json_annotation.dart';
+
+part 'talkSettings.g.dart';
+
+@JsonSerializable()
+class TalkSettings {
+  bool sortFavoritesToTop;
+
+  TalkSettings({required this.sortFavoritesToTop});
+
+  factory TalkSettings.fromJson(Map<String, dynamic> json) => _$TalkSettingsFromJson(json);
+  Map<String, dynamic> toJson() => _$TalkSettingsToJson(this);
+}
\ No newline at end of file
diff --git a/lib/storage/talk/talkSettings.g.dart b/lib/storage/talk/talkSettings.g.dart
new file mode 100644
index 0000000..81cde06
--- /dev/null
+++ b/lib/storage/talk/talkSettings.g.dart
@@ -0,0 +1,16 @@
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+part of 'talkSettings.dart';
+
+// **************************************************************************
+// JsonSerializableGenerator
+// **************************************************************************
+
+TalkSettings _$TalkSettingsFromJson(Map<String, dynamic> json) => TalkSettings(
+      sortFavoritesToTop: json['sortFavoritesToTop'] as bool,
+    );
+
+Map<String, dynamic> _$TalkSettingsToJson(TalkSettings instance) =>
+    <String, dynamic>{
+      'sortFavoritesToTop': instance.sortFavoritesToTop,
+    };
diff --git a/lib/view/pages/talk/chatList.dart b/lib/view/pages/talk/chatList.dart
index 87c6160..41f5252 100644
--- a/lib/view/pages/talk/chatList.dart
+++ b/lib/view/pages/talk/chatList.dart
@@ -4,6 +4,7 @@ import 'package:flutter/material.dart';
 import 'package:provider/provider.dart';
 
 import '../../../model/chatList/chatListProps.dart';
+import '../../../storage/base/settingsProvider.dart';
 import 'chatTile.dart';
 import 'joinChat.dart';
 import 'searchChat.dart';
@@ -65,7 +66,10 @@ class _ChatListState extends State<ChatList> {
           latestData = data;
 
           List<ChatTile> chats = [];
-          for (var chatRoom in data.getRoomsResponse.sortByLastActivity()) {
+          for (var chatRoom in data.getRoomsResponse.sortBy(
+              lastActivity: true,
+              favoritesToTop: Provider.of<SettingsProvider>(context).val().talkSettings.sortFavoritesToTop)
+          ) {
             chats.add(ChatTile(data: chatRoom, query: _query));
           }
 
diff --git a/lib/view/settings/settings.dart b/lib/view/settings/settings.dart
index 389b0f4..bf80633 100644
--- a/lib/view/settings/settings.dart
+++ b/lib/view/settings/settings.dart
@@ -91,6 +91,21 @@ class _SettingsState extends State<Settings> {
 
             const Divider(),
 
+            ListTile(
+              leading: const Icon(Icons.star_border),
+              title: const Text("Favoriten im Talk nach oben sortieren"),
+              trailing: Checkbox(
+                value: settings.val().talkSettings.sortFavoritesToTop,
+                onChanged: (e) {
+                  setState(() {
+                    settings.val(write: true).talkSettings.sortFavoritesToTop = e!;
+                  });
+                },
+              ),
+            ),
+
+            const Divider(),
+
             ListTile(
               leading: const Icon(Icons.live_help_outlined),
               title: const Text("Informationen und Lizenzen"),