forked from firka/student-legacy
updated packages, did things and maybe finally fixed login issue
This commit is contained in:
parent
939761695f
commit
2dafe5ed02
@ -68,6 +68,8 @@ Future loginAPI({
|
|||||||
gradeDelay: 0,
|
gradeDelay: 0,
|
||||||
),
|
),
|
||||||
role: Role.parent,
|
role: Role.parent,
|
||||||
|
accessToken: '',
|
||||||
|
accessTokenExpire: DateTime.now(),
|
||||||
refreshToken: '',
|
refreshToken: '',
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -154,6 +156,8 @@ Future loginAPI({
|
|||||||
name: student.name,
|
name: student.name,
|
||||||
student: student,
|
student: student,
|
||||||
role: JwtUtils.getRoleFromJWT(res["access_token"])!,
|
role: JwtUtils.getRoleFromJWT(res["access_token"])!,
|
||||||
|
accessToken: res["access_token"],
|
||||||
|
accessTokenExpire: DateTime.now(),
|
||||||
refreshToken: '',
|
refreshToken: '',
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -235,6 +239,15 @@ Future newLoginAPI({
|
|||||||
if (res != null) {
|
if (res != null) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print(res);
|
print(res);
|
||||||
|
|
||||||
|
// const splitSize = 1000;
|
||||||
|
// RegExp exp = RegExp(r"\w{" "$splitSize" "}");
|
||||||
|
// // String str = "0102031522";
|
||||||
|
// Iterable<Match> matches = exp.allMatches(res.toString());
|
||||||
|
// var list = matches.map((m) => m.group(0));
|
||||||
|
// list.forEach((e) {
|
||||||
|
// print(e);
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res.containsKey("error")) {
|
if (res.containsKey("error")) {
|
||||||
@ -267,6 +280,9 @@ Future newLoginAPI({
|
|||||||
name: student.name,
|
name: student.name,
|
||||||
student: student,
|
student: student,
|
||||||
role: role,
|
role: role,
|
||||||
|
accessToken: res["access_token"],
|
||||||
|
accessTokenExpire:
|
||||||
|
DateTime.now().add(Duration(seconds: (res["expires_in"] - 30))),
|
||||||
refreshToken: res["refresh_token"],
|
refreshToken: res["refresh_token"],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -40,6 +40,12 @@ Future<void> syncAll(BuildContext context) {
|
|||||||
StatusProvider statusProvider =
|
StatusProvider statusProvider =
|
||||||
Provider.of<StatusProvider>(context, listen: false);
|
Provider.of<StatusProvider>(context, listen: false);
|
||||||
|
|
||||||
|
// check if access token isn't expired
|
||||||
|
// if (user.user?.accessToken == null) {
|
||||||
|
// lock = false;
|
||||||
|
// return Future.value();
|
||||||
|
// }
|
||||||
|
|
||||||
List<Future<void>> tasks = [];
|
List<Future<void>> tasks = [];
|
||||||
int taski = 0;
|
int taski = 0;
|
||||||
|
|
||||||
@ -50,6 +56,25 @@ Future<void> syncAll(BuildContext context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
tasks = [
|
tasks = [
|
||||||
|
// refresh login
|
||||||
|
syncStatus(() async {
|
||||||
|
print(user.user?.accessTokenExpire);
|
||||||
|
|
||||||
|
if (user.user == null) return;
|
||||||
|
if (user.user!.accessTokenExpire.isBefore(DateTime.now())) {
|
||||||
|
String authRes = await Provider.of<KretaClient>(context, listen: false)
|
||||||
|
.refreshLogin() ??
|
||||||
|
'';
|
||||||
|
if (authRes != 'success') {
|
||||||
|
print('ERROR: failed to refresh login');
|
||||||
|
lock = false;
|
||||||
|
return Future.value();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print('INFO: access token is not expired');
|
||||||
|
}
|
||||||
|
}()),
|
||||||
|
|
||||||
syncStatus(Provider.of<GradeProvider>(context, listen: false).fetch()),
|
syncStatus(Provider.of<GradeProvider>(context, listen: false).fetch()),
|
||||||
syncStatus(Provider.of<TimetableProvider>(context, listen: false)
|
syncStatus(Provider.of<TimetableProvider>(context, listen: false)
|
||||||
.fetch(week: Week.current())),
|
.fetch(week: Week.current())),
|
||||||
|
@ -67,6 +67,7 @@ const usersDB = DatabaseStruct("users", {
|
|||||||
"institute_code": String, "student": String, "role": int,
|
"institute_code": String, "student": String, "role": int,
|
||||||
"nickname": String, "picture": String, // premium only (it's now plus btw)
|
"nickname": String, "picture": String, // premium only (it's now plus btw)
|
||||||
"grade_streak": int,
|
"grade_streak": int,
|
||||||
|
"access_token": String, "access_token_expire": String,
|
||||||
"refresh_token": String,
|
"refresh_token": String,
|
||||||
});
|
});
|
||||||
const userDataDB = DatabaseStruct("user_data", {
|
const userDataDB = DatabaseStruct("user_data", {
|
||||||
@ -141,6 +142,8 @@ Future<Database> initDB(DatabaseProvider database) async {
|
|||||||
"nickname": "",
|
"nickname": "",
|
||||||
"picture": "",
|
"picture": "",
|
||||||
"grade_streak": 0,
|
"grade_streak": 0,
|
||||||
|
"access_token": "",
|
||||||
|
"access_token_expire": "",
|
||||||
"refresh_token": "",
|
"refresh_token": "",
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
@ -18,6 +18,8 @@ class User {
|
|||||||
String picture;
|
String picture;
|
||||||
int gradeStreak;
|
int gradeStreak;
|
||||||
// new login method
|
// new login method
|
||||||
|
String accessToken;
|
||||||
|
DateTime accessTokenExpire;
|
||||||
String refreshToken;
|
String refreshToken;
|
||||||
|
|
||||||
String get displayName => nickname != '' ? nickname : name;
|
String get displayName => nickname != '' ? nickname : name;
|
||||||
@ -34,6 +36,8 @@ class User {
|
|||||||
this.nickname = "",
|
this.nickname = "",
|
||||||
this.picture = "",
|
this.picture = "",
|
||||||
this.gradeStreak = 0,
|
this.gradeStreak = 0,
|
||||||
|
required this.accessToken,
|
||||||
|
required this.accessTokenExpire,
|
||||||
required this.refreshToken,
|
required this.refreshToken,
|
||||||
}) {
|
}) {
|
||||||
if (id != null) {
|
if (id != null) {
|
||||||
@ -65,6 +69,9 @@ class User {
|
|||||||
nickname: map["nickname"] ?? "",
|
nickname: map["nickname"] ?? "",
|
||||||
picture: map["picture"] ?? "",
|
picture: map["picture"] ?? "",
|
||||||
gradeStreak: map["grade_streak"] ?? 0,
|
gradeStreak: map["grade_streak"] ?? 0,
|
||||||
|
accessToken: map["access_token"] ?? "",
|
||||||
|
accessTokenExpire: DateTime.parse(
|
||||||
|
map["access_token_expire"] ?? DateTime.now().toIso8601String()),
|
||||||
refreshToken: map["refresh_token"] ?? "",
|
refreshToken: map["refresh_token"] ?? "",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -81,6 +88,8 @@ class User {
|
|||||||
"nickname": nickname,
|
"nickname": nickname,
|
||||||
"picture": picture,
|
"picture": picture,
|
||||||
"grade_streak": gradeStreak,
|
"grade_streak": gradeStreak,
|
||||||
|
"access_token": accessToken,
|
||||||
|
"access_token_expire": accessTokenExpire.toIso8601String(),
|
||||||
"refresh_token": refreshToken,
|
"refresh_token": refreshToken,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ dependencies:
|
|||||||
# ref: master
|
# ref: master
|
||||||
path_provider: ^2.0.2
|
path_provider: ^2.0.2
|
||||||
permission_handler: ^11.0.1
|
permission_handler: ^11.0.1
|
||||||
share_plus: ^9.0.0
|
share_plus: ^10.0.3
|
||||||
connectivity_plus: ^6.0.3
|
connectivity_plus: ^6.0.3
|
||||||
flutter_displaymode: ^0.6.0
|
flutter_displaymode: ^0.6.0
|
||||||
quick_actions: ^1.0.1
|
quick_actions: ^1.0.1
|
||||||
|
@ -28,7 +28,7 @@ class KretaClient {
|
|||||||
late final DatabaseProvider _database;
|
late final DatabaseProvider _database;
|
||||||
late final StatusProvider _status;
|
late final StatusProvider _status;
|
||||||
|
|
||||||
bool _loginRefreshing = false;
|
// bool _loginRefreshing = false;
|
||||||
|
|
||||||
KretaClient({
|
KretaClient({
|
||||||
this.accessToken,
|
this.accessToken,
|
||||||
@ -67,10 +67,14 @@ class KretaClient {
|
|||||||
headerMap = {};
|
headerMap = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (accessToken == null || accessToken == '') {
|
||||||
|
accessToken = _user.user?.accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
http.Response? res;
|
http.Response? res;
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
if (autoHeader) {
|
if (autoHeader) {
|
||||||
if (!headerMap.containsKey("authorization") && accessToken != null) {
|
if (!headerMap.containsKey("authorization") && accessToken != null) {
|
||||||
headerMap["authorization"] = "Bearer $accessToken";
|
headerMap["authorization"] = "Bearer $accessToken";
|
||||||
@ -86,13 +90,14 @@ class KretaClient {
|
|||||||
if (res.statusCode == 401) {
|
if (res.statusCode == 401) {
|
||||||
headerMap.remove("authorization");
|
headerMap.remove("authorization");
|
||||||
print("DEBUG: 401 error, refreshing login");
|
print("DEBUG: 401 error, refreshing login");
|
||||||
await refreshLogin();
|
print("DEBUG: 401 error, URL: $url");
|
||||||
|
// await refreshLogin();
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait before retrying
|
// Wait before retrying
|
||||||
await Future.delayed(const Duration(milliseconds: 500));
|
await Future.delayed(const Duration(milliseconds: 1500));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res == null) throw "Login error";
|
if (res == null) throw "Login error";
|
||||||
@ -130,10 +135,14 @@ class KretaClient {
|
|||||||
headerMap = {};
|
headerMap = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (accessToken == null || accessToken == '') {
|
||||||
|
accessToken = _user.user?.accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
http.Response? res;
|
http.Response? res;
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 2; i++) {
|
||||||
if (autoHeader) {
|
if (autoHeader) {
|
||||||
if (!headerMap.containsKey("authorization") && accessToken != null) {
|
if (!headerMap.containsKey("authorization") && accessToken != null) {
|
||||||
headerMap["authorization"] = "Bearer $accessToken";
|
headerMap["authorization"] = "Bearer $accessToken";
|
||||||
@ -151,11 +160,14 @@ class KretaClient {
|
|||||||
|
|
||||||
res = await client.post(Uri.parse(url), headers: headerMap, body: body);
|
res = await client.post(Uri.parse(url), headers: headerMap, body: body);
|
||||||
if (res.statusCode == 401) {
|
if (res.statusCode == 401) {
|
||||||
await refreshLogin();
|
// await refreshLogin();
|
||||||
headerMap.remove("authorization");
|
headerMap.remove("authorization");
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Wait before retrying
|
||||||
|
await Future.delayed(const Duration(milliseconds: 1500));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res == null) throw "Login error";
|
if (res == null) throw "Login error";
|
||||||
@ -188,6 +200,10 @@ class KretaClient {
|
|||||||
headerMap = {};
|
headerMap = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (accessToken == null || accessToken == '') {
|
||||||
|
accessToken = _user.user?.accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
http.StreamedResponse? res;
|
http.StreamedResponse? res;
|
||||||
|
|
||||||
@ -218,7 +234,7 @@ class KretaClient {
|
|||||||
|
|
||||||
if (res.statusCode == 401) {
|
if (res.statusCode == 401) {
|
||||||
headerMap.remove("authorization");
|
headerMap.remove("authorization");
|
||||||
await refreshLogin();
|
// await refreshLogin();
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -238,8 +254,8 @@ class KretaClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<String?> refreshLogin() async {
|
Future<String?> refreshLogin() async {
|
||||||
if (_loginRefreshing) return null;
|
// if (_loginRefreshing) return null;
|
||||||
_loginRefreshing = true;
|
// _loginRefreshing = true;
|
||||||
|
|
||||||
User? loginUser = _user.user;
|
User? loginUser = _user.user;
|
||||||
if (loginUser == null) return null;
|
if (loginUser == null) return null;
|
||||||
@ -288,6 +304,11 @@ class KretaClient {
|
|||||||
|
|
||||||
if (res.containsKey("access_token")) {
|
if (res.containsKey("access_token")) {
|
||||||
accessToken = res["access_token"];
|
accessToken = res["access_token"];
|
||||||
|
loginUser.accessToken = res["refresh_token"];
|
||||||
|
loginUser.accessTokenExpire =
|
||||||
|
DateTime.now().add(Duration(seconds: (res["expires_in"] - 30)));
|
||||||
|
_database.store.storeUser(loginUser);
|
||||||
|
_user.refresh();
|
||||||
}
|
}
|
||||||
if (res.containsKey("refresh_token")) {
|
if (res.containsKey("refresh_token")) {
|
||||||
refreshToken = res["refresh_token"];
|
refreshToken = res["refresh_token"];
|
||||||
@ -298,15 +319,20 @@ class KretaClient {
|
|||||||
if (res.containsKey("id_token")) {
|
if (res.containsKey("id_token")) {
|
||||||
idToken = res["id_token"];
|
idToken = res["id_token"];
|
||||||
}
|
}
|
||||||
_loginRefreshing = false;
|
// _loginRefreshing = false;
|
||||||
|
print('successful refresh');
|
||||||
|
|
||||||
|
return 'success';
|
||||||
} else {
|
} else {
|
||||||
_loginRefreshing = false;
|
// _loginRefreshing = false;
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_loginRefreshing = false;
|
// _loginRefreshing = false;
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
// return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> logout() async {
|
Future<void> logout() async {
|
||||||
|
@ -42,6 +42,7 @@ import 'package:refilc_mobile_ui/screens/settings/accounts/account_view.dart';
|
|||||||
import 'package:refilc_mobile_ui/screens/settings/notifications_screen.dart';
|
import 'package:refilc_mobile_ui/screens/settings/notifications_screen.dart';
|
||||||
import 'package:refilc_mobile_ui/screens/settings/privacy_view.dart';
|
import 'package:refilc_mobile_ui/screens/settings/privacy_view.dart';
|
||||||
import 'package:refilc_mobile_ui/screens/settings/settings_helper.dart';
|
import 'package:refilc_mobile_ui/screens/settings/settings_helper.dart';
|
||||||
|
import 'package:refilc_mobile_ui/screens/settings/submenu/code_scanner.dart';
|
||||||
import 'package:refilc_mobile_ui/screens/settings/submenu/extras_screen.dart';
|
import 'package:refilc_mobile_ui/screens/settings/submenu/extras_screen.dart';
|
||||||
import 'package:refilc_mobile_ui/screens/settings/submenu/personalize_screen.dart';
|
import 'package:refilc_mobile_ui/screens/settings/submenu/personalize_screen.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
@ -1012,14 +1013,15 @@ class SettingsScreenState extends State<SettingsScreen>
|
|||||||
children: [
|
children: [
|
||||||
PanelButton(
|
PanelButton(
|
||||||
leading: Icon(
|
leading: Icon(
|
||||||
FeatherIcons.map,
|
Icons.qr_code,
|
||||||
size: 22.0,
|
size: 22.0,
|
||||||
color: AppColors.of(context).text.withOpacity(0.95),
|
color: AppColors.of(context).text.withOpacity(0.95),
|
||||||
),
|
),
|
||||||
title: Text("stickermap".i18n),
|
title: Text("qr_scanner".i18n),
|
||||||
onPressed: () => launchUrl(
|
onPressed: () => Navigator.of(context).push(
|
||||||
Uri.parse("https://stickermap.refilc.hu"),
|
MaterialPageRoute(
|
||||||
mode: LaunchMode.inAppBrowserView,
|
builder: (context) => const CodeScannerScreen(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
borderRadius: const BorderRadius.vertical(
|
borderRadius: const BorderRadius.vertical(
|
||||||
top: Radius.circular(12.0),
|
top: Radius.circular(12.0),
|
||||||
@ -1034,6 +1036,22 @@ class SettingsScreenState extends State<SettingsScreen>
|
|||||||
),
|
),
|
||||||
title: Text("news".i18n),
|
title: Text("news".i18n),
|
||||||
onPressed: () => _openNews(context),
|
onPressed: () => _openNews(context),
|
||||||
|
borderRadius: const BorderRadius.vertical(
|
||||||
|
top: Radius.circular(4.0),
|
||||||
|
bottom: Radius.circular(4.0),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PanelButton(
|
||||||
|
leading: Icon(
|
||||||
|
FeatherIcons.map,
|
||||||
|
size: 22.0,
|
||||||
|
color: AppColors.of(context).text.withOpacity(0.95),
|
||||||
|
),
|
||||||
|
title: Text("stickermap".i18n),
|
||||||
|
onPressed: () => launchUrl(
|
||||||
|
Uri.parse("https://stickermap.refilc.hu"),
|
||||||
|
mode: LaunchMode.inAppBrowserView,
|
||||||
|
),
|
||||||
borderRadius: const BorderRadius.vertical(
|
borderRadius: const BorderRadius.vertical(
|
||||||
top: Radius.circular(4.0),
|
top: Radius.circular(4.0),
|
||||||
bottom: Radius.circular(12.0),
|
bottom: Radius.circular(12.0),
|
||||||
|
@ -131,6 +131,7 @@ extension SettingsLocalization on String {
|
|||||||
"feedback": "Feedback",
|
"feedback": "Feedback",
|
||||||
"other": "Other",
|
"other": "Other",
|
||||||
"stickermap": "Sticker Map",
|
"stickermap": "Sticker Map",
|
||||||
|
"qr_scanner": "QR Scanner",
|
||||||
},
|
},
|
||||||
"hu_hu": {
|
"hu_hu": {
|
||||||
"heads_up": "Figyelem!",
|
"heads_up": "Figyelem!",
|
||||||
@ -260,6 +261,7 @@ extension SettingsLocalization on String {
|
|||||||
"feedback": "Visszajelzés",
|
"feedback": "Visszajelzés",
|
||||||
"other": "Egyéb",
|
"other": "Egyéb",
|
||||||
"stickermap": "Matrica térkép",
|
"stickermap": "Matrica térkép",
|
||||||
|
"qr_scanner": "QR Kódolvasó",
|
||||||
},
|
},
|
||||||
"de_de": {
|
"de_de": {
|
||||||
"heads_up": "Achtung!",
|
"heads_up": "Achtung!",
|
||||||
@ -389,6 +391,7 @@ extension SettingsLocalization on String {
|
|||||||
"feedback": "Feedback",
|
"feedback": "Feedback",
|
||||||
"other": "Sonstiges",
|
"other": "Sonstiges",
|
||||||
"stickermap": "Sticker Map",
|
"stickermap": "Sticker Map",
|
||||||
|
"qr_scanner": "QR-Scanner",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
136
refilc_mobile_ui/lib/screens/settings/submenu/code_scanner.dart
Normal file
136
refilc_mobile_ui/lib/screens/settings/submenu/code_scanner.dart
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
|
import 'package:qr_code_scanner_plus/qr_code_scanner_plus.dart';
|
||||||
|
import 'package:refilc_mobile_ui/screens/settings/settings_screen.i18n.dart';
|
||||||
|
|
||||||
|
class CodeScannerScreen extends StatefulWidget {
|
||||||
|
const CodeScannerScreen({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<StatefulWidget> createState() => _CodeScannerScreenState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _CodeScannerScreenState extends State<CodeScannerScreen> {
|
||||||
|
Barcode? result;
|
||||||
|
QRViewController? controller;
|
||||||
|
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
|
||||||
|
|
||||||
|
// In order to get hot reload to work we need to pause the camera if the platform
|
||||||
|
// is android, or resume the camera if the platform is iOS.
|
||||||
|
@override
|
||||||
|
void reassemble() {
|
||||||
|
super.reassemble();
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
controller!.pauseCamera();
|
||||||
|
}
|
||||||
|
controller!.resumeCamera();
|
||||||
|
}
|
||||||
|
|
||||||
|
// @override
|
||||||
|
// void initState() {
|
||||||
|
// super.initState();
|
||||||
|
|
||||||
|
// controller!.resumeCamera();
|
||||||
|
// }
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
title: Text('qr_scanner'.i18n),
|
||||||
|
leading: const BackButton(),
|
||||||
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
icon: FutureBuilder(
|
||||||
|
future: controller?.getFlashStatus(),
|
||||||
|
builder: (context, snapshot) {
|
||||||
|
return Icon(
|
||||||
|
snapshot.data == true
|
||||||
|
? FeatherIcons.zapOff
|
||||||
|
: FeatherIcons.zap,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
onPressed: () async {
|
||||||
|
await controller?.toggleFlash();
|
||||||
|
setState(() {});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: _buildQrView(context),
|
||||||
|
// body: Column(
|
||||||
|
// children: <Widget>[
|
||||||
|
// Expanded(flex: 4, child: _buildQrView(context)),
|
||||||
|
// // Expanded(
|
||||||
|
// // flex: 1,
|
||||||
|
// // child: FittedBox(
|
||||||
|
// // fit: BoxFit.contain,
|
||||||
|
// // child: Column(
|
||||||
|
// // mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
// // children: <Widget>[
|
||||||
|
// // if (result != null)
|
||||||
|
// // Text(
|
||||||
|
// // 'Barcode Type: ${describeEnum(result!.format)} Data: ${result!.code}')
|
||||||
|
// // else
|
||||||
|
// // const Text('Scan a code'),
|
||||||
|
// // ],
|
||||||
|
// // ),
|
||||||
|
// // ),
|
||||||
|
// // )
|
||||||
|
// ],
|
||||||
|
// ),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildQrView(BuildContext context) {
|
||||||
|
// For this example we check how width or tall the device is and change the scanArea and overlay accordingly.
|
||||||
|
var scanArea = (MediaQuery.of(context).size.width < 400 ||
|
||||||
|
MediaQuery.of(context).size.height < 400)
|
||||||
|
? 150.0
|
||||||
|
: 280.0;
|
||||||
|
// To ensure the Scanner view is properly sizes after rotation
|
||||||
|
// we need to listen for Flutter SizeChanged notification and update controller
|
||||||
|
return QRView(
|
||||||
|
key: qrKey,
|
||||||
|
onQRViewCreated: _onQRViewCreated,
|
||||||
|
overlay: QrScannerOverlayShape(
|
||||||
|
borderColor: Theme.of(context).primaryColor,
|
||||||
|
borderRadius: 10,
|
||||||
|
borderLength: 30,
|
||||||
|
borderWidth: 10,
|
||||||
|
cutOutSize: scanArea,
|
||||||
|
),
|
||||||
|
onPermissionSet: (ctrl, p) => _onPermissionSet(context, ctrl, p),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onQRViewCreated(QRViewController controller) {
|
||||||
|
setState(() {
|
||||||
|
this.controller = controller;
|
||||||
|
});
|
||||||
|
controller.scannedDataStream.listen((scanData) {
|
||||||
|
setState(() {
|
||||||
|
result = scanData;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void _onPermissionSet(BuildContext context, QRViewController ctrl, bool p) {
|
||||||
|
// log('${DateTime.now().toIso8601String()}_onPermissionSet $p');
|
||||||
|
if (!p) {
|
||||||
|
ScaffoldMessenger.of(context).showSnackBar(
|
||||||
|
const SnackBar(content: Text('no Permission')),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
controller?.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
}
|
@ -4,7 +4,6 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
import 'package:flutter_feather_icons/flutter_feather_icons.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
// import 'package:refilc/models/settings.dart';
|
// import 'package:refilc/models/settings.dart';
|
||||||
import 'package:refilc/models/shared_theme.dart';
|
|
||||||
import 'package:refilc/theme/colors/colors.dart';
|
import 'package:refilc/theme/colors/colors.dart';
|
||||||
import 'package:refilc_kreta_api/providers/share_provider.dart';
|
import 'package:refilc_kreta_api/providers/share_provider.dart';
|
||||||
import 'package:refilc_mobile_ui/common/action_button.dart';
|
import 'package:refilc_mobile_ui/common/action_button.dart';
|
||||||
|
@ -58,7 +58,7 @@ dependencies:
|
|||||||
auto_size_text: ^3.0.0
|
auto_size_text: ^3.0.0
|
||||||
connectivity_plus: ^6.0.3
|
connectivity_plus: ^6.0.3
|
||||||
collection: ^1.18.0
|
collection: ^1.18.0
|
||||||
share_plus: ^9.0.0
|
share_plus: ^10.0.3
|
||||||
image_picker: ^1.0.7
|
image_picker: ^1.0.7
|
||||||
path_provider: ^2.1.2
|
path_provider: ^2.1.2
|
||||||
image_crop:
|
image_crop:
|
||||||
@ -77,6 +77,7 @@ dependencies:
|
|||||||
webview_flutter: ^4.8.0
|
webview_flutter: ^4.8.0
|
||||||
file_picker: ^8.0.5
|
file_picker: ^8.0.5
|
||||||
shake_flutter: ^17.0.0
|
shake_flutter: ^17.0.0
|
||||||
|
qr_code_scanner_plus: ^2.0.6
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_lints: ^4.0.0
|
flutter_lints: ^4.0.0
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 26cd3fc163d72ddb849edfeb7fdb7b64c7df44bc
|
Subproject commit 6abc4edf70deeaffea8b8a7dd95acebecc5a520b
|
Loading…
x
Reference in New Issue
Block a user