Skip to content

Commit

Permalink
Add ability to login with qrcode
Browse files Browse the repository at this point in the history
  • Loading branch information
vyPal committed Jun 11, 2024
1 parent 2f7cb1c commit 074a6fd
Show file tree
Hide file tree
Showing 12 changed files with 249 additions and 2 deletions.
7 changes: 7 additions & 0 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" android:host="ep2.vypal.me" />
<data android:scheme="https" />
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
Expand Down
4 changes: 3 additions & 1 deletion lib/l10n/app_cs.arb
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
4 changes: 3 additions & 1 deletion lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
32 changes: 32 additions & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -53,6 +57,8 @@ abstract class BaseState<T extends StatefulWidget> extends State<T> {
}
}

final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

class MyApp extends StatelessWidget {
const MyApp({super.key});

Expand All @@ -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],
Expand Down Expand Up @@ -107,6 +114,9 @@ class PageBaseState extends BaseState<PageBase> {
int _selectedIndex = 0;
String baseUrl = FirebaseRemoteConfig.instance.getString("testUrl");

late AppLinks _appLinks;
StreamSubscription<Uri>? _linkSubscription;

bool loaded = false;

bool error = false; //for error status
Expand All @@ -125,6 +135,28 @@ class PageBaseState extends BaseState<PageBase> {
setOptimalDisplayMode();
if (!_isCheckingForUpdate) _checkForUpdate(); // ik that it's not necessary
super.initState();
initDeepLinks();
}

@override
void dispose() {
_linkSubscription?.cancel();
super.dispose();
}

Future<void> 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<void> setOptimalDisplayMode() async {
Expand Down
176 changes: 176 additions & 0 deletions lib/qrlogin.dart
Original file line number Diff line number Diff line change
@@ -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<StatefulWidget> createState() => QRLoinPageState();
}

class QRLoinPageState extends BaseState<QRLoginPage> {
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<void> 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),
),
],
),
),
),
],
),
);
}
}
4 changes: 4 additions & 0 deletions linux/flutter/generated_plugin_registrant.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,17 @@
#include "generated_plugin_registrant.h"

#include <dynamic_color/dynamic_color_plugin.h>
#include <gtk/gtk_plugin.h>
#include <sentry_flutter/sentry_flutter_plugin.h>
#include <url_launcher_linux/url_launcher_plugin.h>

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);
Expand Down
1 change: 1 addition & 0 deletions linux/flutter/generated_plugins.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

list(APPEND FLUTTER_PLUGIN_LIST
dynamic_color
gtk
sentry_flutter
url_launcher_linux
)
Expand Down
2 changes: 2 additions & 0 deletions macos/Flutter/GeneratedPluginRegistrant.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import FlutterMacOS
import Foundation

import app_links
import connectivity_plus
import dynamic_color
import firebase_analytics
Expand All @@ -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"))
Expand Down
16 changes: 16 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions windows/flutter/generated_plugin_registrant.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@

#include "generated_plugin_registrant.h"

#include <app_links/app_links_plugin_c_api.h>
#include <connectivity_plus/connectivity_plus_windows_plugin.h>
#include <dynamic_color/dynamic_color_plugin_c_api.h>
#include <firebase_core/firebase_core_plugin_c_api.h>
#include <sentry_flutter/sentry_flutter_plugin.h>
#include <url_launcher_windows/url_launcher_windows.h>

void RegisterPlugins(flutter::PluginRegistry* registry) {
AppLinksPluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("AppLinksPluginCApi"));
ConnectivityPlusWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
DynamicColorPluginCApiRegisterWithRegistrar(
Expand Down
1 change: 1 addition & 0 deletions windows/flutter/generated_plugins.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#

list(APPEND FLUTTER_PLUGIN_LIST
app_links
connectivity_plus
dynamic_color
firebase_core
Expand Down

0 comments on commit 074a6fd

Please sign in to comment.