From b7c015e60b1072d9132d7721ef727d5f0c36d398 Mon Sep 17 00:00:00 2001 From: Gedion Daniel Date: Fri, 19 Jul 2024 10:42:11 +0200 Subject: [PATCH] updated --- .env | 7 + .flutter-plugins-dependencies | 2 +- .gitignore | 3 +- kotlin/CalculatorTest.kt | 11 + lib/main.dart | 9 +- .../abilita_disabilita_classe_screen.dart | 2 +- lib/presentation/camera_page/camera_page.dart | 235 +++++++++--------- .../controller/string_controller.dart | 42 ++++ .../login_screen/login_screen.dart | 113 ++++++++- .../login_screen/models/app_strings.dart | 0 .../login_screen/recording_details.dart | 77 ++++++ .../splash_screen_one_screen.dart | 1 + pubspec.yaml | 1 + 13 files changed, 361 insertions(+), 142 deletions(-) create mode 100644 .env create mode 100644 kotlin/CalculatorTest.kt create mode 100644 lib/presentation/login_screen/controller/string_controller.dart create mode 100644 lib/presentation/login_screen/models/app_strings.dart create mode 100644 lib/presentation/login_screen/recording_details.dart diff --git a/.env b/.env new file mode 100644 index 0000000..ed5ccc6 --- /dev/null +++ b/.env @@ -0,0 +1,7 @@ +SERVER_URL=https://192.168.60.230:5050 +USERNAME=admin +PASSWORD=Pwdadmin1! + +IP_CAMERA_BASE_URL=HTTP://10.1.1.66:2000 +IP_CAMERA_USERNAME=admin +IP_CAMERA_PASSWORD=Adminadmin1 \ No newline at end of file diff --git a/.flutter-plugins-dependencies b/.flutter-plugins-dependencies index b52bfee..c4b1498 100644 --- a/.flutter-plugins-dependencies +++ b/.flutter-plugins-dependencies @@ -1 +1 @@ -{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\connectivity_plus-2.3.9\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.3.3+1\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"connectivity_plus","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\connectivity_plus-2.3.9\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_android-2.2.4\\\\","native_build":true,"dependencies":[]},{"name":"shared_preferences_android","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_android-2.2.2\\\\","native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.3.3+1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"connectivity_plus_macos","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\connectivity_plus_macos-1.2.6\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.3.3+1\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"connectivity_plus_linux","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\connectivity_plus_linux-1.3.1\\\\","native_build":false,"dependencies":[]},{"name":"path_provider_linux","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_linux-2.3.2\\\\","native_build":false,"dependencies":["path_provider_linux"]}],"windows":[{"name":"connectivity_plus_windows","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\connectivity_plus_windows-1.2.2\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_windows","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_windows-2.3.2\\\\","native_build":false,"dependencies":["path_provider_windows"]}],"web":[{"name":"connectivity_plus_web","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\connectivity_plus_web-1.2.5\\\\","dependencies":[]},{"name":"shared_preferences_web","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_web-2.3.0\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":["connectivity_plus_linux","connectivity_plus_macos","connectivity_plus_web","connectivity_plus_windows"]},{"name":"connectivity_plus_linux","dependencies":[]},{"name":"connectivity_plus_macos","dependencies":[]},{"name":"connectivity_plus_web","dependencies":[]},{"name":"connectivity_plus_windows","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"sqflite","dependencies":[]}],"date_created":"2024-07-02 09:13:46.706236","version":"3.19.6"} \ No newline at end of file +{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"connectivity_plus","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\connectivity_plus-2.3.9\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.3.3+1\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"android":[{"name":"connectivity_plus","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\connectivity_plus-2.3.9\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_android","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_android-2.2.4\\\\","native_build":true,"dependencies":[]},{"name":"shared_preferences_android","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_android-2.2.2\\\\","native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.3.3+1\\\\","native_build":true,"dependencies":[]}],"macos":[{"name":"connectivity_plus_macos","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\connectivity_plus_macos-1.2.6\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_foundation","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"shared_preferences_foundation","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_foundation-2.4.0\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]},{"name":"sqflite","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\sqflite-2.3.3+1\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[]}],"linux":[{"name":"connectivity_plus_linux","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\connectivity_plus_linux-1.3.1\\\\","native_build":false,"dependencies":[]},{"name":"path_provider_linux","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_linux","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_linux-2.3.2\\\\","native_build":false,"dependencies":["path_provider_linux"]}],"windows":[{"name":"connectivity_plus_windows","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\connectivity_plus_windows-1.2.2\\\\","native_build":true,"dependencies":[]},{"name":"path_provider_windows","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.2.1\\\\","native_build":false,"dependencies":[]},{"name":"shared_preferences_windows","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_windows-2.3.2\\\\","native_build":false,"dependencies":["path_provider_windows"]}],"web":[{"name":"connectivity_plus_web","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\connectivity_plus_web-1.2.5\\\\","dependencies":[]},{"name":"shared_preferences_web","path":"C:\\\\Users\\\\HP\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\shared_preferences_web-2.3.0\\\\","dependencies":[]}]},"dependencyGraph":[{"name":"connectivity_plus","dependencies":["connectivity_plus_linux","connectivity_plus_macos","connectivity_plus_web","connectivity_plus_windows"]},{"name":"connectivity_plus_linux","dependencies":[]},{"name":"connectivity_plus_macos","dependencies":[]},{"name":"connectivity_plus_web","dependencies":[]},{"name":"connectivity_plus_windows","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"sqflite","dependencies":[]}],"date_created":"2024-07-19 09:18:49.141725","version":"3.19.6"} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 7fb5ff4..f8fab3a 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ !/.packages !/.flutter-plugins-dependencies !/.flutter-plugins -.env +#uncomment the following line if you want to keep your .env file +#*.env \ No newline at end of file diff --git a/kotlin/CalculatorTest.kt b/kotlin/CalculatorTest.kt new file mode 100644 index 0000000..345ea6e --- /dev/null +++ b/kotlin/CalculatorTest.kt @@ -0,0 +1,11 @@ +import org.junit.Assert.assertEquals +import org.junit.Test + +class CalculatorTest { + + @Test + fun addition_isCorrect() { + val calculator = Calculator() + assertEquals(4, calculator.add(2, 2)) + } +} \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 93ca2e7..dd7ff00 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -3,11 +3,14 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'core/app_export.dart'; - import 'package:flutter_dotenv/flutter_dotenv.dart'; -void main() { +import 'presentation/login_screen/models/app_strings.dart'; + + +void main() async { WidgetsFlutterBinding.ensureInitialized(); + await dotenv.load(fileName: ".env"); SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, ]).then((value){ @@ -34,4 +37,4 @@ class MyApp extends StatelessWidget { getPages: AppRoutes.pages, ); } -} +} \ No newline at end of file diff --git a/lib/presentation/abilita_disabilita_classe_screen/abilita_disabilita_classe_screen.dart b/lib/presentation/abilita_disabilita_classe_screen/abilita_disabilita_classe_screen.dart index 9edfde7..e963b95 100644 --- a/lib/presentation/abilita_disabilita_classe_screen/abilita_disabilita_classe_screen.dart +++ b/lib/presentation/abilita_disabilita_classe_screen/abilita_disabilita_classe_screen.dart @@ -103,7 +103,7 @@ class AbilitaDisabilitaClasseScreen textAlign: TextAlign .right, - style: AppStyle + style: AppStyle .txtRobotoRomanSemiBold19Lime600)) ])) ])), diff --git a/lib/presentation/camera_page/camera_page.dart b/lib/presentation/camera_page/camera_page.dart index b5cd84d..ffcd227 100644 --- a/lib/presentation/camera_page/camera_page.dart +++ b/lib/presentation/camera_page/camera_page.dart @@ -3,10 +3,11 @@ import 'package:http/http.dart' as http; import 'dart:convert'; import 'dart:io'; import 'package:http/io_client.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; class CameraPage extends StatelessWidget { - final String loginUrl = 'https://192.168.60.230:5050/auth/login'; - final String moveCameraUrl = 'https://192.168.60.230:5050/move-camera'; + final String loginUrl = dotenv.env['SERVER_URL']! + '/auth/login'; + final String moveCameraUrl = dotenv.env['SERVER_URL']! + '/move-camera'; Future createHttpClient() async { final ioc = HttpClient() @@ -17,7 +18,10 @@ class CameraPage extends StatelessWidget { Future loginAndGetToken(http.Client client) async { var url = Uri.parse(loginUrl); - var data = {'username': 'admin', 'password': 'Pwdadmin1!'}; + var data = { + 'username': dotenv.env['USERNAME']!, + 'password': dotenv.env['PASSWORD']!, + }; var body = data.keys .map((key) => @@ -75,167 +79,152 @@ class CameraPage extends StatelessWidget { @override Widget build(BuildContext context) { double screenWidth = MediaQuery.of(context).size.width; + double screenHeight = MediaQuery.of(context).size.height; return Scaffold( body: OrientationBuilder( - builder: (context, orientation) => Stack( - children: [ - Column( - children: [ - Expanded( - child: Builder( - builder: (context) => GestureDetector( + builder: (context, orientation) { + return Stack( + children: [ + Column( + children: [ + Expanded( + child: GestureDetector( onTap: () async { final client = await createHttpClient(); String token = await loginAndGetToken(client); await sendPostRequestMoveCamera(context, token, { - "baseUrl": "HTTP://10.1.1.66:2000", - "username": "admin", - "password": "Adminadmin1", + "baseUrl": dotenv.env['IP_CAMERA_BASE_URL']!, + "username": dotenv.env['IP_CAMERA_USERNAME']!, + "password": dotenv.env['IP_CAMERA_PASSWORD']!, "preset": 1 }); }, - child: Stack( - children: [ - Container( - color: Colors.transparent, - child: Transform.rotate( - angle: 3.14 / 2, - child: Image.asset( - 'assets/images/img1.png', - fit: BoxFit.cover, - ), - ), + child: Container( + color: Colors.transparent, + child: Transform.rotate( + angle: 3.14 / 2, + child: Image.asset( + 'assets/images/img1.png', + fit: BoxFit.cover, ), - ], + ), ), ), ), - ), - Expanded( - child: Builder( - builder: (context) => GestureDetector( + Expanded( + child: GestureDetector( onTap: () async { final client = await createHttpClient(); String token = await loginAndGetToken(client); await sendPostRequestMoveCamera(context, token, { - "baseUrl": "HTTP://10.1.1.66:2000", - "username": "admin", - "password": "Adminadmin1", + "baseUrl": dotenv.env['IP_CAMERA_BASE_URL']!, + "username": dotenv.env['IP_CAMERA_USERNAME']!, + "password": dotenv.env['IP_CAMERA_PASSWORD']!, "preset": 3 }); }, - child: Stack( - children: [ - Container( - color: Colors.transparent, - child: Transform.rotate( - angle: 3.14 / 2, - child: Image.asset( - 'assets/images/img2.png', - fit: BoxFit.cover, - ), - ), + child: Container( + color: Colors.transparent, + child: Transform.rotate( + angle: 3.14 / 2, + child: Image.asset( + 'assets/images/img2.png', + fit: BoxFit.cover, ), - ], + ), ), ), ), - ), - Expanded( - child: Builder( - builder: (context) => GestureDetector( + Expanded( + child: GestureDetector( onTap: () async { final client = await createHttpClient(); String token = await loginAndGetToken(client); await sendPostRequestMoveCamera(context, token, { - "baseUrl": "HTTP://10.1.1.66:2000", - "username": "admin", - "password": "Adminadmin1", + "baseUrl": dotenv.env['IP_CAMERA_BASE_URL']!, + "username": dotenv.env['IP_CAMERA_USERNAME']!, + "password": dotenv.env['IP_CAMERA_PASSWORD']!, "preset": 2 }); }, - child: Stack( - children: [ - Container( - color: Colors.transparent, - child: Transform.rotate( - angle: 3.14 / 2, - child: Image.asset( - 'assets/images/img3.png', - fit: BoxFit.cover, - ), - ), + child: Container( + color: Colors.transparent, + child: Transform.rotate( + angle: 3.14 / 2, + child: Image.asset( + 'assets/images/img3.png', + fit: BoxFit.cover, ), - ], + ), ), ), ), - ), - ], - ), - Positioned( - top: 110.0, - right: 350.0, - child: GestureDetector( - onTap: () async { - final client = await createHttpClient(); - String token = await loginAndGetToken(client); - await sendPostRequestMoveCamera(context, token, { - "baseUrl": "HTTP://10.1.1.66:2000", - "username": "admin", - "password": "Adminadmin1", - "preset": 5 - }); - }, - child: Transform.rotate( - angle: 3.14 / 2, // Rotating 90 degrees (PI / 2 radians) - child: FaceSymbol(), + ], + ), + Positioned( + top: screenHeight * 0.15, + left: screenWidth * 0.05, + child: GestureDetector( + onTap: () async { + final client = await createHttpClient(); + String token = await loginAndGetToken(client); + await sendPostRequestMoveCamera(context, token, { + "baseUrl": dotenv.env['IP_CAMERA_BASE_URL']!, + "username": dotenv.env['IP_CAMERA_USERNAME']!, + "password": dotenv.env['IP_CAMERA_PASSWORD']!, + "preset": 5 + }); + }, + child: Transform.rotate( + angle: 3.14 / 2, // Rotating 90 degrees (PI / 2 radians) + child: FaceSymbol(), + ), ), ), - ), - Positioned( - top: 350.0, - right: 350.0, - child: GestureDetector( - onTap: () async { - final client = await createHttpClient(); - String token = await loginAndGetToken(client); - await sendPostRequestMoveCamera(context, token, { - "baseUrl": "HTTP://10.1.1.66:2000", - "username": "admin", - "password": "Adminadmin1", - "preset": 4 - }); - }, - child: Transform.rotate( - angle: 3.14 / 2, // Rotating 90 degrees (PI / 2 radians) - child: FaceSymbol(), + Positioned( + top: screenHeight * 0.35, + left: screenWidth * 0.05, + child: GestureDetector( + onTap: () async { + final client = await createHttpClient(); + String token = await loginAndGetToken(client); + await sendPostRequestMoveCamera(context, token, { + "baseUrl": dotenv.env['IP_CAMERA_BASE_URL']!, + "username": dotenv.env['IP_CAMERA_USERNAME']!, + "password": dotenv.env['IP_CAMERA_PASSWORD']!, + "preset": 4 + }); + }, + child: Transform.rotate( + angle: 3.14 / 2, // Rotating 90 degrees (PI / 2 radians) + child: FaceSymbol(), + ), ), ), - ), - Positioned( - top: 700.0, - right: 350.0, - child: GestureDetector( - onTap: () async { - final client = await createHttpClient(); - String token = await loginAndGetToken(client); - await sendPostRequestMoveCamera(context, token, { - "baseUrl": "HTTP://10.1.1.66:2000", - "username": "admin", - "password": "Adminadmin1", - "preset": 6 - }); - }, - child: Transform.rotate( - angle: 3.14 / 2, // Rotating 90 degrees (PI / 2 radians) - child: FaceSymbol(), + Positioned( + top: screenHeight * 0.7, + left: screenWidth * 0.05, + child: GestureDetector( + onTap: () async { + final client = await createHttpClient(); + String token = await loginAndGetToken(client); + await sendPostRequestMoveCamera(context, token, { + "baseUrl": dotenv.env['IP_CAMERA_BASE_URL']!, + "username": dotenv.env['IP_CAMERA_USERNAME']!, + "password": dotenv.env['IP_CAMERA_PASSWORD']!, + "preset": 6 + }); + }, + child: Transform.rotate( + angle: 3.14 / 2, // Rotating 90 degrees (PI / 2 radians) + child: FaceSymbol(), + ), ), ), - ), - ], - ), + ], + ); + }, ), ); } @@ -250,4 +239,4 @@ class FaceSymbol extends StatelessWidget { color: Colors.blue, ); } -} +} \ No newline at end of file diff --git a/lib/presentation/login_screen/controller/string_controller.dart b/lib/presentation/login_screen/controller/string_controller.dart new file mode 100644 index 0000000..5136a56 --- /dev/null +++ b/lib/presentation/login_screen/controller/string_controller.dart @@ -0,0 +1,42 @@ +import 'dart:convert'; +import 'package:http/http.dart' as http; +import 'package:get/get.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; + + +class StringService { + final String url = dotenv.env['SERVER_URL']! + 'getStrings'; + + Future> fetchStrings() async { + final response = await http.get(Uri.parse(url)); + + if (response.statusCode == 200) { + Map jsonResponse = json.decode(response.body); + return jsonResponse.map((key, value) => MapEntry(key, value.toString())); + } else { + throw Exception('Failed to load strings'); + } + } +} + + +class StringController extends GetxController { + var strings = {}.obs; + var isLoading = true.obs; + + @override + void onInit() { + fetchStrings(); + super.onInit(); + } + + void fetchStrings() async { + try { + isLoading(true); + var fetchedStrings = await StringService().fetchStrings(); + strings.value = fetchedStrings; + } finally { + isLoading(false); + } + } +} diff --git a/lib/presentation/login_screen/login_screen.dart b/lib/presentation/login_screen/login_screen.dart index dd9c6cd..3270e88 100644 --- a/lib/presentation/login_screen/login_screen.dart +++ b/lib/presentation/login_screen/login_screen.dart @@ -11,6 +11,7 @@ import 'package:http/http.dart' as http; import 'package:michele_s_application8/presentation/camera_page/camera_page.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:shared_preferences/shared_preferences.dart'; class LoginScreen extends StatefulWidget { @override @@ -33,12 +34,69 @@ class _LoginScreenState extends State { Timer? _recordingTimer; + List _defaultTimes = []; + String mainTitle = ''; + String selectDuration = ''; + String enterCustomDuration = ''; + String insertTitle = ''; + String insertPresenterName = ''; + String startRecording = ''; + String recordingDetails = ''; + String goToCamera = ''; + @override void initState() { super.initState(); String deviceLanguage = ui.window.locale.languageCode; String language = (deviceLanguage == 'en') ? 'EN' : (deviceLanguage == 'it') ? 'IT' : 'IT'; _languageController = TextEditingController(text: language); + fetchStringsFromServer(); + } + + Future fetchStringsFromServer() async { + try { + String token = await loginAndGetToken(); // Get the token first + HttpClient httpClient = new HttpClient() + ..badCertificateCallback = + ((X509Certificate cert, String host, int port) => true); + + var request = await httpClient.getUrl(Uri.parse(dotenv.env['SERVER_URL']! + '/get-strings')) + ..headers.add('Authorization', 'Bearer $token'); + var response = await request.close(); + var responseBody = await response.transform(utf8.decoder).join(); + + if (response.statusCode == 200) { + final data = jsonDecode(responseBody); + setState(() { + _defaultTimes = List.from(data['durations']); + selectDuration = data['select_duration']; + enterCustomDuration = data['enter_custom_duration']; + insertTitle = data['insert_title']; + insertPresenterName = data['insert_presenter_name']; + startRecording = data['start_recording']; + recordingDetails = data['recording_details']; + goToCamera = data['go_to_camera']; + mainTitle = data['main_title']; + }); + } else { + print('Failed to load strings with status code: ${response.statusCode}'); + throw Exception('Failed to load strings'); + } + } catch (e) { + print('Error fetching strings: $e'); // Debug: Print error message + setState(() { + isError = true; + _defaultTimes = ["00:05:00", "01:00:00", "01:30:00", "02:00:00"]; + mainTitle = 'CookingLab'; + selectDuration = 'seleziona Durata'; + enterCustomDuration = 'Oppure inserisci una durata personalizzata'; + insertTitle = 'Inserisci il titolo'; + insertPresenterName = 'Inserisci il nome del relatore'; + startRecording = 'Inizia a Registrare'; + recordingDetails = 'Dettagli di registrazione'; + goToCamera = 'Vai a Fotocamera'; + }); + } } @override @@ -68,7 +126,7 @@ class _LoginScreenState extends State { children: [ if (!isRecording || showStartRecordingButton) Text( - 'CookingLab', + mainTitle, style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold), ), if (!isRecording || showStartRecordingButton) @@ -80,6 +138,32 @@ class _LoginScreenState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ + DropdownButtonFormField( + value: null, + hint: Text(selectDuration), + icon: Icon(Icons.timer), + decoration: InputDecoration( + border: OutlineInputBorder(), + ), + items: _defaultTimes.map((String value) { + return DropdownMenuItem( + value: value, + child: Text(value), + ); + }).toList(), + onChanged: (newValue) { + setState(() { + _timeController1.text = newValue!; + }); + }, + validator: (value) { + if (_timeController1.text.isEmpty || !isTime(_timeController1.text)) { + return "Inserisci un'ora valida (HH:MM:SS)"; + } + return null; + }, + ), + SizedBox(height: 12), GestureDetector( onTap: () async { await showDialog( @@ -93,7 +177,7 @@ class _LoginScreenState extends State { onTimerDurationChanged: (Duration duration) { _timeController1.text = "${duration.inHours.toString().padLeft(2, '0')}:${duration.inMinutes.remainder(60).toString().padLeft(2, '0')}:${duration.inSeconds.remainder(60).toString().padLeft(2, '0')}"; }, - initialTimerDuration: Duration(hours: DateTime.now().hour, minutes: DateTime.now().minute, seconds: DateTime.now().second), + initialTimerDuration: Duration(hours: 0, minutes: 0, seconds: 0), ), ), ); @@ -104,7 +188,7 @@ class _LoginScreenState extends State { child: CustomTextFormField( controller: _timeController1, prefixIcon: Icon(Icons.timer), - hintText: "Inserisci la durata", + hintText: enterCustomDuration, decoration: InputDecoration( border: OutlineInputBorder(), ), @@ -121,7 +205,7 @@ class _LoginScreenState extends State { CustomTextFormField( controller: _titleController, prefixIcon: Icon(Icons.title), - hintText: "Inserisci il titolo", + hintText: insertTitle, margin: EdgeInsets.fromLTRB(5, 12, 10, 0), validator: (value) { if (value != null && !isText(value)) { @@ -133,7 +217,7 @@ class _LoginScreenState extends State { CustomTextFormField( controller: _presenterNameController, prefixIcon: Icon(Icons.person), - hintText: "Inserisci il nome del relatore", + hintText: insertPresenterName, margin: EdgeInsets.fromLTRB(5, 12, 10, 0), validator: (value) { if (value != null && !isText(value)) { @@ -148,7 +232,7 @@ class _LoginScreenState extends State { ), if (!isRecording || showStartRecordingButton) CustomButton( - text: "Inizia a Registrare", + text: startRecording, margin: EdgeInsets.fromLTRB(50, 30, 50, 10), variant: ButtonVariant.OutlineBlack9003f, padding: ButtonPadding.PaddingAll9, @@ -224,7 +308,7 @@ class _LoginScreenState extends State { child: Column( children: [ Text( - 'Dettagli di registrazione', + recordingDetails, style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold, color: Colors.black), ), SizedBox(height: 10), @@ -284,7 +368,7 @@ class _LoginScreenState extends State { child: isLoading ? SizedBox() // Hide the button when isLoading is true : CustomButton( - text: "Vai a Fotocamera", + text: goToCamera, // prefixIcon: Icon(Icons.camera_alt), margin: EdgeInsets.symmetric(horizontal: 50, vertical: 30), variant: ButtonVariant.OutlineBlack9003f, @@ -310,8 +394,11 @@ class _LoginScreenState extends State { } Future loginAndGetToken() async { - var url = Uri.parse('https://192.168.60.230:5050/auth/login'); - var data = {'username': 'admin', 'password': 'Pwdadmin1!'}; + var url = Uri.parse(dotenv.env['SERVER_URL']! + '/auth/login'); + var data = { + 'username': dotenv.env['USERNAME']!, + 'password': dotenv.env['PASSWORD']!, + }; var body = data.keys.map((key) => "${Uri.encodeComponent(key)}=${Uri.encodeComponent(data[key] ?? '')}").join("&"); @@ -337,7 +424,7 @@ class _LoginScreenState extends State { Future sendPostRequestStart(String token, Map data, String time, String camNumber) async { - var url = Uri.parse('https://192.168.60.230:5050/start-recording'); + var url = Uri.parse(dotenv.env['SERVER_URL']! + '/start-recording'); List timeParts = time.split(':'); int durationInSeconds = int.parse(timeParts[0]) * 3600 + int.parse(timeParts[1]) * 60 + int.parse(timeParts[2]); durationInSeconds += 10; @@ -385,7 +472,7 @@ class _LoginScreenState extends State { Future sendPostRequestStop(String token, String camNumber) async { - var url = Uri.parse('https://192.168.60.230:5050/stop-recording'); + var url = Uri.parse(dotenv.env['SERVER_URL']! + '/stop-recording'); var requestData = { "camera_name": int.parse(camNumber), @@ -443,4 +530,4 @@ class _LoginScreenState extends State { bool isText(String? value) { return value != null && value.isNotEmpty; } -} +} \ No newline at end of file diff --git a/lib/presentation/login_screen/models/app_strings.dart b/lib/presentation/login_screen/models/app_strings.dart new file mode 100644 index 0000000..e69de29 diff --git a/lib/presentation/login_screen/recording_details.dart b/lib/presentation/login_screen/recording_details.dart new file mode 100644 index 0000000..1e1b26a --- /dev/null +++ b/lib/presentation/login_screen/recording_details.dart @@ -0,0 +1,77 @@ +// recording_details.dart +import 'package:flutter/material.dart'; +import 'package:michele_s_application8/widgets/custom_button.dart'; + +class RecordingDetails extends StatelessWidget { + final String recordingDetails; + final String duration; + final String title; + final String presenterName; + final VoidCallback onStop; + + RecordingDetails({ + required this.recordingDetails, + required this.duration, + required this.title, + required this.presenterName, + required this.onStop, + }); + + @override + Widget build(BuildContext context) { + return Expanded( + child: Center( + child: Column( + mainAxisSize: MainAxisSize.min, // Minimize the column size to its content + children: [ + Container( + padding: EdgeInsets.all(40), // Increase the padding to increase the size of the Container + decoration: BoxDecoration( + color: Colors.white, // Change this to your preferred color + borderRadius: BorderRadius.circular(15), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 5, + blurRadius: 7, + offset: Offset(0, 3), // changes position of shadow + ), + ], + ), + child: Column( + children: [ + Text( + recordingDetails, + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold, color: Colors.black), + ), + SizedBox(height: 10), + Text( + 'Durata: $duration', + style: TextStyle(fontSize: 20, color: Colors.black), + ), + SizedBox(height: 10), + Text( + 'Titolo: $title', + style: TextStyle(fontSize: 20, color: Colors.black), + ), + SizedBox(height: 10), + Text( + 'Nome del relatore: $presenterName', + style: TextStyle(fontSize: 20, color: Colors.black), + ), + ], + ), + ), + CustomButton( + text: "Interrompi la registrazione", + margin: EdgeInsets.fromLTRB(80, 10, 80, 10), + variant: ButtonVariant.OutlineBlack9003f, + padding: ButtonPadding.PaddingAll15, + onTap: onStop, + ), + ], + ), + ), + ); + } +} diff --git a/lib/presentation/splash_screen_one_screen/splash_screen_one_screen.dart b/lib/presentation/splash_screen_one_screen/splash_screen_one_screen.dart index 7e3cff7..2f31f2d 100644 --- a/lib/presentation/splash_screen_one_screen/splash_screen_one_screen.dart +++ b/lib/presentation/splash_screen_one_screen/splash_screen_one_screen.dart @@ -58,6 +58,7 @@ class _SplashScreenOneScreenState extends State with Auto @override Widget build(BuildContext context) { + super.build(context); return Scaffold( body: Stack( children: [ diff --git a/pubspec.yaml b/pubspec.yaml index 4fc15ff..19ea1cc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -35,6 +35,7 @@ flutter: - assets/images/lab1.jpg - assets/images/lab2.jpg - assets/images/lab3.jpg + - .env fonts: - family: Roboto fonts: