docs(project): added docstrings to all code files
This commit is contained in:
parent
47acdec22a
commit
0d354efb8e
24 changed files with 1826 additions and 107 deletions
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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"),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue