From 074a6fdf9efefb8d3ca34c67a50ab80d5e5fc988 Mon Sep 17 00:00:00 2001 From: vyPal <66716025+vyPal@users.noreply.github.com> Date: Tue, 11 Jun 2024 09:43:12 +0200 Subject: [PATCH 1/7] Add ability to login with qrcode --- android/app/src/main/AndroidManifest.xml | 7 + lib/l10n/app_cs.arb | 4 +- lib/l10n/app_en.arb | 4 +- lib/main.dart | 32 ++++ lib/qrlogin.dart | 176 ++++++++++++++++++ linux/flutter/generated_plugin_registrant.cc | 4 + linux/flutter/generated_plugins.cmake | 1 + macos/Flutter/GeneratedPluginRegistrant.swift | 2 + pubspec.lock | 16 ++ pubspec.yaml | 1 + .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 1 + 12 files changed, 249 insertions(+), 2 deletions(-) create mode 100644 lib/qrlogin.dart diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 326245c..20c1cd6 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -31,6 +31,13 @@ + + + + + + + diff --git a/lib/l10n/app_cs.arb b/lib/l10n/app_cs.arb index a97b098..3a60312 100644 --- a/lib/l10n/app_cs.arb +++ b/lib/l10n/app_cs.arb @@ -139,5 +139,7 @@ "createMessageNewPollOptionPlaceholder": "Nová možnost", "createMessageErrorSelectRecipient": "Vyberte prosím příjemce", "createMessageErrorNoMessage": "Napište prosím zprávu", - "createMessageSend": "Odeslat" + "createMessageSend": "Odeslat", + "qrLoginPleaseLogin": "EduPage2 QR Přihlášení", + "qrLoginUseExistingCredentials": "Chystáte se přihlásit pomocí QR kódu" } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 46ad383..3e91a08 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -71,5 +71,7 @@ "createMessageNewPollOptionPlaceholder": "New option", "createMessageErrorSelectRecipient": "Please select a recipient", "createMessageErrorNoMessage": "Please write a message", - "createMessageSend": "Send" + "createMessageSend": "Send", + "qrLoginPleaseLogin": "EduPage2 QR Login", + "qrLoginUseExistingCredentials": "You are about to login to EduPage2 using a QR code" } diff --git a/lib/main.dart b/lib/main.dart index e4185fc..f44eeea 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,9 +1,13 @@ +import 'dart:async'; + +import 'package:app_links/app_links.dart'; import 'package:dynamic_color/dynamic_color.dart'; import 'package:eduapge2/api.dart'; import 'package:eduapge2/homework.dart'; import 'package:eduapge2/icanteen.dart'; import 'package:eduapge2/load.dart'; import 'package:eduapge2/messages.dart'; +import 'package:eduapge2/qrlogin.dart'; import 'package:eduapge2/timetable.dart'; import 'package:firebase_analytics/firebase_analytics.dart'; import 'package:firebase_remote_config/firebase_remote_config.dart'; @@ -53,6 +57,8 @@ abstract class BaseState extends State { } } +final GlobalKey navigatorKey = GlobalKey(); + class MyApp extends StatelessWidget { const MyApp({super.key}); @@ -78,6 +84,7 @@ class MyApp extends StatelessWidget { return DynamicColorBuilder(builder: (lightColorScheme, darkColorScheme) { return MaterialApp( title: 'EduPage2', + navigatorKey: navigatorKey, localizationsDelegates: AppLocalizations.localizationsDelegates, supportedLocales: AppLocalizations.supportedLocales, navigatorObservers: [SentryNavigatorObserver(), observer], @@ -107,6 +114,9 @@ class PageBaseState extends BaseState { int _selectedIndex = 0; String baseUrl = FirebaseRemoteConfig.instance.getString("testUrl"); + late AppLinks _appLinks; + StreamSubscription? _linkSubscription; + bool loaded = false; bool error = false; //for error status @@ -125,6 +135,28 @@ class PageBaseState extends BaseState { setOptimalDisplayMode(); if (!_isCheckingForUpdate) _checkForUpdate(); // ik that it's not necessary super.initState(); + initDeepLinks(); + } + + @override + void dispose() { + _linkSubscription?.cancel(); + super.dispose(); + } + + Future initDeepLinks() async { + _appLinks = AppLinks(); + + _linkSubscription = _appLinks.uriLinkStream.listen((uri) { + if (uri.path.startsWith('/l/')) { + final code = uri.pathSegments[1]; + navigatorKey.currentState?.push(MaterialPageRoute( + builder: (context) => QRLoginPage( + code: code, + ), + )); + } + }); } Future setOptimalDisplayMode() async { diff --git a/lib/qrlogin.dart b/lib/qrlogin.dart new file mode 100644 index 0000000..00bb01b --- /dev/null +++ b/lib/qrlogin.dart @@ -0,0 +1,176 @@ +import 'package:dio/dio.dart'; +import 'package:eduapge2/main.dart'; +import 'package:flutter/material.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +class QRLoginPage extends StatefulWidget { + final String code; + const QRLoginPage({super.key, required this.code}); + + @override + BaseState createState() => QRLoinPageState(); +} + +class QRLoinPageState extends BaseState { + AppLocalizations? local; + late SharedPreferences sharedPreferences; + String email = ""; + String password = ""; + String server = ""; + bool _useCustomEndpoint = false; + String _customEndpoint = ''; + bool showPassword = false; + + @override + void initState() { + getPrefs(); + super.initState(); + } + + @override + void setState(VoidCallback fn) { + if (!mounted) return; + super.setState(fn); + } + + Future getPrefs() async { + sharedPreferences = await SharedPreferences.getInstance(); + String? sEmail = sharedPreferences.getString("email"); + String? sPassword = sharedPreferences.getString("password"); + String? sServer = sharedPreferences.getString("server"); + String? sEndpoint = sharedPreferences.getString("customEndpoint"); + + if (sEmail != null) { + email = sEmail; + } + if (sPassword != null) { + password = sPassword; + } + if (sServer != null) { + server = sServer; + } + if (sEndpoint != null && sEndpoint != "") { + _customEndpoint = sEndpoint; + _useCustomEndpoint = true; + } + setState(() {}); + } + + @override + Widget build(BuildContext context) { + local ??= AppLocalizations.of(context); + return Center( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Card( + child: Padding( + padding: const EdgeInsets.all(15), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + local!.qrLoginPleaseLogin, + style: const TextStyle( + fontSize: 18, + ), + ), + Text(local!.qrLoginUseExistingCredentials), + TextField( + decoration: InputDecoration( + icon: const Icon(Icons.email), + hintText: local!.loginUsername, + ), + onChanged: (text) => {email = text}, + keyboardType: TextInputType.emailAddress, + ), + TextField( + decoration: InputDecoration( + icon: const Icon(Icons.key), + hintText: local!.loginPassword, + suffixIcon: IconButton( + icon: Icon(showPassword + ? Icons.visibility + : Icons.visibility_off), + onPressed: () { + setState(() { + showPassword = !showPassword; + }); + }, + ), + ), + onChanged: (text) => {password = text}, + obscureText: true, + keyboardType: TextInputType.visiblePassword, + ), + Row( + children: [ + Checkbox( + value: _useCustomEndpoint, + onChanged: (value) { + setState(() { + _useCustomEndpoint = value!; + }); + }, + ), + Text(local!.loginCustomEndpointCheckbox), + ], + ), + if (_useCustomEndpoint) + TextField( + decoration: InputDecoration( + icon: const Icon(Icons.language), + hintText: local!.loginCustomEndpoint, + ), + onChanged: (value) => {_customEndpoint = value}), + TextField( + decoration: InputDecoration( + icon: const Icon(Icons.cloud_queue), + hintText: local!.loginServer, + ), + onChanged: (text) => {server = text}, + keyboardType: TextInputType.url, + ), + const SizedBox(height: 10), + ElevatedButton( + onPressed: () async { + Dio dio = Dio(); + + var response = await dio.post( + 'https://ep2.vypal.me/qrlogin/${widget.code}', + options: Options( + headers: { + Headers.contentTypeHeader: + Headers.formUrlEncodedContentType, + }, + ), + data: { + 'username': email, + 'password': password, + 'server': server, + 'endpoint': _customEndpoint, + }, + ); + + if (response.statusCode == 200) { + navigatorKey.currentState!.pop(); + } else { + // If the server did not return a 200 OK response, throw an exception. + throw Exception('Failed to load data'); + } + }, + style: ButtonStyle( + elevation: MaterialStateProperty.all(3), + ), + child: Text(local!.loginLogin), + ), + ], + ), + ), + ), + ], + ), + ); + } +} diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index 2528735..aecfb5b 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -7,6 +7,7 @@ #include "generated_plugin_registrant.h" #include +#include #include #include @@ -14,6 +15,9 @@ void fl_register_plugins(FlPluginRegistry* registry) { g_autoptr(FlPluginRegistrar) dynamic_color_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin"); dynamic_color_plugin_register_with_registrar(dynamic_color_registrar); + g_autoptr(FlPluginRegistrar) gtk_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "GtkPlugin"); + gtk_plugin_register_with_registrar(gtk_registrar); g_autoptr(FlPluginRegistrar) sentry_flutter_registrar = fl_plugin_registry_get_registrar_for_plugin(registry, "SentryFlutterPlugin"); sentry_flutter_plugin_register_with_registrar(sentry_flutter_registrar); diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake index b942fff..a98a528 100644 --- a/linux/flutter/generated_plugins.cmake +++ b/linux/flutter/generated_plugins.cmake @@ -4,6 +4,7 @@ list(APPEND FLUTTER_PLUGIN_LIST dynamic_color + gtk sentry_flutter url_launcher_linux ) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 4216f5d..459ff28 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,6 +5,7 @@ import FlutterMacOS import Foundation +import app_links import connectivity_plus import dynamic_color import firebase_analytics @@ -18,6 +19,7 @@ import sqflite import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + AppLinksMacosPlugin.register(with: registry.registrar(forPlugin: "AppLinksMacosPlugin")) ConnectivityPlusPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlusPlugin")) DynamicColorPlugin.register(with: registry.registrar(forPlugin: "DynamicColorPlugin")) FLTFirebaseAnalyticsPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAnalyticsPlugin")) diff --git a/pubspec.lock b/pubspec.lock index 741ac9e..cb61985 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -9,6 +9,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.30" + app_links: + dependency: "direct main" + description: + name: app_links + sha256: "96e677810b83707ff5e10fac11e4839daa0ea4e0123c35864c092699165eb3db" + url: "https://pub.dev" + source: hosted + version: "6.1.1" args: dependency: transitive description: @@ -319,6 +327,14 @@ packages: description: flutter source: sdk version: "0.0.0" + gtk: + dependency: transitive + description: + name: gtk + sha256: e8ce9ca4b1df106e4d72dad201d345ea1a036cc12c360f1a7d5a758f78ffa42c + url: "https://pub.dev" + source: hosted + version: "2.1.0" html_unescape: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 5ed8aa1..6a28649 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -31,6 +31,7 @@ dependencies: flutter_displaymode: ^0.6.0 install_referrer: ^1.2.1 in_app_update: ^4.2.2 + app_links: ^6.1.1 dev_dependencies: integration_test: sdk: flutter diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 1a60256..511a95b 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,6 +6,7 @@ #include "generated_plugin_registrant.h" +#include #include #include #include @@ -13,6 +14,8 @@ #include void RegisterPlugins(flutter::PluginRegistry* registry) { + AppLinksPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("AppLinksPluginCApi")); ConnectivityPlusWindowsPluginRegisterWithRegistrar( registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); DynamicColorPluginCApiRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 928840d..5995934 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + app_links connectivity_plus dynamic_color firebase_core From da3d83995dc11ab67d8caf852752c6dd4a467191 Mon Sep 17 00:00:00 2001 From: vyPal <66716025+vyPal@users.noreply.github.com> Date: Tue, 11 Jun 2024 16:32:38 +0200 Subject: [PATCH 2/7] Automatically load credentials saved in app --- lib/qrlogin.dart | 48 +++++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/lib/qrlogin.dart b/lib/qrlogin.dart index 00bb01b..77aaaea 100644 --- a/lib/qrlogin.dart +++ b/lib/qrlogin.dart @@ -1,6 +1,7 @@ import 'package:dio/dio.dart'; import 'package:eduapge2/main.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; @@ -15,13 +16,14 @@ class QRLoginPage extends StatefulWidget { class QRLoinPageState extends BaseState { AppLocalizations? local; late SharedPreferences sharedPreferences; - String email = ""; - String password = ""; - String server = ""; bool _useCustomEndpoint = false; - String _customEndpoint = ''; bool showPassword = false; + TextEditingController emailController = TextEditingController(); + TextEditingController passwordController = TextEditingController(); + TextEditingController serverController = TextEditingController(); + TextEditingController customEndpointController = TextEditingController(); + @override void initState() { getPrefs(); @@ -42,16 +44,16 @@ class QRLoinPageState extends BaseState { String? sEndpoint = sharedPreferences.getString("customEndpoint"); if (sEmail != null) { - email = sEmail; + emailController.text = sEmail; } if (sPassword != null) { - password = sPassword; + passwordController.text = sPassword; } if (sServer != null) { - server = sServer; + serverController.text = sServer; } if (sEndpoint != null && sEndpoint != "") { - _customEndpoint = sEndpoint; + customEndpointController.text = sEndpoint; _useCustomEndpoint = true; } setState(() {}); @@ -78,14 +80,15 @@ class QRLoinPageState extends BaseState { ), Text(local!.qrLoginUseExistingCredentials), TextField( + controller: emailController, decoration: InputDecoration( icon: const Icon(Icons.email), hintText: local!.loginUsername, ), - onChanged: (text) => {email = text}, keyboardType: TextInputType.emailAddress, ), TextField( + controller: passwordController, decoration: InputDecoration( icon: const Icon(Icons.key), hintText: local!.loginPassword, @@ -100,8 +103,7 @@ class QRLoinPageState extends BaseState { }, ), ), - onChanged: (text) => {password = text}, - obscureText: true, + obscureText: !showPassword, keyboardType: TextInputType.visiblePassword, ), Row( @@ -119,17 +121,18 @@ class QRLoinPageState extends BaseState { ), if (_useCustomEndpoint) TextField( - decoration: InputDecoration( - icon: const Icon(Icons.language), - hintText: local!.loginCustomEndpoint, - ), - onChanged: (value) => {_customEndpoint = value}), + controller: customEndpointController, + decoration: InputDecoration( + icon: const Icon(Icons.language), + hintText: local!.loginCustomEndpoint, + ), + ), TextField( + controller: serverController, decoration: InputDecoration( icon: const Icon(Icons.cloud_queue), hintText: local!.loginServer, ), - onChanged: (text) => {server = text}, keyboardType: TextInputType.url, ), const SizedBox(height: 10), @@ -146,17 +149,16 @@ class QRLoinPageState extends BaseState { }, ), data: { - 'username': email, - 'password': password, - 'server': server, - 'endpoint': _customEndpoint, + 'username': emailController.text, + 'password': passwordController.text, + 'server': serverController.text, + 'endpoint': customEndpointController.text, }, ); if (response.statusCode == 200) { - navigatorKey.currentState!.pop(); + SystemNavigator.pop(); } else { - // If the server did not return a 200 OK response, throw an exception. throw Exception('Failed to load data'); } }, From 51d939c27480a774d5d997377af9d0c2bea3905a Mon Sep 17 00:00:00 2001 From: vyPal <66716025+vyPal@users.noreply.github.com> Date: Sat, 6 Jul 2024 08:38:37 +0200 Subject: [PATCH 3/7] Fix depraction issue --- lib/qrlogin.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/qrlogin.dart b/lib/qrlogin.dart index 77aaaea..f265f21 100644 --- a/lib/qrlogin.dart +++ b/lib/qrlogin.dart @@ -163,7 +163,7 @@ class QRLoinPageState extends BaseState { } }, style: ButtonStyle( - elevation: MaterialStateProperty.all(3), + elevation: WidgetStateProperty.all(3), ), child: Text(local!.loginLogin), ), From a037741ed7d0bb5dc699c297b0b917870965ac3e Mon Sep 17 00:00:00 2001 From: vyPal <66716025+vyPal@users.noreply.github.com> Date: Sat, 6 Jul 2024 08:41:22 +0200 Subject: [PATCH 4/7] Fix analyzer issues --- lib/create_message.dart | 4 ++-- lib/grades.dart | 2 +- lib/home.dart | 6 +++--- lib/homework.dart | 2 +- lib/login.dart | 2 +- lib/message.dart | 2 +- lib/messages.dart | 2 +- lib/timetable.dart | 2 +- pubspec.lock | 28 ++++++++++++++-------------- 9 files changed, 25 insertions(+), 25 deletions(-) diff --git a/lib/create_message.dart b/lib/create_message.dart index c1ce623..29b3a73 100644 --- a/lib/create_message.dart +++ b/lib/create_message.dart @@ -253,11 +253,11 @@ class SendMessageScreenState extends BaseState { leading: const Icon(Icons.drag_handle_rounded), trailing: ElevatedButton( style: ButtonStyle( - backgroundColor: MaterialStateProperty.all< + backgroundColor: WidgetStateProperty.all< Color>( const Color.fromARGB(255, 152, 1, 29)), foregroundColor: - MaterialStateProperty.all( + WidgetStateProperty.all( Colors.white), ), child: const Icon(Icons.delete_rounded), diff --git a/lib/grades.dart b/lib/grades.dart index 6938c55..1d14155 100644 --- a/lib/grades.dart +++ b/lib/grades.dart @@ -47,7 +47,7 @@ class GradesPageState extends BaseState { children: [messages], ) : Text(AppLocalizations.of(context)!.loading), - backgroundColor: Theme.of(context).colorScheme.background, + backgroundColor: Theme.of(context).colorScheme.surface, ); } diff --git a/lib/home.dart b/lib/home.dart index 140d10a..fae73fe 100644 --- a/lib/home.dart +++ b/lib/home.dart @@ -341,9 +341,9 @@ class HomePageState extends BaseState { height: 50, margin: const EdgeInsets.only(left: 20, right: 20, top: 10), decoration: BoxDecoration( - color: theme.colorScheme.surfaceVariant, + color: theme.colorScheme.surfaceContainerHighest, border: Border.all( - color: theme.colorScheme.background, + color: theme.colorScheme.surface, ), borderRadius: BorderRadiusDirectional.circular(25), ), @@ -617,7 +617,7 @@ class HomePageState extends BaseState { ), ], ), - backgroundColor: theme.colorScheme.background, + backgroundColor: theme.colorScheme.surface, drawer: Drawer( child: ListView( children: [ diff --git a/lib/homework.dart b/lib/homework.dart index 500697d..cd782b4 100644 --- a/lib/homework.dart +++ b/lib/homework.dart @@ -52,7 +52,7 @@ class HomeworkPageState extends BaseState { children: [messages], ) : Text(AppLocalizations.of(context)!.loading), - backgroundColor: Theme.of(context).colorScheme.background, + backgroundColor: Theme.of(context).colorScheme.surface, ); } diff --git a/lib/login.dart b/lib/login.dart index 28df784..6cc8953 100644 --- a/lib/login.dart +++ b/lib/login.dart @@ -147,7 +147,7 @@ class LoinPageState extends BaseState { Navigator.pop(context), }, style: ButtonStyle( - elevation: MaterialStateProperty.all(3), + elevation: WidgetStateProperty.all(3), ), child: Text(local!.loginLogin), ), diff --git a/lib/message.dart b/lib/message.dart index f9b72b5..9c36edd 100644 --- a/lib/message.dart +++ b/lib/message.dart @@ -413,7 +413,7 @@ class MessagePageState extends BaseState { children: [messages], ) : Text(AppLocalizations.of(context)!.loading), - backgroundColor: Theme.of(context).colorScheme.background, + backgroundColor: Theme.of(context).colorScheme.surface, ); } } diff --git a/lib/messages.dart b/lib/messages.dart index 6905440..278f1ee 100644 --- a/lib/messages.dart +++ b/lib/messages.dart @@ -89,7 +89,7 @@ class TimeTablePageState extends BaseState { children: [messages], ) : Text(AppLocalizations.of(context)!.loading), - backgroundColor: Theme.of(context).colorScheme.background, + backgroundColor: Theme.of(context).colorScheme.surface, floatingActionButton: FloatingActionButton( onPressed: () { Navigator.push( diff --git a/lib/timetable.dart b/lib/timetable.dart index d834ff7..1fadd9a 100644 --- a/lib/timetable.dart +++ b/lib/timetable.dart @@ -112,7 +112,7 @@ class TimeTablePageState extends BaseState { context); }, ), - backgroundColor: Theme.of(context).colorScheme.background, + backgroundColor: Theme.of(context).colorScheme.surface, ); } } diff --git a/pubspec.lock b/pubspec.lock index cb61985..e56c8ae 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -384,34 +384,34 @@ packages: dependency: "direct main" description: name: intl - sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf url: "https://pub.dev" source: hosted - version: "0.18.1" + version: "0.19.0" leak_tracker: dependency: transitive description: name: leak_tracker - sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" url: "https://pub.dev" source: hosted - version: "10.0.0" + version: "10.0.4" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.3" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.1" linkify: dependency: transitive description: @@ -448,10 +448,10 @@ packages: dependency: transitive description: name: meta - sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 + sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "1.12.0" nm: dependency: transitive description: @@ -757,10 +757,10 @@ packages: dependency: transitive description: name: test_api - sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" url: "https://pub.dev" source: hosted - version: "0.6.1" + version: "0.7.0" typed_data: dependency: transitive description: @@ -853,10 +853,10 @@ packages: dependency: transitive description: name: vm_service - sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" url: "https://pub.dev" source: hosted - version: "13.0.0" + version: "14.2.1" web: dependency: transitive description: From aef47b0e114c99e1b6706577231b7b35ddbbcee3 Mon Sep 17 00:00:00 2001 From: vyPal <66716025+vyPal@users.noreply.github.com> Date: Sat, 6 Jul 2024 15:16:03 +0200 Subject: [PATCH 5/7] Fix 401 during validation causing error --- lib/api.dart | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/api.dart b/lib/api.dart index 24b77db..950898c 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -262,7 +262,12 @@ class User { try { Response resp = await data.dio.get( "${data.baseUrl}/validate-token", - options: Options(headers: {"Authorization": "Bearer $token"}), + options: Options( + headers: {"Authorization": "Bearer $token"}, + validateStatus: (status) { + return status == 200 || status == 401; + }, + ), ); if (resp.data['success'] != true) { From 8a68b3e5d8a9cbf7784679a5d0bee65a4b5cbd00 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Sat, 6 Jul 2024 13:16:10 +0000 Subject: [PATCH 6/7] Restyled by astyle --- linux/flutter/generated_plugin_registrant.cc | 24 +++++++++---------- .../flutter/generated_plugin_registrant.cc | 24 +++++++++---------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc index aecfb5b..766ab16 100644 --- a/linux/flutter/generated_plugin_registrant.cc +++ b/linux/flutter/generated_plugin_registrant.cc @@ -12,16 +12,16 @@ #include void fl_register_plugins(FlPluginRegistry* registry) { - g_autoptr(FlPluginRegistrar) dynamic_color_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin"); - dynamic_color_plugin_register_with_registrar(dynamic_color_registrar); - g_autoptr(FlPluginRegistrar) gtk_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "GtkPlugin"); - gtk_plugin_register_with_registrar(gtk_registrar); - g_autoptr(FlPluginRegistrar) sentry_flutter_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "SentryFlutterPlugin"); - sentry_flutter_plugin_register_with_registrar(sentry_flutter_registrar); - g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = - fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); - url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); + g_autoptr(FlPluginRegistrar) dynamic_color_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "DynamicColorPlugin"); + dynamic_color_plugin_register_with_registrar(dynamic_color_registrar); + g_autoptr(FlPluginRegistrar) gtk_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "GtkPlugin"); + gtk_plugin_register_with_registrar(gtk_registrar); + g_autoptr(FlPluginRegistrar) sentry_flutter_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "SentryFlutterPlugin"); + sentry_flutter_plugin_register_with_registrar(sentry_flutter_registrar); + g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = + fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); + url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); } diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index 511a95b..02a3349 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -14,16 +14,16 @@ #include void RegisterPlugins(flutter::PluginRegistry* registry) { - AppLinksPluginCApiRegisterWithRegistrar( - registry->GetRegistrarForPlugin("AppLinksPluginCApi")); - ConnectivityPlusWindowsPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); - DynamicColorPluginCApiRegisterWithRegistrar( - registry->GetRegistrarForPlugin("DynamicColorPluginCApi")); - FirebaseCorePluginCApiRegisterWithRegistrar( - registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); - SentryFlutterPluginRegisterWithRegistrar( - registry->GetRegistrarForPlugin("SentryFlutterPlugin")); - UrlLauncherWindowsRegisterWithRegistrar( - registry->GetRegistrarForPlugin("UrlLauncherWindows")); + AppLinksPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("AppLinksPluginCApi")); + ConnectivityPlusWindowsPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin")); + DynamicColorPluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("DynamicColorPluginCApi")); + FirebaseCorePluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("FirebaseCorePluginCApi")); + SentryFlutterPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("SentryFlutterPlugin")); + UrlLauncherWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("UrlLauncherWindows")); } From e4b3c93924be28b40d1ab31f3021bbb9b4a27965 Mon Sep 17 00:00:00 2001 From: vyPal <66716025+vyPal@users.noreply.github.com> Date: Sat, 6 Jul 2024 16:49:34 +0200 Subject: [PATCH 7/7] chore: Add check for empty user token in TimeTable class --- lib/api.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/api.dart b/lib/api.dart index 950898c..7218377 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -406,6 +406,10 @@ class TimeTable { return timetables[dateOnly]!; } + if (data.user.token == "") { + return TimeTableData(date, [], []); + } + Response response = await data.dio.get( "${data.baseUrl}/api/timetable?to=${DateFormat('yyyy-MM-dd\'T\'HH:mm:ss\'Z\'', 'en_US').format(DateTime(date.year, date.month, date.day))}&from=${DateFormat('yyyy-MM-dd\'T\'HH:mm:ss\'Z\'', 'en_US').format(DateTime(date.year, date.month, date.day))}", options: Options(