| @@ -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 | |||
| @@ -6,4 +6,5 @@ | |||
| !/.packages | |||
| !/.flutter-plugins-dependencies | |||
| !/.flutter-plugins | |||
| .env | |||
| #uncomment the following line if you want to keep your .env file | |||
| #*.env | |||
| @@ -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)) | |||
| } | |||
| } | |||
| @@ -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, | |||
| ); | |||
| } | |||
| } | |||
| } | |||
| @@ -103,7 +103,7 @@ class AbilitaDisabilitaClasseScreen | |||
| textAlign: | |||
| TextAlign | |||
| .right, | |||
| style: AppStyle | |||
| style: AppStyle | |||
| .txtRobotoRomanSemiBold19Lime600)) | |||
| ])) | |||
| ])), | |||
| @@ -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<http.Client> createHttpClient() async { | |||
| final ioc = HttpClient() | |||
| @@ -17,7 +18,10 @@ class CameraPage extends StatelessWidget { | |||
| Future<String> 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, | |||
| ); | |||
| } | |||
| } | |||
| } | |||
| @@ -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<Map<String, String>> fetchStrings() async { | |||
| final response = await http.get(Uri.parse(url)); | |||
| if (response.statusCode == 200) { | |||
| Map<String, dynamic> 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 = <String, String>{}.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); | |||
| } | |||
| } | |||
| } | |||
| @@ -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<LoginScreen> { | |||
| Timer? _recordingTimer; | |||
| List<String> _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<void> 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<String>.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<LoginScreen> { | |||
| 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<LoginScreen> { | |||
| child: Column( | |||
| crossAxisAlignment: CrossAxisAlignment.start, | |||
| children: [ | |||
| DropdownButtonFormField<String>( | |||
| value: null, | |||
| hint: Text(selectDuration), | |||
| icon: Icon(Icons.timer), | |||
| decoration: InputDecoration( | |||
| border: OutlineInputBorder(), | |||
| ), | |||
| items: _defaultTimes.map((String value) { | |||
| return DropdownMenuItem<String>( | |||
| 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<LoginScreen> { | |||
| 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<LoginScreen> { | |||
| 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<LoginScreen> { | |||
| 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<LoginScreen> { | |||
| 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<LoginScreen> { | |||
| ), | |||
| 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<LoginScreen> { | |||
| 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<LoginScreen> { | |||
| 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<LoginScreen> { | |||
| } | |||
| Future<String> 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<LoginScreen> { | |||
| Future<void> sendPostRequestStart(String token, Map<String, dynamic> 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<String> 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<LoginScreen> { | |||
| Future<void> 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<LoginScreen> { | |||
| bool isText(String? value) { | |||
| return value != null && value.isNotEmpty; | |||
| } | |||
| } | |||
| } | |||
| @@ -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, | |||
| ), | |||
| ], | |||
| ), | |||
| ), | |||
| ); | |||
| } | |||
| } | |||
| @@ -58,6 +58,7 @@ class _SplashScreenOneScreenState extends State<SplashScreenOneScreen> with Auto | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| super.build(context); | |||
| return Scaffold( | |||
| body: Stack( | |||
| children: [ | |||
| @@ -35,6 +35,7 @@ flutter: | |||
| - assets/images/lab1.jpg | |||
| - assets/images/lab2.jpg | |||
| - assets/images/lab3.jpg | |||
| - .env | |||
| fonts: | |||
| - family: Roboto | |||
| fonts: | |||