docs(project): added docstrings to all code files

This commit is contained in:
Patryk Hegenberg 2024-05-29 23:55:47 +02:00
parent 47acdec22a
commit 0d354efb8e
24 changed files with 1826 additions and 107 deletions

View file

@ -8,92 +8,161 @@ import 'package:flutter_test_gui/pages/send_screen.dart';
import 'package:flutter_test_gui/pages/receive_screen.dart';
import 'package:flutter_test_gui/consts/consts.dart';
/// Main entrypoint of the application.
///
/// This function is called when the application starts. It initializes the
/// Rust library, sets up the application widget, and shows the window.
///
/// The function first calls the [RustLib.init] function to initialize the
/// Rust library. Then, it runs the application using the [runApp] function
/// with the [MyApp] widget. If the application is running on Windows, Linux,
/// or macOS, it sets up the window properties such as the minimum size,
/// initial size, alignment, and title. Finally, it shows the window.
Future<void> main() async {
// Initialize the Rust library
await RustLib.init();
// Set up the application widget
runApp(const MyApp());
// Set up the window properties if running on Windows, Linux, or macOS
if (Platform.isWindows || Platform.isLinux || Platform.isMacOS) {
doWhenWindowReady(() {
final win = appWindow;
// Set the minimum size of the window
const initialSize = Size(720, 512);
win.minSize = initialSize;
// Set the initial size of the window
win.size = initialSize;
// Set the alignment of the window
win.alignment = Alignment.center;
// Set the title of the window
win.title = 'Caesar Test Demo';
// Show the window
win.show();
});
}
}
// const backColor = Color(0xFF32363E);
// const highlightColor = Color(0xFF98C379);
// const textColor = Color(0xFFABB2BF);
/// The root widget of the application.
///
/// It sets up the material design theme and provides the home page.
class MyApp extends StatefulWidget {
/// Creates a new instance of [MyApp].
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
/// The state for the [MyApp] widget.
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
// Set up the material design theme.
return MaterialApp(
title: 'Caesar-Transfer',
theme: ThemeData(
useMaterial3: true,
),
home: const MyHomePage(title: 'Caesar-Transfer'),
// Set the home page.
home: const MyHomePage(
title: 'Caesar-Transfer',
),
);
}
}
/// The root widget of the application that represents the home page.
///
/// It sets up the material design theme and provides the home page.
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
/// Creates a new instance of [MyHomePage].
///
/// The [title] argument is the title of the home page.
const MyHomePage({
super.key,
required this.title,
});
/// The title of the home page.
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
/// The state for the [MyHomePage] widget.
class _MyHomePageState extends State<MyHomePage> {
/// The list of screens that can be displayed on the home page.
final List<Widget> _screens = [
SendScreen(),
ReceiveScreen(),
];
/// The index of the currently selected screen.
int _selectedIndex = 0;
/// Handles the tap event on a tab.
///
/// Updates the selected index and rebuilds the widget tree.
///
/// The [index] argument is the index of the selected tab.
void _onItemTapped(int index) {
setState(() {
_selectedIndex = index;
});
}
/// Builds the user interface for the home page.
///
/// It creates a [MaterialApp] widget with a [Scaffold] as the home page.
/// The [Scaffold] includes an [AppBar], [BottomNavigationBar], and a [Body].
/// The [AppBar] displays the title of the app and a [PopupMenuButton] for
/// accessing the settings screen. The [BottomNavigationBar] displays icons
/// for the send and receive screens and allows the user to select one of them.
/// The [Body] displays the currently selected screen.
///
/// Returns a [Widget] that represents the user interface for the home page.
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
// Sets the background color of the scaffold.
backgroundColor: Constants.backColor,
appBar: AppBar(
// Sets the background color of the app bar.
backgroundColor: const Color(0xFF292c3c), //0xFF282C34),
centerTitle: true,
// Sets the title of the app bar.
title: Text(
widget.title,
// Sets the style of the title text.
style: const TextStyle(color: Constants.textColor),
),
// Sets the action buttons for the app bar.
actions: [
PopupMenuButton<String>(
// Sets the action to perform when a menu item is selected.
onSelected: (String result) {
if (result == 'Settings') {
// Navigates to the settings screen when the 'Settings' menu item is selected.
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SettingsScreen()),
);
}
},
// Sets the items to display in the popup menu.
itemBuilder: (BuildContext context) => <PopupMenuEntry<String>>[
const PopupMenuItem<String>(
// Sets the value and label of a menu item.
value: 'Settings',
child: Text('Settings'),
)
@ -101,11 +170,16 @@ class _MyHomePageState extends State<MyHomePage> {
),
],
),
// Sets the body of the scaffold.
body: _screens[_selectedIndex],
// Sets the bottom navigation bar.
bottomNavigationBar: BottomNavigationBar(
// Sets the background color of the bottom navigation bar.
backgroundColor: const Color(0xFF292c3c), //0xFF282C34),
// Sets the items to display in the bottom navigation bar.
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(
// Sets the icon and label of a bottom navigation bar item.
icon: Icon(Icons.send),
label: 'Send',
),
@ -114,9 +188,11 @@ class _MyHomePageState extends State<MyHomePage> {
label: 'Receive',
),
],
// Sets the currently selected item in the bottom navigation bar.
currentIndex: _selectedIndex,
selectedItemColor: Constants.highlightColor,
unselectedItemColor: Constants.textColor,
// Sets the action to perform when an item is tapped.
onTap: _onItemTapped,
),
),

View file

@ -11,28 +11,52 @@ import 'package:shared_preferences/shared_preferences.dart';
// import 'package:flutter_test_gui/src/rust/frb_generated.dart';
import 'package:flutter_test_gui/consts/consts.dart';
/// Screen for receiving files.
///
/// This screen is used to accept incoming file transfers. It displays a QR
/// code scanner on supported platforms and allows the user to enter a
/// connection link manually.
class ReceiveScreen extends StatefulWidget {
/// Creates a new instance of the receive screen.
const ReceiveScreen({super.key});
@override
ReceiveScreenState createState() => ReceiveScreenState();
}
/// State for the receive screen.
class ReceiveScreenState extends State<ReceiveScreen> {
/// The URL of the app that initiated the transfer.
String appOrigin = '';
/// Text editing controller for the connection link input.
final myController = TextEditingController();
/// The current input value of the connection link input.
String inputValue = '';
/// Whether to show the QR code scanner.
bool _showScanner = false;
/// Builds the QR code scanner widget.
///
/// If the platform is iOS or Android, a QR code scanner is displayed. If the
/// platform is not supported, an empty box is returned.
///
/// Returns a QR code scanner widget if the platform is supported, otherwise an
/// empty box.
Widget _buildQRScanner() {
// Check if the platform is iOS or Android
if (Platform.isIOS || Platform.isAndroid) {
return MobileScanner(
controller: MobileScannerController(
detectionSpeed: DetectionSpeed.noDuplicates),
onDetect: (barcode) {
// Check if the scanner failed to scan a QR code
if (barcode.raw == null) {
debugPrint('Failed to scan qr code');
} else {
// Set the input value to the scanned code
final String code = barcode.barcodes.first.displayValue.toString();
print(code);
setState(() {
@ -43,25 +67,49 @@ class ReceiveScreenState extends State<ReceiveScreen> {
},
);
} else {
// If the platform is not supported, hide the scanner
_showScanner = false;
return const SizedBox.shrink();
}
}
/// Loads the app origin from the shared preferences.
///
/// If the app origin is not present in the shared preferences, it sets the
/// default value to 'wss://caesar-transfer-iu.shuttleapp.rs'.
///
/// Returns a [Future] that completes with no value.
Future<void> loadSettings() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
appOrigin = prefs.getString('app_origin') ??
'wss://caesar-transfer-iu.shuttleapp.rs'; // Laden Sie die app_origin
'wss://caesar-transfer-iu.shuttleapp.rs'; // Load the app origin
}
/// Requests permission for a given [permission].
///
/// If the permission is already granted, it returns true. If the permission
/// is not granted, it requests the permission and returns true if the user
/// grants the permission, otherwise it returns false.
///
/// Returns a [Future] that completes with a [bool] value indicating whether
/// the permission was granted or not.
Future<bool> _requestPermission(Permission permission) async {
// Print the function name
print("In _requestPermission");
// Check if the permission is already granted
if (await permission.isGranted) {
// Print the message
print("Granted");
return true;
} else {
// Print the message
print("Else Zweig");
// Request the permission
final result = await permission.request();
// Check if the permission is granted
if (result == PermissionStatus.granted) {
return true;
} else {
@ -70,25 +118,49 @@ class ReceiveScreenState extends State<ReceiveScreen> {
}
}
/// Starts a transfer by getting the directory path from the user and navigating
/// to the [TransferScreen] with the given [input] and [filePath].
///
/// The [input] is the value of the input field. If it is not empty, it gets the
/// directory path from the user using the [FilePicker.platform.getDirectoryPath]
/// method. If the user chooses a directory, it sets the [filePath] to the
/// selected directory path. If the user doesn't choose a directory, it prints
/// a message indicating that the user didn't choose a directory.
///
/// If the platform is Android, it checks if the external storage permission is
/// granted. If it is not granted, it requests the permission and navigates to
/// the [TransferScreen] with the given [input] and [filePath]. If the permission
/// is granted, it navigates to the [MyHomePage] with the title 'Caesar Transfer'.
///
/// If the platform is not Android, it navigates to the [TransferScreen] with the
/// given [input] and [filePath].
///
/// Returns a [Future] that completes with no value.
Future<void> _startTransfer(String appOrigin) async {
final input = inputValue.trim();
String filePath = '';
if (input.isNotEmpty) {
// Get the directory path from the user
String? selectDirectory = await FilePicker.platform.getDirectoryPath();
if (selectDirectory == null) {
print("User doesnt choose a directory");
// Print a message indicating that the user didn't choose a directory
print("User doesn't choose a directory");
} else {
print("user choose: $selectDirectory");
// Set the filePath to the selected directory path
print("User chose: $selectDirectory");
filePath = selectDirectory;
}
if (Platform.isAndroid) {
// Check if the external storage permission is granted
if (await _requestPermission(Permission.manageExternalStorage)) {
// Navigate to the TransferScreen
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => TransferScreen(
transferName: input, directory: filePath)));
} else {
// Navigate to the MyHomePage with the title 'Caesar Transfer'
Navigator.push(
context,
MaterialPageRoute(
@ -96,6 +168,7 @@ class ReceiveScreenState extends State<ReceiveScreen> {
const MyHomePage(title: 'Caesar Transfer')));
}
} else {
// Navigate to the TransferScreen
Navigator.push(
context,
MaterialPageRoute(
@ -105,6 +178,12 @@ class ReceiveScreenState extends State<ReceiveScreen> {
}
}
/// Builds the scaffold for the receive screen.
///
/// The scaffold contains a center widget that contains a column of widgets.
/// The column contains a QR code scanner if [_showScanner] is true, otherwise
/// it contains a text field for entering the transfer name. Below the text
/// field is an elevated button for initiating the receive process.
@override
Widget build(BuildContext context) {
return Scaffold(
@ -113,6 +192,8 @@ class ReceiveScreenState extends State<ReceiveScreen> {
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// If _showScanner is false, display a QR code icon that can be tapped
// to start the QR code scanner.
if (!_showScanner)
GestureDetector(
onTap: () {
@ -138,6 +219,7 @@ class ReceiveScreenState extends State<ReceiveScreen> {
),
),
),
// If _showScanner is true, display the QR code scanner.
if (_showScanner)
Container(
width: MediaQuery.of(context).size.width * 0.8,
@ -148,7 +230,9 @@ class ReceiveScreenState extends State<ReceiveScreen> {
),
child: _buildQRScanner(),
),
// Add some spacing between the scanner and the text field.
const SizedBox(height: 32),
// Display a text field for entering the transfer name.
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16),
child: SizedBox(
@ -179,7 +263,9 @@ class ReceiveScreenState extends State<ReceiveScreen> {
),
),
),
// Add some spacing between the text field and the receive button.
const SizedBox(height: 16),
// Display an elevated button for initiating the receive process.
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Constants.textColor,

View file

@ -9,20 +9,45 @@ import 'package:flutter_test_gui/src/rust/api/simple.dart';
// import 'package:flutter_test_gui/src/rust/frb_generated.dart';
import 'package:flutter_test_gui/consts/consts.dart';
/// Represents the screen for sending files.
///
/// This is a [StatefulWidget] that displays a screen for sending files.
/// It allows the user to select files to send and provides a name for the transfer.
/// The selected files are stored in a list and can be accessed by the [SendScreenState].
///
/// See also:
/// - [SendScreenState]
class SendScreen extends StatefulWidget {
/// Creates a [SendScreen].
///
/// The [key] parameter is used to identify the [SendScreen] widget.
const SendScreen({super.key});
/// Creates a [SendScreenState] to control the [SendScreen].
///
/// This method is called when a [SendScreen] widget is created.
/// It returns a new instance of [SendScreenState].
@override
SendScreenState createState() => SendScreenState();
}
class SendScreenState extends State<SendScreen> {
/// List of selected files to send.
final List<XFile> _list = [];
/// Name of the transfer.
String transferName = '';
/// Indicates whether the user is currently dragging files.
bool _dragging = false;
/// Opens the file picker and adds the selected files to [_list].
///
/// See also:
/// - [FilePicker.platform.pickFiles]
Future<void> openFilePicker() async {
FilePickerResult? result = await FilePicker.platform.pickFiles(
allowMultiple: true, // Erlaube die Auswahl mehrerer Dateien
allowMultiple: true, // Allow selecting multiple files
);
if (result != null) {
@ -30,9 +55,15 @@ class SendScreenState extends State<SendScreen> {
}
}
/// Generates a random name for the transfer and navigates to the waiting screen.
///
/// See also:
/// - [generateRandomName]
/// - [WaitingScreen]
Future<void> _startTransfer() async {
final randomName = generateRandomName(); // Rust-Funktion aufrufen
print('Zusammengefügter Text: $randomName');
final randomName =
generateRandomName(); // Call Rust function to generate random name
print('Generated transfer name: $randomName');
setState(() {
transferName = randomName;
});
@ -43,42 +74,61 @@ class SendScreenState extends State<SendScreen> {
WaitingScreen(transferName: transferName, files: _list)));
}
/// Builds the UI for the send screen.
///
/// Returns a [Scaffold] widget that contains a [Column] with two children:
/// - A [Center] widget that contains a [Stack] with a [GestureDetector] that
/// handles file picking and dragging.
/// - An [ElevatedButton] that triggers the transfer when pressed.
@override
Widget build(BuildContext context) {
return Scaffold(
// Set the background color of the scaffold.
backgroundColor: Constants.backColor,
// Build the body of the scaffold.
body: Column(
// Align the children vertically to the center.
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Build the file picking and dragging UI.
Center(
child: Stack(
children: [
// Build the gesture detector.
GestureDetector(
// Handle file picking when the user taps.
onTap: openFilePicker,
// Handle file dragging.
child: DropTarget(
// Add the selected files to the list when the user drops files.
onDragDone: (detail) {
setState(() {
_list.addAll(detail.files);
});
},
// Show the add icon when the user drags files over the drop area.
onDragEntered: (detail) {
setState(() {
_dragging = true;
});
},
// Hide the add icon when the user stops dragging files.
onDragExited: (detail) {
setState(() {
_dragging = false;
});
},
// Build the drop area UI.
child: Column(
children: [
// Build the circular container for the drop area.
Container(
height: 200,
width: 200,
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: Constants.textColor),
// Show the add icon when the user is dragging files.
child: _dragging
? const Center(
child: Icon(
@ -87,6 +137,7 @@ class SendScreenState extends State<SendScreen> {
size: 200,
),
)
// Show the upload icon when the user is not dragging files.
: const Center(
child: Icon(
Icons.upload_rounded,
@ -95,6 +146,7 @@ class SendScreenState extends State<SendScreen> {
),
),
),
// Add some spacing between the drop area and the send button.
const SizedBox(height: 16),
],
),
@ -103,17 +155,23 @@ class SendScreenState extends State<SendScreen> {
],
),
),
// Build the send button.
ElevatedButton(
style: ElevatedButton.styleFrom(
// Set the background color of the button.
backgroundColor: Constants.textColor,
// Set the text color of the button.
foregroundColor: Constants.backColor,
// Set the shape of the button.
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
),
// Trigger the transfer when the user presses the button.
onPressed: () {
_startTransfer();
},
// Set the text of the button.
child: const Text("Send"),
),
],

View file

@ -2,12 +2,26 @@ import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_test_gui/consts/consts.dart';
/// Screen for displaying and editing the app's settings.
///
/// This screen allows the user to view and edit the app's settings.
/// The settings include the app environment, host, port, origin, and relay.
/// The settings are stored in SharedPreferences.
class SettingsScreen extends StatefulWidget {
/// Constructs a [SettingsScreen].
const SettingsScreen({Key? key}) : super(key: key);
@override
_SettingsScreenState createState() => _SettingsScreenState();
}
/// State for the [SettingsScreen].
///
/// This state manages the text editing controllers for the app's settings.
/// It also loads the settings from SharedPreferences when the widget is
/// first created.
class _SettingsScreenState extends State<SettingsScreen> {
// Controllers for the text fields.
final TextEditingController _appEnvironmentController =
TextEditingController();
final TextEditingController _appHostController = TextEditingController();
@ -15,21 +29,31 @@ class _SettingsScreenState extends State<SettingsScreen> {
final TextEditingController _appOriginController = TextEditingController();
final TextEditingController _appRelayController = TextEditingController();
/// Loads the app settings from SharedPreferences when the widget is created.
@override
void initState() {
super.initState();
loadSettings();
}
/// Loads the app settings from SharedPreferences.
///
/// This function retrieves the app settings from SharedPreferences and
/// sets the text of the corresponding text editing controllers.
/// If any of the settings are not found in SharedPreferences, an empty
/// string is used instead.
Future<void> loadSettings() async {
// Retrieve the SharedPreferences instance
SharedPreferences prefs = await SharedPreferences.getInstance();
// Retrieve the app settings from SharedPreferences
String appEnvironment = prefs.getString('app_environment') ?? '';
String appHost = prefs.getString('app_host') ?? '';
String appPort = prefs.getString('app_port') ?? '';
String appOrigin = prefs.getString('app_origin') ?? '';
String appRelay = prefs.getString('app_relay') ?? '';
// Setzen Sie die Controller-Texte nach dem Laden der Einstellungen
// Set the text of the corresponding text editing controllers
setState(() {
_appEnvironmentController.text = appEnvironment;
_appHostController.text = appHost;
@ -39,28 +63,49 @@ class _SettingsScreenState extends State<SettingsScreen> {
});
}
/// Saves the app settings to SharedPreferences.
///
/// This function retrieves the text from the corresponding text editing controllers
/// and saves them to SharedPreferences.
/// If any of the settings are empty, it saves an empty string.
Future<void> saveSettings() async {
// Retrieve the SharedPreferences instance
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString('app_environment', _appEnvironmentController.text);
await prefs.setString('app_host', _appHostController.text);
await prefs.setString('app_port', _appPortController.text);
await prefs.setString('app_origin', _appOriginController.text);
await prefs.setString('app_relay', _appRelayController.text);
// Retrieve the text from the corresponding text editing controllers
String appEnvironment = _appEnvironmentController.text;
String appHost = _appHostController.text;
String appPort = _appPortController.text;
String appOrigin = _appOriginController.text;
String appRelay = _appRelayController.text;
// Save the app settings to SharedPreferences
await prefs.setString('app_environment', appEnvironment);
await prefs.setString('app_host', appHost);
await prefs.setString('app_port', appPort);
await prefs.setString('app_origin', appOrigin);
await prefs.setString('app_relay', appRelay);
}
@override
Widget build(BuildContext context) {
return Scaffold(
// Set the background color of the Scaffold
backgroundColor: Constants.backColor,
appBar: AppBar(
// Set the title of the AppBar
title: const Text('Settings'),
// Set the background color of the AppBar
backgroundColor: const Color(0xFF292c3c), //0xFF282C34),
// Set the foreground color of the AppBar
foregroundColor: Constants.textColor,
),
body: Padding(
// Set the padding around the body of the Scaffold
padding: const EdgeInsets.all(16.0),
child: Column(
children: [
// Create a TextField for the 'App Environment' setting
TextField(
controller: _appEnvironmentController,
decoration: const InputDecoration(
@ -68,6 +113,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
labelStyle: TextStyle(color: Constants.highlightColor)),
style: const TextStyle(color: Constants.textColor),
),
// Create a TextField for the 'App Host' setting
TextField(
controller: _appHostController,
decoration: const InputDecoration(
@ -75,6 +121,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
labelStyle: TextStyle(color: Constants.highlightColor)),
style: const TextStyle(color: Constants.textColor),
),
// Create a TextField for the 'App Port' setting
TextField(
controller: _appPortController,
decoration: const InputDecoration(
@ -82,6 +129,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
labelStyle: TextStyle(color: Constants.highlightColor)),
style: const TextStyle(color: Constants.textColor),
),
// Create a TextField for the 'App Origin' setting
TextField(
controller: _appOriginController,
decoration: const InputDecoration(
@ -89,6 +137,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
labelStyle: TextStyle(color: Constants.highlightColor)),
style: const TextStyle(color: Constants.textColor),
),
// Create a TextField for the 'App Relay' setting
TextField(
controller: _appRelayController,
decoration: const InputDecoration(
@ -97,6 +146,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
style: const TextStyle(color: Constants.textColor),
),
Spacer(),
// Create an ElevatedButton to save the settings and return to the previous screen
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Constants.textColor,

View file

@ -2,18 +2,30 @@ import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_test_gui/main.dart';
import 'package:qr_flutter/qr_flutter.dart';
import 'package:cross_file/cross_file.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:flutter_test_gui/src/rust/api/simple.dart';
// import 'package:flutter_test_gui/src/rust/frb_generated.dart';
import 'package:flutter_test_gui/consts/consts.dart';
import 'package:permission_handler/permission_handler.dart';
/// Represents the screen for transferring files.
///
/// This is a [StatefulWidget] that displays a screen for transferring files.
/// It takes in two parameters:
/// - [transferName]: The name of the transfer.
/// - [directory]: The directory containing the files to be transferred.
class TransferScreen extends StatefulWidget {
// The name of the transfer.
final String transferName;
// The directory containing the files to be transferred.
final String directory;
/// Creates a [TransferScreen] widget.
///
/// The [transferName] and [directory] parameters are required.
///
/// The [key] parameter is optional.
const TransferScreen(
{Key? key, required this.transferName, required this.directory})
: super(key: key);
@ -23,57 +35,92 @@ class TransferScreen extends StatefulWidget {
}
class TransferScreenState extends State<TransferScreen> {
// The origin of the application.
String appOrigin = '';
// The input value of the transfer name.
String inputValue = '';
@override
void initState() {
// Call the loadSettings function to load the settings.
super.initState();
loadSettings().then((_) => callStartReceiver(appOrigin));
}
/// Loads the settings from the SharedPreferences.
///
/// It retrieves the value of 'app_origin' from the SharedPreferences and
/// assigns it to the [appOrigin] variable. If the value is not present, it
/// assigns a default value of 'wss://caesar-transfer-iu.shuttleapp.rs'.
Future<void> loadSettings() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
appOrigin = prefs.getString('app_origin') ??
'wss://caesar-transfer-iu.shuttleapp.rs';
}
/// Calls the start transfer function with the given [appOrigin].
///
/// It calls the _startTransfer function with the [appOrigin] parameter.
Future<void> callStartReceiver(String appOrigin) async {
_startTransfer(appOrigin);
}
/// Starts the transfer with the given [appOrigin].
///
/// If the transfer name is not empty, it checks if the platform is Android.
/// If it is, it requests the ManageExternalStorage permission. If the
/// permission is granted, it starts the receiver using the startRustReceiver
/// function. If the permission is not granted, it navigates to the
/// MyHomePage. If the platform is not Android, it starts the receiver
/// directly. If the transfer name is empty, it does not start the receiver.
///
/// Parameters:
/// - appOrigin: The origin of the application.
Future<void> _startTransfer(String appOrigin) async {
// Get the input value from the widget.
final input = widget.transferName;
String filePath = widget.directory;
// If the input value is not empty, start the transfer.
if (input.isNotEmpty) {
if (Platform.isAndroid) {
if (await _requestPermission(Permission.manageExternalStorage)) {
try {
final outcome = await startRustReceiver(
filepath: filePath, transfername: input, relay: appOrigin);
print('Ergebnis von Rust: $outcome');
} catch (e) {
print('Fehler beim Starten des Receivers: $e');
}
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const MyHomePage(title: 'Caesar Transfer')));
} else {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const MyHomePage(title: 'Caesar Transfer')));
// Check if the ManageExternalStorage permission is granted.
//if (await _requestPermission(Permission.manageExternalStorage)) {
try {
// Start the receiver with the given parameters.
final outcome = await startRustReceiver(
filepath: filePath, transfername: input, relay: appOrigin);
print('Ergebnis von Rust: $outcome');
} catch (e) {
// If an error occurs, print the error message.
print('Fehler beim Starten des Receivers: $e');
}
// Navigate to the MyHomePage.
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
const MyHomePage(title: 'Caesar Transfer')));
//} else {
// // If the permission is not granted, navigate to the MyHomePage.
// Navigator.push(
// context,
// MaterialPageRoute(
// builder: (context) =>
// const MyHomePage(title: 'Caesar Transfer')));
//}
} else {
// If the platform is not Android, start the receiver directly.
try {
final outcome = await startRustReceiver(
filepath: filePath, transfername: input, relay: appOrigin);
print('Ergebnis von Rust: $outcome');
} catch (e) {
// If an error occurs, print the error message.
print('Fehler beim Starten des Receivers: $e');
}
// Navigate to the MyHomePage.
Navigator.push(
context,
MaterialPageRoute(
@ -81,36 +128,74 @@ class TransferScreenState extends State<TransferScreen> {
const MyHomePage(title: 'Caesar Transfer')));
}
}
// Print the app origin.
print("Transfer startet with app_origin: $appOrigin");
}
/// Requests the given [permission] and returns a `Future` of `bool` indicating
/// whether the permission is granted.
///
/// If the permission is already granted, it returns `true`. If the permission
/// is not granted, it requests the permission and returns `true` if the
/// permission is granted successfully, otherwise it returns `false`.
///
/// Parameters:
/// - permission: The permission to be requested.
///
/// Returns:
/// A `Future` of `bool` indicating whether the permission is granted.
Future<bool> _requestPermission(Permission permission) async {
// If the permission is already granted, return true.
if (await permission.isGranted) {
return true;
} else {
// Request the permission and get the result.
var result = await permission.request();
if (result == PermissionStatus.granted) {
return true;
} else {
return false;
}
// If the permission is granted, return true. Otherwise, return false.
return result == PermissionStatus.granted;
}
}
@override
/// Builds the widget tree for the TransferScreen.
///
/// This method builds a widget tree for the TransferScreen. It returns a
/// Scaffold widget with a background color set to Constants.backColor. The
/// body of the scaffold is a Center widget that contains a Column widget.
/// The Column widget has its mainAxisAlignment set to MainAxisAlignment.center.
/// It contains three children: a Text widget displaying the transferName, a
/// Text widget with the text "Transfer in Progress", and a SizedBox widget
/// with a height of 32. The SizedBox widget is followed by a Center widget
/// that contains an Icon widget with the icon Icons.cloud_download_rounded,
/// its color set to Constants.highlightColor, and its size set to 200.
///
/// Returns:
/// The widget tree for the TransferScreen.
Widget build(BuildContext context) {
return Scaffold(
// Set the background color of the Scaffold widget.
backgroundColor: Constants.backColor,
body: Center(
// The body of the Scaffold widget.
child: Column(
// The Column widget has its mainAxisAlignment set to
// MainAxisAlignment.center.
mainAxisAlignment: MainAxisAlignment.center,
children: [
// A Text widget displaying the transferName.
Text(
widget.transferName,
style: const TextStyle(color: Colors.white, fontSize: 24),
style: const TextStyle(
color: Colors.white,
fontSize: 24,
),
),
// A Text widget with the text "Transfer in Progress".
Text("Transfer in Progress"),
// A SizedBox widget with a height of 32.
const SizedBox(height: 32),
// A Center widget containing an Icon widget.
const Center(
child: Icon(
Icons.cloud_download_rounded,

View file

@ -8,63 +8,135 @@ import 'package:flutter_test_gui/src/rust/api/simple.dart';
// import 'package:flutter_test_gui/src/rust/frb_generated.dart';
import 'package:flutter_test_gui/consts/consts.dart';
/// Represents the screen for displaying the waiting state.
///
/// This is a [StatefulWidget] that displays a screen for the waiting state.
/// It takes in two parameters:
/// - [transferName]: The name of the transfer.
/// - [files]: The list of files being transferred.
class WaitingScreen extends StatefulWidget {
// The list of files being transferred.
final List<XFile> files;
// The name of the transfer.
final String transferName;
/// Creates a new instance of the [WaitingScreen] widget.
///
/// The [transferName] parameter is the name of the transfer.
/// The [files] parameter is the list of files being transferred.
const WaitingScreen(
{Key? key, required this.transferName, required this.files})
: super(key: key);
/// Creates the mutable state for this widget at a given location in the tree.
///
/// See also:
/// - [StatefulWidget.createState]
@override
WaitingScreenState createState() => WaitingScreenState();
}
class WaitingScreenState extends State<WaitingScreen> {
// The origin of the app.
String appOrigin = '';
/// Initializes the state of the widget.
///
/// This function is called when the widget is first created.
@override
void initState() {
super.initState();
// Load the settings and then start the transfer.
loadSettings().then((_) => callStartSender(appOrigin));
}
/// Loads the settings.
///
/// This function loads the settings from the shared preferences.
/// It retrieves the app origin from the shared preferences and assigns it to
/// the [appOrigin] variable.
///
/// Returns a [Future] that completes when the settings are loaded.
Future<void> loadSettings() async {
// Get the shared preferences instance.
SharedPreferences prefs = await SharedPreferences.getInstance();
// Get the app origin from the shared preferences.
// If the app origin is not found, use the default value.
appOrigin = prefs.getString('app_origin') ??
'wss://caesar-transfer-iu.shuttleapp.rs';
}
/// Calls the start sender function.
///
/// This function calls the [_startTransfer] function with the provided
/// [appOrigin].
///
/// Parameters:
/// - appOrigin: The origin of the app.
Future<void> callStartSender(String appOrigin) async {
_startTransfer(appOrigin);
}
/// Starts the transfer.
///
/// This function converts the list of files to a list of file names and then
/// calls the [startRustSender] function with the provided parameters.
///
/// Parameters:
/// - appOrigin: The origin of the app.
Future<void> _startTransfer(String appOrigin) async {
// Convert the list of files to a list of file names.
List<String> fileNames = widget.files.map((file) => file.path).toList();
// Start the transfer.
final outcome = await startRustSender(
name: widget.transferName, relay: appOrigin, files: fileNames);
// Navigate to the home page.
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => MyHomePage(title: 'Caesar Transfer')));
}
/// Builds the waiting screen widget.
///
/// This widget displays the transfer name and a QR code representing the
/// transfer name.
///
/// Returns:
/// A [Scaffold] widget containing the waiting screen UI.
@override
Widget build(BuildContext context) {
return Scaffold(
// Set the background color of the scaffold.
backgroundColor: Constants.backColor,
// Center the content of the scaffold.
body: Center(
child: Column(
// Align the children of the column in the center.
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Display the transfer name.
Text(
widget.transferName,
// Set the text style for the transfer name.
style: const TextStyle(color: Colors.white, fontSize: 24),
),
// Add spacing between the transfer name and the QR code.
const SizedBox(height: 32),
// Display a QR code representing the transfer name.
QrImageView(
// Set the data to be encoded in the QR code.
data: widget.transferName,
// Set the version of the QR code.
version: QrVersions.auto,
// Set the size of the QR code.
size: 200,
// Set the foreground color of the QR code.
foregroundColor: Constants.highlightColor,
),
],