diff --git a/.idea/libraries/Dart_Packages.xml b/.idea/libraries/Dart_Packages.xml index 01bb18b..0548163 100644 --- a/.idea/libraries/Dart_Packages.xml +++ b/.idea/libraries/Dart_Packages.xml @@ -5,7 +5,7 @@ - @@ -19,7 +19,7 @@ - @@ -54,7 +54,7 @@ - @@ -110,7 +110,7 @@ - @@ -131,21 +131,21 @@ - - - @@ -159,7 +159,7 @@ - @@ -215,7 +215,7 @@ - @@ -264,7 +264,7 @@ - @@ -278,7 +278,7 @@ - @@ -313,14 +313,7 @@ - - - - - - - @@ -331,10 +324,17 @@ + + + + + + - @@ -348,7 +348,7 @@ - @@ -362,7 +362,7 @@ - @@ -425,21 +425,21 @@ - - - @@ -450,6 +450,13 @@ + + + + + + @@ -495,14 +502,14 @@ - - @@ -530,14 +537,14 @@ - - @@ -572,7 +579,7 @@ - @@ -593,14 +600,14 @@ - - @@ -635,28 +642,28 @@ - - - - @@ -677,7 +684,7 @@ - @@ -695,13 +702,6 @@ - - - - - - @@ -733,28 +733,7 @@ - - - - - - - - - - - - - - - - - - - @@ -768,14 +747,14 @@ - - @@ -789,7 +768,7 @@ - @@ -831,7 +810,7 @@ - @@ -866,42 +845,42 @@ - - - - - - @@ -919,13 +898,6 @@ - - - - - - @@ -936,14 +908,14 @@ - - @@ -968,6 +940,13 @@ + + + + + + @@ -1003,52 +982,66 @@ + + + + + + + + + + + + - - - - - - - @@ -1083,14 +1076,14 @@ - - @@ -1104,14 +1097,14 @@ - - @@ -1146,70 +1139,70 @@ - - - - - - - - - - @@ -1265,14 +1258,14 @@ - - @@ -1293,28 +1286,28 @@ - - - - @@ -1363,21 +1356,21 @@ - - - @@ -1406,16 +1399,16 @@ - - - + + + - + - + @@ -1423,14 +1416,14 @@ - + - - - + + + - + @@ -1438,27 +1431,27 @@ - + - + - + - - + + - + - + @@ -1467,54 +1460,51 @@ - - - + + + + - - + + - - + + - + - - + + - - - - + + + + - + - - - - - + - - + + - + @@ -1524,55 +1514,57 @@ - - - - - - + + + + + + - - - + + + - - - - - - - + + + + + + + + + - - + + - - + + - - - - - - - - - - + + + + + + + + + + @@ -1580,23 +1572,23 @@ - - + + - - - - + + + + - - - + + + diff --git a/.idea/libraries/Flutter_Plugins.xml b/.idea/libraries/Flutter_Plugins.xml index 0091b0c..7582baa 100644 --- a/.idea/libraries/Flutter_Plugins.xml +++ b/.idea/libraries/Flutter_Plugins.xml @@ -1,51 +1,51 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - - - - - - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android/.idea/gradle.xml b/android/.idea/gradle.xml index fac6e3b..41b2598 100644 --- a/android/.idea/gradle.xml +++ b/android/.idea/gradle.xml @@ -10,18 +10,24 @@ - + + + + + + + + + + + + + + - + - - - + @@ -121,11 +121,11 @@ - - 1690744630092 + + 1693761601368 diff --git a/android/build.gradle b/android/build.gradle index db9efaf..391b068 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.6.10' + ext.kotlin_version = '1.8.0' repositories { google() mavenCentral() diff --git a/lib/api/marianumcloud/webdav/queries/listFiles/listFiles.dart b/lib/api/marianumcloud/webdav/queries/listFiles/listFiles.dart index ca60edf..b5b281a 100644 --- a/lib/api/marianumcloud/webdav/queries/listFiles/listFiles.dart +++ b/lib/api/marianumcloud/webdav/queries/listFiles/listFiles.dart @@ -14,7 +14,7 @@ class ListFiles extends WebdavApi { @override Future run() async { - List davFiles = (await (await WebdavApi.webdav).propfind(params.path)).toWebDavFiles(); + List davFiles = (await (await WebdavApi.webdav).propfind(Uri.parse(params.path))).toWebDavFiles(); Set files = davFiles.map((e) => CacheableFile.fromDavFile(e)).toSet(); // webdav handles subdirectories wrong, this is a fix diff --git a/lib/api/marianumcloud/webdav/webdavApi.dart b/lib/api/marianumcloud/webdav/webdavApi.dart index 1e59daa..9c9570d 100644 --- a/lib/api/marianumcloud/webdav/webdavApi.dart +++ b/lib/api/marianumcloud/webdav/webdavApi.dart @@ -18,7 +18,7 @@ abstract class WebdavApi extends ApiRequest { static Future webdavConnectString = buildWebdavConnectString(); static Future establishWebdavConnection() async { - return NextcloudClient("https://${EndpointData().nextcloud().full()}", password: AccountData().getPassword(), loginName: AccountData().getUsername()).webdav; + return NextcloudClient(Uri.parse("https://${EndpointData().nextcloud().full()}"), password: AccountData().getPassword(), loginName: AccountData().getUsername()).webdav; } static Future buildWebdavConnectString() async { diff --git a/lib/main.dart b/lib/main.dart index a4e3403..be781d8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -8,12 +8,12 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:jiffy/jiffy.dart'; -import 'package:marianum_mobile/firebase_options.dart'; import 'package:provider/provider.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'api/mhsl/breaker/getBreakers/getBreakersResponse.dart'; import 'app.dart'; +import 'firebase_options.dart'; import 'model/accountData.dart'; import 'model/accountModel.dart'; import 'model/breakers/Breaker.dart'; @@ -43,9 +43,9 @@ Future main() async { ByteData data = await PlatformAssetBundle().load('assets/ca/lets-encrypt-r3.pem'); SecurityContext.defaultContext.setTrustedCertificatesBytes(data.buffer.asUint8List()); - ErrorWidget.builder = (error) { - return PlaceholderView(icon: Icons.phonelink_erase_rounded, text: error.toString()); - }; + // ErrorWidget.builder = (error) { + // return PlaceholderView(icon: Icons.phonelink_erase_rounded, text: error.toString()); + // }; runApp( MultiProvider( diff --git a/lib/model/dataHolder.dart b/lib/model/dataHolder.dart index d8703b5..5169eb8 100644 --- a/lib/model/dataHolder.dart +++ b/lib/model/dataHolder.dart @@ -14,6 +14,7 @@ abstract class DataHolder extends ChangeNotifier { List properties(); bool primaryLoading() { + // log("${toString()} ${properties().map((e) => e != null ? "1" : "0").join(", ")}"); for(ApiResponse? element in properties()) { if(element == null) return true; } diff --git a/lib/model/timetable/timetableProps.dart b/lib/model/timetable/timetableProps.dart index c3ca35d..40545eb 100644 --- a/lib/model/timetable/timetableProps.dart +++ b/lib/model/timetable/timetableProps.dart @@ -1,7 +1,8 @@ +import 'dart:convert'; + import 'package:intl/intl.dart'; import '../../api/apiResponse.dart'; -import '../../api/webuntis/queries/getHolidays/getHolidaysCache.dart'; import '../../api/webuntis/queries/getHolidays/getHolidaysResponse.dart'; import '../../api/webuntis/queries/getRooms/getRoomsCache.dart'; import '../../api/webuntis/queries/getRooms/getRoomsResponse.dart'; @@ -78,12 +79,16 @@ class TimetableProps extends DataHolder { } ); - GetHolidaysCache( - onUpdate: (GetHolidaysResponse data) => { - _getHolidaysResponse = data, - notifyListeners(), - } - ); + // GetHolidaysCache( // TODO is this fixed by webuntis? miese kriese + // onUpdate: (GetHolidaysResponse data) => { + // _getHolidaysResponse = data, + // notifyListeners(), + // } + // ); + _getHolidaysResponse = GetHolidaysResponse.fromJson(jsonDecode(""" + {"jsonrpc":"2.0","id":"ID","result":[]} + """)); + notifyListeners(); } DateTime getDate(DateTime d) => DateTime(d.year, d.month, d.day); diff --git a/lib/theming/lightAppTheme.dart b/lib/theming/lightAppTheme.dart index de996fa..5d08920 100644 --- a/lib/theming/lightAppTheme.dart +++ b/lib/theming/lightAppTheme.dart @@ -35,8 +35,7 @@ class LightAppTheme { color: marianumRed, ), checkboxTheme: CheckboxThemeData( - fillColor: MaterialStateProperty.all(marianumRed), - // visualDensity: const VisualDensity(horizontal: VisualDensity.maximumDensity), + fillColor: MaterialStateProperty.resolveWith((states) => states.contains(MaterialState.selected) ? marianumRed : Colors.white), ), ); } \ No newline at end of file diff --git a/lib/view/pages/files/fileElement.dart b/lib/view/pages/files/fileElement.dart index 974cf40..4b603e5 100644 --- a/lib/view/pages/files/fileElement.dart +++ b/lib/view/pages/files/fileElement.dart @@ -161,7 +161,7 @@ class _FileElementState extends State { content: "Das Element wird unwiederruflich gelöscht.", onConfirm: () { WebdavApi.webdav - .then((value) => value.delete(widget.file.path)) + .then((value) => value.delete(Uri.parse(widget.file.path))) .then((value) => widget.refetch()); } )); diff --git a/lib/view/pages/files/fileUploadDialog.dart b/lib/view/pages/files/fileUploadDialog.dart index d48a3e7..95f6ffa 100644 --- a/lib/view/pages/files/fileUploadDialog.dart +++ b/lib/view/pages/files/fileUploadDialog.dart @@ -43,7 +43,7 @@ class _FileUploadDialogState extends State { setState(() { state = FileUploadState.checkConflict; }); - List result = (await webdavClient.propfind(widget.remotePath.join("/"))).responses; + List result = (await webdavClient.propfind(Uri.parse(widget.remotePath.join("/")))).responses; if(result.any((element) => element.href!.endsWith("/$targetFileName"))) { setState(() { state = FileUploadState.conflict; @@ -56,7 +56,7 @@ class _FileUploadDialogState extends State { } } - Future uploadTask = webdavClient.putFile(File(widget.localPath), FileStat.statSync(widget.localPath), fullRemotePath); // TODO use onProgress from putFile + Future uploadTask = webdavClient.putFile(File(widget.localPath), FileStat.statSync(widget.localPath), Uri.parse(fullRemotePath)); // TODO use onProgress from putFile uploadTask.then((value) => Future.value(value)).catchError((e) { setState(() { state = FileUploadState.error; diff --git a/lib/view/pages/files/files.dart b/lib/view/pages/files/files.dart index 71f77c4..628b64e 100644 --- a/lib/view/pages/files/files.dart +++ b/lib/view/pages/files/files.dart @@ -189,7 +189,7 @@ class _FilesState extends State { }, child: const Text("Abbrechen")), TextButton(onPressed: () { WebdavApi.webdav.then((webdav) { - webdav.mkcol("${widget.path.join("/")}/${inputController.text}").then((value) => _query()); + webdav.mkcol(Uri.parse("${widget.path.join("/")}/${inputController.text}")).then((value) => _query()); }); Navigator.of(context).pop(); }, child: const Text("Ordner erstellen")), diff --git a/lib/view/pages/more/holidays/holidays.dart b/lib/view/pages/more/holidays/holidays.dart index 160b86d..da45f71 100644 --- a/lib/view/pages/more/holidays/holidays.dart +++ b/lib/view/pages/more/holidays/holidays.dart @@ -147,7 +147,7 @@ class _HolidaysState extends State { subtitle: Text(Jiffy.parse(holiday.start).fromNow()), ), ), - DebugTile(holiday.toJson()).asTile(context), + DebugTile(context).jsonData(holiday.toJson()), ], )), trailing: const Icon(Icons.arrow_right), diff --git a/lib/view/pages/more/overhang.dart b/lib/view/pages/more/overhang.dart index 7b501a6..08eb965 100644 --- a/lib/view/pages/more/overhang.dart +++ b/lib/view/pages/more/overhang.dart @@ -1,8 +1,18 @@ +import 'dart:convert'; +import 'dart:developer'; +import 'package:http/http.dart' as http; + +import 'package:crypto/crypto.dart'; +import 'package:fast_rsa/fast_rsa.dart'; +import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; import 'package:persistent_bottom_nav_bar/persistent_tab_view.dart'; +import 'package:share_plus/share_plus.dart'; +import '../../../model/endpointData.dart'; import '../../../widget/ListItem.dart'; +import '../../../widget/debug/debugTile.dart'; import '../../settings/settings.dart'; import 'gradeAverages/gradeAverage.dart'; import 'holidays/holidays.dart'; @@ -14,6 +24,7 @@ class Overhang extends StatelessWidget { @override Widget build(BuildContext context) { + return Scaffold( appBar: AppBar( title: const Text("Mehr"), @@ -22,11 +33,59 @@ class Overhang extends StatelessWidget { ], ), body: ListView( - children: const [ - ListItemNavigator(icon: Icons.newspaper, text: "Marianum Message", target: Message()), - ListItemNavigator(icon: Icons.room, text: "Raumplan", target: Roomplan()), - ListItemNavigator(icon: Icons.calculate, text: "Notendurschnittsrechner", target: GradeAverage()), - ListItemNavigator(icon: Icons.calendar_month, text: "Schulferien", target: Holidays()), + children: [ + const ListItemNavigator(icon: Icons.newspaper, text: "Marianum Message", target: Message()), + const ListItemNavigator(icon: Icons.room, text: "Raumplan", target: Roomplan()), + const ListItemNavigator(icon: Icons.calculate, text: "Notendurschnittsrechner", target: GradeAverage()), + const ListItemNavigator(icon: Icons.calendar_month, text: "Schulferien", target: Holidays()), + ListTile( + leading: const Icon(Icons.share_outlined), + title: const Text("Teile die App mit deiner Klasse"), + onTap: () { + Share.share( // TODO ipad needs position argument + subject: "App Teilen", + "Hol dir die inoffizielle App für's Marianum:" + "\n\nAndroid: https://play.google.com/store/apps/details?id=eu.mhsl.marianum.mobile.client " + "\nApple: https://apps.apple.com/us/app/marianum-fulda/id6458789560 " + "\n\nViel Spaß!" + ); + }, + ), + DebugTile(context, onlyInDebug: true).callback(onTab: () async { + log("Starting"); + log("Generate keys"); + final rsaKey = await RSA.generate(2048); + final devicePrivateKey = rsaKey.privateKey.toString(); + final devicePublicKey = rsaKey.publicKey.toString(); + log("Private: \n$devicePrivateKey"); + log("Public: \n$devicePublicKey"); + final pushToken = await FirebaseMessaging.instance.getToken(); + log("PushToken: $pushToken}"); + final pushTokenHash = sha512.convert(utf8.encode(pushToken!)); + log("PushTokenHash: $pushTokenHash"); + + final requestMap = { + "format": "json", + "pushTokenHash": pushTokenHash.toString(), + "devicePublicKey": devicePublicKey.toString(), + "proxyServer": "https://push-notifications.nextcloud.com/devices" + }; + + log(jsonEncode(requestMap)); + http.post( + //${AccountData().buildHttpAuthString()}@ + Uri.parse("https://${EndpointData().nextcloud().full()}/ocs/v2.php/apps/notifications/api/v2/push"), + headers: { + "OCS-APIRequest": "true", + "Content-Type": "application/json", + "Accept": "application/json", + "Authorization": "Bearer Fv3g7g9jW91FXNjZLaJmyprClfy8pX1jEM3hJGbXjPEFcx4oGIEVcpwEnuT4mPs39D9xT063" + }, + body: jsonEncode(requestMap), + ).then((response) { + log("Response: ${response.statusCode}\n${response.body}"); + }); + }), ], ), ); diff --git a/lib/view/pages/talk/chatBubble.dart b/lib/view/pages/talk/chatBubble.dart index 5275852..24ce608 100644 --- a/lib/view/pages/talk/chatBubble.dart +++ b/lib/view/pages/talk/chatBubble.dart @@ -255,7 +255,7 @@ class _ChatBubbleState extends State { }, ), ), - DebugTile(widget.bubbleData.toJson()).asTile(context), + DebugTile(context).jsonData(widget.bubbleData.toJson()), ], ); }); diff --git a/lib/view/pages/talk/chatTextfield.dart b/lib/view/pages/talk/chatTextfield.dart index 4fb7741..9c1687c 100644 --- a/lib/view/pages/talk/chatTextfield.dart +++ b/lib/view/pages/talk/chatTextfield.dart @@ -41,7 +41,7 @@ class _ChatTextfieldState extends State { String filename = "${path.split("/").last.split(".").first}-${const Uuid().v4()}.${path.split(".").last}"; String shareFolder = "MarianumMobile"; WebdavApi.webdav.then((webdav) { - webdav.mkcol("/$shareFolder"); + webdav.mkcol(Uri.parse("/$shareFolder")); }); showDialog(context: context, builder: (context) => FileUploadDialog( diff --git a/lib/view/pages/talk/chatTile.dart b/lib/view/pages/talk/chatTile.dart index f4e7327..3037d3d 100644 --- a/lib/view/pages/talk/chatTile.dart +++ b/lib/view/pages/talk/chatTile.dart @@ -172,7 +172,7 @@ class _ChatTileState extends State { ).asDialog(context); }, ), - DebugTile(widget.data.toJson()).asTile(context), + DebugTile(context).jsonData(widget.data.toJson()), ], )); }, diff --git a/lib/view/pages/timetable/appointmentDetails.dart b/lib/view/pages/timetable/appointmentDetails.dart index db63516..2276d87 100644 --- a/lib/view/pages/timetable/appointmentDetails.dart +++ b/lib/view/pages/timetable/appointmentDetails.dart @@ -92,7 +92,7 @@ class AppointmentDetails { leading: const Icon(Icons.people), title: Text("Klasse(n): ${timetableData.kl.map((e) => e.name).join(", ")}"), ), - DebugTile(timetableData.toJson()).asTile(context), + DebugTile(context).jsonData(timetableData.toJson()), ], ), ) diff --git a/lib/view/settings/settings.dart b/lib/view/settings/settings.dart index f106da4..f902198 100644 --- a/lib/view/settings/settings.dart +++ b/lib/view/settings/settings.dart @@ -1,4 +1,6 @@ +import 'dart:io'; + import 'package:filesize/filesize.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -145,45 +147,48 @@ class _SettingsState extends State { const Divider(), - ListTile( - leading: const CenteredLeading(Icon(Icons.notifications_active_outlined)), - title: const Text("Push-Benachrichtigungen aktivieren"), - subtitle: const Text("Lange tippen für mehr Informationen"), - trailing: Checkbox( - value: settings.val().notificationSettings.enabled, - onChanged: (e) { - if(e!) { - ConfirmDialog( - title: "Warnung", - icon: Icons.warning_amber, - content: "" - "Die Push-Benachrichtigungen werden durch mhsl.eu versendet.\n\n" - "Durch das aktivieren dieser Funktion wird dein Nutzername, dein Password und eine Geräte-ID von mhsl dauerhaft gespeichert und verarbeitet.\n\n" - "Für mehr Informationen drücke lange auf die Einstellungsoption!", - confirmButton: "Aktivieren", - onConfirm: () { - settings.val(write: true).notificationSettings.enabled = e; - NotifyUpdater.registerToServer(); - }, - ).asDialog(context); - } else { - settings.val(write: true).notificationSettings.enabled = e; - } - }, - ), - onLongPress: () => showDialog(context: context, builder: (context) => AlertDialog( - title: const Text("Info über Push"), - content: const SingleChildScrollView(child: Text("" - "Aufgrund technischer Limitationen müssen Push-nachrichten über einen Externen Server - hier 'mhsl.eu' (Author dieser App) - erfolgen.\n\n" - "Wenn Push aktiviert wird, werden deine Zugangsdaten und ein Token verschlüsselt an den Betreiber gesendet und von ihm unverschlüsselt gespeichert.\n\n" - "Der extene Server verwendet die Zugangsdaten um sich maschinell in Nextcloud Talk anzumelden und via Websockets auf neue Nachrichten zu warten.\n\n" - "Wenn eine neue Nachricht eintrifft wird dein Telefon via FBC-Messaging (Google Firebase Push) vom Externen Server benachrichtigt.\n\n" - "Behalte im Hinterkopf, dass deine Zugangsdaten auf einem Externen Server gespeichert werden und dies trots bester Absichten ein Sicherheitsrisiko sein kann!" + Visibility( + visible: Platform.isAndroid, + child: ListTile( + leading: const CenteredLeading(Icon(Icons.notifications_active_outlined)), + title: const Text("Push-Benachrichtigungen aktivieren"), + subtitle: const Text("Lange tippen für mehr Informationen"), + trailing: Checkbox( + value: settings.val().notificationSettings.enabled, + onChanged: (e) { + if(e!) { + ConfirmDialog( + title: "Warnung", + icon: Icons.warning_amber, + content: "" + "Die Push-Benachrichtigungen werden durch mhsl.eu versendet.\n\n" + "Durch das aktivieren dieser Funktion wird dein Nutzername, dein Password und eine Geräte-ID von mhsl dauerhaft gespeichert und verarbeitet.\n\n" + "Für mehr Informationen drücke lange auf die Einstellungsoption!", + confirmButton: "Aktivieren", + onConfirm: () { + settings.val(write: true).notificationSettings.enabled = e; + NotifyUpdater.registerToServer(); + }, + ).asDialog(context); + } else { + settings.val(write: true).notificationSettings.enabled = e; + } + }, + ), + onLongPress: () => showDialog(context: context, builder: (context) => AlertDialog( + title: const Text("Info über Push"), + content: const SingleChildScrollView(child: Text("" + "Aufgrund technischer Limitationen müssen Push-nachrichten über einen Externen Server - hier 'mhsl.eu' (Author dieser App) - erfolgen.\n\n" + "Wenn Push aktiviert wird, werden deine Zugangsdaten und ein Token verschlüsselt an den Betreiber gesendet und von ihm unverschlüsselt gespeichert.\n\n" + "Der extene Server verwendet die Zugangsdaten um sich maschinell in Nextcloud Talk anzumelden und via Websockets auf neue Nachrichten zu warten.\n\n" + "Wenn eine neue Nachricht eintrifft wird dein Telefon via FBC-Messaging (Google Firebase Push) vom Externen Server benachrichtigt.\n\n" + "Behalte im Hinterkopf, dass deine Zugangsdaten auf einem Externen Server gespeichert werden und dies trots bester Absichten ein Sicherheitsrisiko sein kann!" + )), + actions: [ + TextButton(onPressed: () => Navigator.of(context).pop(), child: const Text("Zurück")) + ], )), - actions: [ - TextButton(onPressed: () => Navigator.of(context).pop(), child: const Text("Zurück")) - ], - )), + ), ), const Divider(), diff --git a/lib/widget/debug/debugTile.dart b/lib/widget/debug/debugTile.dart index 0327bc3..8853d8b 100644 --- a/lib/widget/debug/debugTile.dart +++ b/lib/widget/debug/debugTile.dart @@ -1,26 +1,38 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../../storage/base/settingsProvider.dart'; +import '../centeredLeading.dart'; import 'jsonViewer.dart'; class DebugTile { - Map data; + BuildContext context; + bool onlyInDebug; + DebugTile(this.context, {this.onlyInDebug = false}); - DebugTile(this.data); + Widget jsonData(Map data, {bool ignoreConfig = false}) { + return callback( + title: "JSON daten anzeigen", + onTab: () => JsonViewer.asDialog(context, data) + ); + } - Widget asTile(BuildContext context, {bool ignoreConfig = false}) { - return Visibility( - visible: Provider.of(context).val().devToolsEnabled || ignoreConfig, - child: ListTile( - leading: const Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [Icon(Icons.data_object)], - ), - title: const Text("JSON daten anzeigen"), + Widget callback({String title = "Debugaktion", required void Function() onTab}) { + return child( + ListTile( + leading: const CenteredLeading(Icon(Icons.developer_mode_outlined)), + title: Text(title), subtitle: const Text("Entwicklermodus aktiviert"), - onTap: () => JsonViewer.asDialog(context, data), - ), + onTap: onTab, + ) + ); + } + + Widget child(Widget child) { + return Visibility( + visible: Provider.of(context).val().devToolsEnabled && (onlyInDebug ? kDebugMode : true), + child: child, ); } } \ No newline at end of file diff --git a/lib/widget/fileViewer.dart b/lib/widget/fileViewer.dart index 2cb45a2..edccd43 100644 --- a/lib/widget/fileViewer.dart +++ b/lib/widget/fileViewer.dart @@ -3,11 +3,11 @@ import 'dart:math'; import 'package:better_open_file/better_open_file.dart'; import 'package:flutter/material.dart'; -import 'package:marianum_mobile/storage/base/settingsProvider.dart'; import 'package:photo_view/photo_view.dart'; import 'package:provider/provider.dart'; import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart'; +import '../storage/base/settingsProvider.dart'; import 'placeholderView.dart'; class FileViewer extends StatefulWidget { diff --git a/lib/widget/loadingSpinner.dart b/lib/widget/loadingSpinner.dart index 6ab2502..8fb9cfd 100644 --- a/lib/widget/loadingSpinner.dart +++ b/lib/widget/loadingSpinner.dart @@ -16,7 +16,7 @@ class _LoadingSpinnerState extends State { @override void initState() { - timer = Timer(const Duration(seconds: 15), () { + timer = Timer(const Duration(seconds: 30), () { setState(() { textVisible = true; }); @@ -33,13 +33,16 @@ class _LoadingSpinnerState extends State { children: [ Visibility( visible: !textVisible, - replacement: const Icon(Icons.signal_wifi_connected_no_internet_4_outlined), + replacement: const Icon(Icons.sentiment_dissatisfied_outlined), child: const CircularProgressIndicator(), ), const SizedBox(height: 30), Visibility( visible: textVisible, - child: const Text("Etwas scheint nicht zu funktionieren!\nBist du mit dem Internet verbunden?\n\nVersuche die App neuzustarten"), + child: const Text( + textAlign: TextAlign.center, + "Irgendetwas funktioniert nicht!\nBist du mit dem Internet verbunden?\n\nVersuche die App neuzustarten" + ), ), ], ), diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 7299b5c..9874fcc 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -6,10 +6,14 @@ #include "generated_plugin_registrant.h" +#include #include #include void fl_register_plugins(FlPluginRegistry* registry) { + g_autoptr(FlPluginRegistrar) fast_rsa_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "FastRsaPlugin"); + fast_rsa_plugin_register_with_registrar(fast_rsa_registrar); g_autoptr(FlPluginRegistrar) file_selector_linux_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin"); file_selector_plugin_register_with_registrar(file_selector_linux_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index 786ff5c..887494c 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + fast_rsa file_selector_linux url_launcher_linux ) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index f9e6582..7e74013 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -6,12 +6,14 @@ import FlutterMacOS import Foundation import device_info_plus +import fast_rsa import file_selector_macos import firebase_core import firebase_messaging import flutter_local_notifications import package_info import path_provider_foundation +import share_plus import shared_preferences_foundation import sqflite import syncfusion_pdfviewer_macos @@ -19,12 +21,14 @@ import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin")) + FastRsaPlugin.register(with: registry.registrar(forPlugin: "FastRsaPlugin")) FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin")) FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) FLTPackageInfoPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) + SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) SyncfusionFlutterPdfViewerPlugin.register(with: registry.registrar(forPlugin: "SyncfusionFlutterPdfViewerPlugin")) diff --git a/pubspec.yaml b/pubspec.yaml index 9984312..095e772 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -56,7 +56,7 @@ dependencies: git: url: https://github.com/provokateurin/nextcloud-neon path: packages/nextcloud - ref: 9a42bdb3a0ef1e3dbd62f746fb0fe75856be66a3 + ref: ba151505ab7f9d4c356345625482e2b61ce460cb flutter_launcher_icons: ^0.13.1 pretty_json: ^2.0.0 cached_network_image: ^3.2.3 @@ -86,6 +86,8 @@ dependencies: firebase_in_app_messaging: ^0.7.3+4 flutter_local_notifications: ^15.1.0+1 fluttertoast: ^8.2.2 + fast_rsa: ^3.6.1 + share_plus: ^7.1.0 dev_dependencies: flutter_test: diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 9f7d909..da31771 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,16 +6,22 @@ #include "generated_plugin_registrant.h" +#include #include #include +#include #include #include void RegisterPlugins(flutter::PluginRegistry* registry) { + FastRsaPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FastRsaPlugin")); FileSelectorWindowsRegisterWithRegistrar( registry->GetRegistrarForPlugin("FileSelectorWindows")); FirebaseCorePluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); + SharePlusWindowsPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi")); SyncfusionPdfviewerWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("SyncfusionPdfviewerWindowsPlugin")); UrlLauncherWindowsRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index d9d5615..a2ae4b5 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,8 +3,10 @@ # list(APPEND FLUTTER_PLUGIN_LIST + fast_rsa file_selector_windows firebase_core + share_plus syncfusion_pdfviewer_windows url_launcher_windows )