forked from eatvio/eatvio_app
feat(qr+devtools): scan qr code and dev tools
This commit is contained in:
@@ -388,7 +388,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 30;
|
||||
CURRENT_PROJECT_VERSION = 31;
|
||||
DEVELOPMENT_TEAM = VL68C36HYS;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
@@ -538,7 +538,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 30;
|
||||
CURRENT_PROJECT_VERSION = 31;
|
||||
DEVELOPMENT_TEAM = VL68C36HYS;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
@@ -576,7 +576,7 @@
|
||||
CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
|
||||
CODE_SIGN_IDENTITY = "Apple Distribution: ITVIO, OOO (VL68C36HYS)";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
CURRENT_PROJECT_VERSION = 30;
|
||||
CURRENT_PROJECT_VERSION = 31;
|
||||
DEVELOPMENT_TEAM = VL68C36HYS;
|
||||
ENABLE_BITCODE = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>30</string>
|
||||
<string>31</string>
|
||||
<key>ITSAppUsesNonExemptEncryption</key>
|
||||
<false/>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
|
||||
@@ -88,10 +88,10 @@ class _AuthScreenState extends State<AuthScreen> {
|
||||
title: GestureDetector(
|
||||
onTap: () {
|
||||
tapsCount++;
|
||||
if (tapsCount == 6) {
|
||||
if (tapsCount == 7) {
|
||||
tapsCount = 0;
|
||||
GoRouter.of(context).pushNamed(DevToolsScreen.name);
|
||||
}
|
||||
GoRouter.of(context).pushNamed(DevToolsScreen.name);
|
||||
},
|
||||
child: SvgPicture.asset(
|
||||
ImageConstant.imgLogoEatvio,
|
||||
@@ -244,7 +244,7 @@ class _AuthScreenState extends State<AuthScreen> {
|
||||
height: 48,
|
||||
width: 48,
|
||||
child: FloatingActionButton.extended(
|
||||
heroTag: 'authButton',
|
||||
heroTag: 'scanQrCodeButton',
|
||||
highlightElevation: 0,
|
||||
elevation: 0,
|
||||
focusElevation: 0,
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:eatvio_app/core/app_router.dart';
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/locator_service.dart';
|
||||
import 'package:eatvio_app/core/token_storage.dart';
|
||||
import 'package:eatvio_app/core/utils/toasts.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:qr_code_scanner_plus/qr_code_scanner_plus.dart';
|
||||
|
||||
class ScanQRCodeScreen extends StatefulWidget {
|
||||
const ScanQRCodeScreen({super.key});
|
||||
@@ -8,6 +18,20 @@ class ScanQRCodeScreen extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _ScanQRCodeScreenState extends State<ScanQRCodeScreen> {
|
||||
final GlobalKey qrKey = GlobalKey(debugLabel: 'QR');
|
||||
Barcode? result;
|
||||
QRViewController? controller;
|
||||
|
||||
@override
|
||||
void reassemble() {
|
||||
super.reassemble();
|
||||
if (Platform.isAndroid) {
|
||||
controller!.pauseCamera();
|
||||
} else if (Platform.isIOS) {
|
||||
controller!.resumeCamera();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@@ -15,6 +39,52 @@ class _ScanQRCodeScreenState extends State<ScanQRCodeScreen> {
|
||||
title: const Text('Сканирование QR-кода'),
|
||||
centerTitle: true,
|
||||
),
|
||||
body: Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: QRView(
|
||||
key: qrKey,
|
||||
onQRViewCreated: _onQRViewCreated,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _onQRViewCreated(QRViewController controller) {
|
||||
this.controller = controller;
|
||||
controller.scannedDataStream.listen((scanData) async {
|
||||
setState(() {
|
||||
result = scanData;
|
||||
});
|
||||
controller.pauseCamera();
|
||||
try {
|
||||
final scannedUrl = scanData.code;
|
||||
final uri = Uri.parse(scannedUrl ?? '');
|
||||
final scannedBaseUrl = (uri.hasAuthority) ? '${uri.scheme}://${uri.host}' : '';
|
||||
baseUrl = scannedBaseUrl;
|
||||
sl<Dio>().options.baseUrl = baseUrl;
|
||||
final response = await Dio().getUri(
|
||||
uri,
|
||||
options: Options(
|
||||
headers: {
|
||||
'accept': 'application/json',
|
||||
'content-type': 'application/json',
|
||||
},
|
||||
),
|
||||
);
|
||||
final token = response.data['token'];
|
||||
await TokenStorage.saveTokenInStorage(token);
|
||||
AppRouter.navigatorKey.currentContext?.go(
|
||||
'/feed-screen',
|
||||
extra: {'needToInitializeWebSocket': false},
|
||||
);
|
||||
showSuccessToast('Добро пожаловать!');
|
||||
} catch (e) {
|
||||
controller.resumeCamera();
|
||||
showErrorToast('Что-то пошло не так, попробуйте обновить страницу с qr кодом или используйте вход через логин и пароль');
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'package:badges/badges.dart' as badges;
|
||||
import 'package:eatvio_app/core/const.dart';
|
||||
import 'package:eatvio_app/core/utils/image_constant.dart';
|
||||
import 'package:eatvio_app/features/dev_tools/presentation/dev_tools_screen.dart';
|
||||
import 'package:eatvio_app/features/notifications/presentation/notifications_cubit/notifications_cubit.dart';
|
||||
import 'package:eatvio_app/features/notifications/presentation/notifications_cubit/notifications_state.dart';
|
||||
import 'package:eatvio_app/features/profile/models/profile_model.dart';
|
||||
@@ -30,6 +31,7 @@ class BottomNavigationBarWidget extends StatefulWidget {
|
||||
class _BottomNavigationBarWidgetState extends State<BottomNavigationBarWidget> {
|
||||
int currentBottomNavBarIndex = 1;
|
||||
late final List<String> pages;
|
||||
int tapsCount = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
@@ -58,12 +60,29 @@ class _BottomNavigationBarWidgetState extends State<BottomNavigationBarWidget> {
|
||||
}
|
||||
|
||||
void _onItemTapped(int index) async {
|
||||
if (pages.length == 7) {
|
||||
if (index == 6) {
|
||||
tapsCount++;
|
||||
if (tapsCount == 7) {
|
||||
tapsCount = 0;
|
||||
GoRouter.of(context).pushNamed(DevToolsScreen.name);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (index == 5) {
|
||||
tapsCount++;
|
||||
if (tapsCount == 7) {
|
||||
tapsCount = 0;
|
||||
GoRouter.of(context).pushNamed(DevToolsScreen.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (currentBottomNavBarIndex != index) {
|
||||
setState(() {
|
||||
currentBottomNavBarIndex = index;
|
||||
});
|
||||
GoRouter.of(context).replace(pages[currentBottomNavBarIndex]);
|
||||
}
|
||||
GoRouter.of(context).replace(pages[currentBottomNavBarIndex]);
|
||||
}
|
||||
|
||||
@override
|
||||
|
||||
@@ -81,6 +81,8 @@ class _DevToolsScreenContentState extends State<DevToolsScreenContent> {
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
baseUrlForTest = controller.text;
|
||||
baseUrl = baseUrlForTest.toLowerCase();
|
||||
sl<Dio>().options.baseUrl = baseUrl;
|
||||
controller.clear();
|
||||
});
|
||||
},
|
||||
@@ -89,73 +91,79 @@ class _DevToolsScreenContentState extends State<DevToolsScreenContent> {
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
if (baseUrlForTest != baseUrl)
|
||||
CustomOutlinedButton(
|
||||
text: 'Set dev2 base url',
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
baseUrlForTest = baseUrl;
|
||||
});
|
||||
},
|
||||
buttonStyle: const ButtonStyle(),
|
||||
),
|
||||
CustomOutlinedButton(
|
||||
text: baseUrl == 'https://dev2.eatvio.com' ? 'Set production base url' : 'Set dev2 base url',
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
if (baseUrl == 'https://eatvio.ru') {
|
||||
baseUrlForTest = 'https://dev2.eatvio.com';
|
||||
} else {
|
||||
baseUrlForTest = 'https://eatvio.ru';
|
||||
}
|
||||
baseUrl = baseUrlForTest.toLowerCase();
|
||||
sl<Dio>().options.baseUrl = baseUrl;
|
||||
controller.clear();
|
||||
});
|
||||
},
|
||||
buttonStyle: const ButtonStyle(),
|
||||
),
|
||||
SizedBox(height: baseUrlForTest != baseUrl ? 40 : 10),
|
||||
ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: testCases.length,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder:
|
||||
(context, index) => Padding(
|
||||
padding: const EdgeInsets.only(bottom: 10.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(child: Text('${index + 1}. ${testCases[index].name}')),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
CustomOutlinedButton(
|
||||
text: 'run',
|
||||
height: 20,
|
||||
width: 60,
|
||||
onPressed: () async {
|
||||
if (testsStates[index] == TestState.loading) return;
|
||||
if (baseUrl.toLowerCase() != 'https://eatvio.ru')
|
||||
ListView.builder(
|
||||
shrinkWrap: true,
|
||||
itemCount: testCases.length,
|
||||
physics: const NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (context, index) => Padding(
|
||||
padding: const EdgeInsets.only(bottom: 10.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Expanded(child: Text('${index + 1}. ${testCases[index].name}')),
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
CustomOutlinedButton(
|
||||
text: 'run',
|
||||
height: 20,
|
||||
width: 60,
|
||||
onPressed: () async {
|
||||
if (testsStates[index] == TestState.loading) return;
|
||||
|
||||
setState(() {
|
||||
testsStates[index] = TestState.loading;
|
||||
});
|
||||
final result = await testCases[index].run(baseUrl: baseUrlForTest);
|
||||
if (result) {
|
||||
setState(() {
|
||||
testsStates[index] = TestState.loading;
|
||||
testsStates[index] = TestState.success;
|
||||
});
|
||||
final result = await testCases[index].run(baseUrl: baseUrlForTest);
|
||||
if (result) {
|
||||
setState(() {
|
||||
testsStates[index] = TestState.success;
|
||||
});
|
||||
showSuccessToast('${testCases[index].name} passed');
|
||||
} else {
|
||||
setState(() {
|
||||
testsStates[index] = TestState.fail;
|
||||
});
|
||||
showErrorToast('${testCases[index].name} failed');
|
||||
}
|
||||
},
|
||||
buttonStyle: const ButtonStyle(),
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
switch (testsStates[index]) {
|
||||
TestState.success => Container(width: 20, height: 20, color: Colors.green),
|
||||
TestState.fail => Container(width: 20, height: 20, color: Colors.red),
|
||||
TestState.notRun => Container(width: 20, height: 20, color: Colors.grey),
|
||||
TestState.loading => const SizedBox(
|
||||
showSuccessToast('${testCases[index].name} passed');
|
||||
} else {
|
||||
setState(() {
|
||||
testsStates[index] = TestState.fail;
|
||||
});
|
||||
showErrorToast('${testCases[index].name} failed');
|
||||
}
|
||||
},
|
||||
buttonStyle: const ButtonStyle(),
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
switch (testsStates[index]) {
|
||||
TestState.success => Container(width: 20, height: 20, color: Colors.green),
|
||||
TestState.fail => Container(width: 20, height: 20, color: Colors.red),
|
||||
TestState.notRun => Container(width: 20, height: 20, color: Colors.grey),
|
||||
TestState.loading => const SizedBox(
|
||||
width: 20,
|
||||
height: 20,
|
||||
child: SizedBox(height: 20, width: 20, child: Center(child: CircularProgressIndicator())),
|
||||
),
|
||||
},
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
},
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
CustomOutlinedButton(
|
||||
text: 'add token to server',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
name: eatvio_app
|
||||
description: A new Flutter project.
|
||||
version: 1.1.7+37
|
||||
version: 1.1.8+38
|
||||
publish_to: 'none'
|
||||
|
||||
environment:
|
||||
@@ -71,6 +71,7 @@ dependencies:
|
||||
package_info_plus: ^8.3.0
|
||||
device_info_plus: ^11.4.0
|
||||
permission_handler: ^12.0.0+1
|
||||
qr_code_scanner_plus: ^2.0.10+1
|
||||
|
||||
dev_dependencies:
|
||||
build_runner: ^2.4.15
|
||||
|
||||
Reference in New Issue
Block a user