Compare commits

..

1 Commits

Author SHA1 Message Date
25f3eb02de Remove uncessary file 2025-07-09 12:42:45 +02:00
21 changed files with 546 additions and 764 deletions

View File

@ -206,9 +206,5 @@
}
},
"flightDeletedSuccessfully": "Flight deleted successfully!",
"failedToDeleteFlight": "Failed to delete flight",
"customColorSetting": "Button Color",
"selectButtonColor": "Select Button Primary Color",
"pickColor": "Pick a color",
"select": "Select"
"failedToDeleteFlight": "Failed to delete flight"
}

View File

@ -206,9 +206,5 @@
}
},
"flightDeletedSuccessfully": "Vol supprimé avec succès !",
"failedToDeleteFlight": "Échec de la suppression du vol",
"customColorSetting": "Couleur des Boutons",
"selectButtonColor": "Sélectionner la couleur principale des boutons",
"pickColor": "Choisir une couleur",
"select": "Sélectionner"
"failedToDeleteFlight": "Échec de la suppression du vol"
}

View File

@ -712,30 +712,6 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'Failed to delete flight'**
String get failedToDeleteFlight;
/// No description provided for @customColorSetting.
///
/// In en, this message translates to:
/// **'Button Color'**
String get customColorSetting;
/// No description provided for @selectButtonColor.
///
/// In en, this message translates to:
/// **'Select Button Primary Color'**
String get selectButtonColor;
/// No description provided for @pickColor.
///
/// In en, this message translates to:
/// **'Pick a color'**
String get pickColor;
/// No description provided for @select.
///
/// In en, this message translates to:
/// **'Select'**
String get select;
}
class _AppLocalizationsDelegate extends LocalizationsDelegate<AppLocalizations> {

View File

@ -342,16 +342,4 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get failedToDeleteFlight => 'Failed to delete flight';
@override
String get customColorSetting => 'Button Color';
@override
String get selectButtonColor => 'Select Button Primary Color';
@override
String get pickColor => 'Pick a color';
@override
String get select => 'Select';
}

View File

@ -342,16 +342,4 @@ class AppLocalizationsFr extends AppLocalizations {
@override
String get failedToDeleteFlight => 'Échec de la suppression du vol';
@override
String get customColorSetting => 'Couleur des Boutons';
@override
String get selectButtonColor => 'Sélectionner la couleur principale des boutons';
@override
String get pickColor => 'Choisir une couleur';
@override
String get select => 'Sélectionner';
}

View File

@ -5,7 +5,6 @@ import 'package:rtime/l10n/app_localizations.dart';
import 'package:rtime/pages/home_page.dart';
import 'package:rtime/providers/local_provider.dart';
import 'package:rtime/providers/theme_provider.dart';
import 'package:rtime/providers/color_provider.dart';
void main() {
runApp(
@ -17,9 +16,6 @@ void main() {
ChangeNotifierProvider(
create: (context) => ThemeProvider(),
),
ChangeNotifierProvider(
create: (context) => ColorProvider(),
),
],
child: const MyApp(),
),
@ -36,11 +32,8 @@ class MyApp extends StatefulWidget {
class _MyAppState extends State<MyApp> {
@override
Widget build(BuildContext context) {
return Consumer3<LocaleProvider, ThemeProvider, ColorProvider>(
builder: (context, localeProvider, themeProvider, colorProvider, child) {
// customAccentColor est toujours là si tu veux l'utiliser pour d'autres éléments
final customAccentColor = colorProvider.accentColor;
return Consumer2<LocaleProvider, ThemeProvider>(
builder: (context, localeProvider, themeProvider, child) {
return MaterialApp(
title: 'Rtime',
locale: localeProvider.locale,
@ -54,10 +47,11 @@ class _MyAppState extends State<MyApp> {
Locale('en', ''),
Locale('fr', ''),
],
theme: ThemeData(
primaryColor: Colors.white,
colorScheme: ColorScheme.light(
primary: Colors.blue, // Couleur primaire fixe pour le mode clair
primary: Colors.blue.shade600,
secondary: Colors.teal.shade400,
surface: Colors.white,
background: Colors.white,
@ -68,19 +62,20 @@ class _MyAppState extends State<MyApp> {
onBackground: Colors.black87,
),
scaffoldBackgroundColor: Colors.white,
appBarTheme: const AppBarTheme(
backgroundColor: Color(0xFFF5F5F5),
appBarTheme: AppBarTheme(
backgroundColor: Colors.white,
foregroundColor: Colors.black87,
elevation: 0.5,
iconTheme: IconThemeData(color: Colors.black87),
titleTextStyle: TextStyle(
color: Colors.black,
iconTheme: const IconThemeData(color: Colors.black87),
titleTextStyle: const TextStyle(
color: Colors.black87,
fontSize: 20,
fontWeight: FontWeight.bold,
),
),
floatingActionButtonTheme: FloatingActionButtonThemeData(
backgroundColor: customAccentColor,
backgroundColor: Colors.blue.shade600,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
@ -104,7 +99,7 @@ class _MyAppState extends State<MyApp> {
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
selectedTileColor: customAccentColor.withOpacity(0.1),
selectedTileColor: Colors.blue.shade50,
),
textTheme: const TextTheme(
headlineSmall: TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: Colors.black87),
@ -115,27 +110,11 @@ class _MyAppState extends State<MyApp> {
bodySmall: TextStyle(fontSize: 12, color: Colors.black45),
),
visualDensity: VisualDensity.adaptivePlatformDensity,
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: customAccentColor,
foregroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
),
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(
foregroundColor: customAccentColor,
),
),
outlinedButtonTheme: OutlinedButtonThemeData(
style: OutlinedButton.styleFrom(
side: BorderSide(color: customAccentColor),
foregroundColor: customAccentColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
buttonTheme: ButtonThemeData(
buttonColor: Colors.blue.shade600,
textTheme: ButtonTextTheme.primary,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
inputDecorationTheme: InputDecorationTheme(
@ -145,7 +124,7 @@ class _MyAppState extends State<MyApp> {
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: customAccentColor, width: 2),
borderSide: BorderSide(color: Colors.blue.shade600, width: 2),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
@ -155,10 +134,12 @@ class _MyAppState extends State<MyApp> {
hintStyle: TextStyle(color: Colors.grey.shade500),
),
),
darkTheme: ThemeData.dark().copyWith(
primaryColor: Colors.blueGrey[900],
colorScheme: ColorScheme.dark(
primary: Colors.blueGrey[600]!,
primary: Colors.lightBlueAccent,
secondary: Colors.tealAccent,
surface: Colors.blueGrey.shade800,
background: Colors.blueGrey.shade900,
@ -167,6 +148,9 @@ class _MyAppState extends State<MyApp> {
onSurface: Colors.white,
onBackground: Colors.white,
),
appBarTheme: AppBarTheme(
backgroundColor: Colors.blueGrey[900],
foregroundColor: Colors.white,
@ -179,7 +163,7 @@ class _MyAppState extends State<MyApp> {
),
),
floatingActionButtonTheme: FloatingActionButtonThemeData(
backgroundColor: customAccentColor,
backgroundColor: Colors.lightBlueAccent,
foregroundColor: Colors.black,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30.0),
@ -201,7 +185,7 @@ class _MyAppState extends State<MyApp> {
contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
tileColor: Colors.blueGrey[800],
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
selectedTileColor: customAccentColor.withOpacity(0.3),
selectedTileColor: Colors.blueGrey[700],
),
textTheme: const TextTheme(
headlineSmall: TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: Colors.white),
@ -212,27 +196,11 @@ class _MyAppState extends State<MyApp> {
bodySmall: TextStyle(fontSize: 12, color: Colors.white70),
),
visualDensity: VisualDensity.adaptivePlatformDensity,
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: customAccentColor,
foregroundColor: Colors.black,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
),
textButtonTheme: TextButtonThemeData(
style: TextButton.styleFrom(
foregroundColor: customAccentColor,
),
),
outlinedButtonTheme: OutlinedButtonThemeData(
style: OutlinedButton.styleFrom(
side: BorderSide(color: customAccentColor),
foregroundColor: customAccentColor,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
buttonTheme: ButtonThemeData(
buttonColor: Colors.lightBlueAccent,
textTheme: ButtonTextTheme.primary,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(8),
),
),
inputDecorationTheme: InputDecorationTheme(
@ -242,7 +210,7 @@ class _MyAppState extends State<MyApp> {
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide(color: customAccentColor, width: 2),
borderSide: BorderSide(color: Colors.lightBlueAccent, width: 2),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),

View File

@ -59,21 +59,29 @@ class _BatteryDetailPageState extends State<BatteryDetailPage> {
}
}
Future<void> _loadAssociatedFlights() async {
setState(() {
_isLoadingFlights = true;
});
try {
final allFlights = await DbHelper.instance.getBatteryFlights(widget.battery.id!);
_associatedFlights = allFlights
.where((flight) => flight.batteryId == widget.battery.id)
.toList();
_associatedFlights.sort((a, b) => b.startTimestamp.compareTo(a.startTimestamp));
setState(() {
_isLoadingFlights = false;
});
} catch (e) {
if (mounted) {
setState(() {
_isLoadingFlights = false;
});
@ -83,7 +91,9 @@ class _BatteryDetailPageState extends State<BatteryDetailPage> {
Future<void> _pickImage(ImageSource source) async {
final uuid = await ImagesManager.instance.createImage(source);
if (uuid != null) {
if (_currentImageUuid != null && _currentImageUuid != uuid) {
await ImagesManager.instance.deleteImage(_currentImageUuid!);
}
@ -114,13 +124,20 @@ class _BatteryDetailPageState extends State<BatteryDetailPage> {
voltage: double.parse(_voltageController.text.trim()),
imageUuid: _currentImageUuid,
);
try {
await DbHelper.instance.updateBattery(updatedBattery);
if (mounted) {
Navigator.of(context).pop(true);
}
} catch (e) {
if (mounted) {
}
}
}
@ -145,17 +162,25 @@ class _BatteryDetailPageState extends State<BatteryDetailPage> {
],
),
);
if (confirm == true) {
try {
if (_currentImageUuid != null && _currentImageUuid!.isNotEmpty) {
await ImagesManager.instance.deleteImage(_currentImageUuid!);
}
await DbHelper.instance.deleteBattery(widget.battery.id!);
if (mounted) {
Navigator.of(context).pop(true);
}
} catch (e) {
if (mounted) {
}
}
}
@ -170,8 +195,8 @@ class _BatteryDetailPageState extends State<BatteryDetailPage> {
appBar: AppBar(
title: Text(_isEditing ? l10n.editBattery : l10n.batteryDetails),
backgroundColor: Theme.of(context).primaryColor,
foregroundColor: Theme.of(context).appBarTheme.foregroundColor,
iconTheme: Theme.of(context).appBarTheme.iconTheme,
foregroundColor: Colors.white,
iconTheme: const IconThemeData(color: Colors.white),
actions: [
IconButton(
icon: Icon(_isEditing ? Icons.save : Icons.edit),
@ -202,10 +227,9 @@ class _BatteryDetailPageState extends State<BatteryDetailPage> {
width: 180,
height: 180,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
color: Colors.blueGrey[800],
borderRadius: BorderRadius.circular(15),
border: Border.all(
color: Theme.of(context).colorScheme.primary, width: 2),
border: Border.all(color: Colors.tealAccent, width: 2),
image: _displayImage != null
? DecorationImage(
image: _displayImage!.image,
@ -217,7 +241,7 @@ class _BatteryDetailPageState extends State<BatteryDetailPage> {
? Icon(
Icons.camera_alt,
size: 80,
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.4),
color: Colors.blueGrey[400],
)
: null,
),
@ -233,7 +257,7 @@ class _BatteryDetailPageState extends State<BatteryDetailPage> {
label: Text(l10n.takePhoto),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blueGrey[700],
foregroundColor: Colors.white, // Texte en blanc
foregroundColor: Colors.white,
),
),
const SizedBox(width: 10),
@ -243,7 +267,7 @@ class _BatteryDetailPageState extends State<BatteryDetailPage> {
label: Text(l10n.chooseFromGallery),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blueGrey[700],
foregroundColor: Colors.white, // Texte en blanc
foregroundColor: Colors.white,
),
),
],
@ -261,13 +285,15 @@ class _BatteryDetailPageState extends State<BatteryDetailPage> {
readOnly: !_isEditing,
decoration: InputDecoration(
labelText: l10n.batteryName,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: _isEditing ? Colors.blueGrey[600]! : Colors.white30),
labelStyle: const TextStyle(color: Colors.white70),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.white30),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueGrey[600]!),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.tealAccent),
),
),
style: const TextStyle(color: Colors.white),
validator: (value) {
if (value == null || value.isEmpty) {
return l10n.pleaseEnterBatteryName;
@ -281,13 +307,15 @@ class _BatteryDetailPageState extends State<BatteryDetailPage> {
readOnly: !_isEditing,
decoration: InputDecoration(
labelText: l10n.batteryType,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: _isEditing ? Colors.blueGrey[600]! : Colors.white30),
labelStyle: const TextStyle(color: Colors.white70),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.white30),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueGrey[600]!),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.tealAccent),
),
),
style: const TextStyle(color: Colors.white),
validator: (value) {
if (value == null || value.isEmpty) {
return l10n.pleaseEnterBatteryType;
@ -302,13 +330,15 @@ class _BatteryDetailPageState extends State<BatteryDetailPage> {
readOnly: !_isEditing,
decoration: InputDecoration(
labelText: l10n.batteryVoltage,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: _isEditing ? Colors.blueGrey[600]! : Colors.white30),
labelStyle: const TextStyle(color: Colors.white70),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.white30),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueGrey[600]!),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.tealAccent),
),
),
style: const TextStyle(color: Colors.white),
validator: (value) {
if (value == null || value.isEmpty) {
return l10n.pleaseEnterBatteryVoltage;
@ -324,24 +354,25 @@ class _BatteryDetailPageState extends State<BatteryDetailPage> {
Center(
child: ElevatedButton(
onPressed: _saveBattery,
style: Theme.of(context).elevatedButtonTheme.style?.copyWith(
padding: MaterialStateProperty.all(
const EdgeInsets.symmetric(horizontal: 40, vertical: 15)),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
)),
foregroundColor: MaterialStateProperty.all(Colors.white), // Texte en blanc pour le bouton Save Changes
style: ElevatedButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.secondary,
foregroundColor: Colors.black,
padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 15),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
child: Text(
l10n.saveChanges,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
),
),
const SizedBox(height: 30),
Text(
l10n.latestFlights,
style: Theme.of(context).textTheme.headlineSmall,
style: Theme.of(context).textTheme.headlineSmall!.copyWith(color: Colors.white),
),
const SizedBox(height: 15),
_isLoadingFlights
@ -350,7 +381,7 @@ class _BatteryDetailPageState extends State<BatteryDetailPage> {
? Center(
child: Text(
l10n.noFlightsYet,
style: Theme.of(context).textTheme.titleMedium,
style: Theme.of(context).textTheme.titleMedium!.copyWith(color: Colors.white70),
),
)
: ListView.builder(
@ -366,14 +397,14 @@ class _BatteryDetailPageState extends State<BatteryDetailPage> {
child: ListTile(
contentPadding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 12),
leading: Icon(Icons.flight_takeoff,
leading: const Icon(Icons.flight_takeoff,
color: Colors.orangeAccent, size: 32),
title: Text(
'${flight.name} - ${flightDate.toLocal().toString().split(' ')[0]}',
style: Theme.of(context).textTheme.titleMedium,
),
trailing: Icon(Icons.arrow_forward_ios,
size: 20, color: Theme.of(context).colorScheme.onSurface),
trailing: const Icon(Icons.arrow_forward_ios,
size: 20, color: Colors.white54),
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(

View File

@ -53,6 +53,7 @@ class _DroneDetailPageState extends State<DroneDetailPage> {
}
}
Future<void> _loadAssociatedFlights() async {
setState(() {
_isLoadingFlights = true;
@ -71,6 +72,10 @@ class _DroneDetailPageState extends State<DroneDetailPage> {
});
} catch (e) {
if (mounted) {
setState(() {
_isLoadingFlights = false;
});
@ -114,10 +119,16 @@ class _DroneDetailPageState extends State<DroneDetailPage> {
try {
await DbHelper.instance.updateDrone(updatedDrone);
if (mounted) {
Navigator.of(context).pop(true);
}
} catch (e) {
if (mounted) {
}
}
}
@ -150,10 +161,16 @@ class _DroneDetailPageState extends State<DroneDetailPage> {
}
await DbHelper.instance.deleteDrone(widget.drone.id!);
if (mounted) {
Navigator.of(context).pop(true);
}
} catch (e) {
if (mounted) {
}
}
}
@ -168,8 +185,8 @@ class _DroneDetailPageState extends State<DroneDetailPage> {
appBar: AppBar(
title: Text(_isEditing ? l10n.editDrone : l10n.droneDetails),
backgroundColor: Theme.of(context).primaryColor,
foregroundColor: Theme.of(context).appBarTheme.foregroundColor,
iconTheme: Theme.of(context).appBarTheme.iconTheme,
foregroundColor: Colors.white,
iconTheme: const IconThemeData(color: Colors.white),
actions: [
IconButton(
icon: Icon(_isEditing ? Icons.save : Icons.edit),
@ -200,10 +217,9 @@ class _DroneDetailPageState extends State<DroneDetailPage> {
width: 180,
height: 180,
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.surface,
color: Colors.blueGrey[800],
borderRadius: BorderRadius.circular(15),
border: Border.all(
color: Theme.of(context).colorScheme.primary, width: 2),
border: Border.all(color: Colors.lightBlueAccent, width: 2),
image: _displayImage != null
? DecorationImage(
image: _displayImage!.image,
@ -215,7 +231,7 @@ class _DroneDetailPageState extends State<DroneDetailPage> {
? Icon(
Icons.camera_alt,
size: 80,
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.4),
color: Colors.blueGrey[400],
)
: null,
),
@ -231,7 +247,7 @@ class _DroneDetailPageState extends State<DroneDetailPage> {
label: Text(l10n.takePhoto),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blueGrey[700],
foregroundColor: Colors.white, // Texte en blanc
foregroundColor: Colors.white,
),
),
const SizedBox(width: 10),
@ -241,7 +257,7 @@ class _DroneDetailPageState extends State<DroneDetailPage> {
label: Text(l10n.chooseFromGallery),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blueGrey[700],
foregroundColor: Colors.white, // Texte en blanc
foregroundColor: Colors.white,
),
),
],
@ -259,13 +275,15 @@ class _DroneDetailPageState extends State<DroneDetailPage> {
readOnly: !_isEditing,
decoration: InputDecoration(
labelText: l10n.droneName,
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: _isEditing ? Colors.blueGrey[600]! : Colors.white30),
labelStyle: const TextStyle(color: Colors.white70),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.white30),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueGrey[600]!),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.lightBlueAccent),
),
),
style: const TextStyle(color: Colors.white),
validator: (value) {
if (value == null || value.isEmpty) {
return l10n.pleaseEnterDroneName;
@ -278,24 +296,25 @@ class _DroneDetailPageState extends State<DroneDetailPage> {
Center(
child: ElevatedButton(
onPressed: _saveDrone,
style: Theme.of(context).elevatedButtonTheme.style?.copyWith(
padding: MaterialStateProperty.all(
const EdgeInsets.symmetric(horizontal: 40, vertical: 15)),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
)),
foregroundColor: MaterialStateProperty.all(Colors.white), // Texte en blanc pour le bouton Save Changes
style: ElevatedButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.secondary,
foregroundColor: Colors.black,
padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 15),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
child: Text(
l10n.saveChanges,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
),
),
const SizedBox(height: 30),
Text(
l10n.latestFlights,
style: Theme.of(context).textTheme.headlineSmall,
style: Theme.of(context).textTheme.headlineSmall!.copyWith(color: Colors.white),
),
const SizedBox(height: 15),
_isLoadingFlights
@ -304,7 +323,7 @@ class _DroneDetailPageState extends State<DroneDetailPage> {
? Center(
child: Text(
l10n.noFlightsYet,
style: Theme.of(context).textTheme.titleMedium,
style: Theme.of(context).textTheme.titleMedium!.copyWith(color: Colors.white70),
),
)
: ListView.builder(
@ -326,8 +345,8 @@ class _DroneDetailPageState extends State<DroneDetailPage> {
'${flight.name} - ${flightDate.toLocal().toString().split(' ')[0]}',
style: Theme.of(context).textTheme.titleMedium,
),
trailing: Icon(Icons.arrow_forward_ios,
size: 20, color: Theme.of(context).colorScheme.onSurface),
trailing: const Icon(Icons.arrow_forward_ios,
size: 20, color: Colors.white54),
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(

View File

@ -7,9 +7,6 @@ import 'package:rtime/db/db_helper.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:rtime/images_manager.dart';
import 'package:provider/provider.dart';
import 'package:rtime/providers/color_provider.dart';
class FlightDetailPage extends StatefulWidget {
final Flight flight;
@ -51,11 +48,15 @@ class _FlightDetailPageState extends State<FlightDetailPage> {
final droneList = await DbHelper.instance.getDrones();
final batteryList = await DbHelper.instance.getBatteries();
final drone = droneList.firstWhere((d) => d.id == widget.flight.droneId,
final drone = droneList.firstWhere(
(d) => d.id == widget.flight.droneId,
orElse: () => Drone(name: 'Unknown Drone'));
final battery = batteryList.firstWhere((b) => b.id == widget.flight.batteryId,
orElse: () => Battery(name: 'Unknown Battery', type: '', voltage: 0.0));
final battery = batteryList.firstWhere(
(b) => b.id == widget.flight.batteryId,
orElse: () => Battery(
name: 'Unknown Battery', type: '', voltage: 0.0));
await _loadImage(drone.imageUuid, (image) {
setState(() {
@ -118,7 +119,9 @@ class _FlightDetailPageState extends State<FlightDetailPage> {
Navigator.of(context).pop(true);
}
} catch (e) {
if (mounted) {}
if (mounted) {
}
}
}
}
@ -127,8 +130,6 @@ class _FlightDetailPageState extends State<FlightDetailPage> {
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
final flight = widget.flight;
final colorProvider = Provider.of<ColorProvider>(context);
final accentColor = colorProvider.accentColor;
final DateTime startDate =
DateTime.fromMillisecondsSinceEpoch(flight.startTimestamp * 1000);
@ -139,12 +140,13 @@ class _FlightDetailPageState extends State<FlightDetailPage> {
backgroundColor: Theme.of(context).primaryColor,
appBar: AppBar(
title: Text(l10n.flightDetails),
backgroundColor: Theme.of(context).appBarTheme.backgroundColor,
foregroundColor: Theme.of(context).appBarTheme.foregroundColor,
iconTheme: Theme.of(context).iconTheme,
backgroundColor: Theme.of(context).primaryColor,
foregroundColor: Colors.white,
iconTheme: const IconThemeData(color: Colors.white),
elevation: 0,
actions: [
IconButton(
icon: Icon(Icons.delete_forever, color: Theme.of(context).colorScheme.error),
icon: const Icon(Icons.delete_forever, color: Colors.redAccent),
onPressed: _deleteFlight,
),
],
@ -159,7 +161,8 @@ class _FlightDetailPageState extends State<FlightDetailPage> {
Card(
elevation: 4,
margin: const EdgeInsets.only(bottom: 20),
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(15)),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15)),
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
@ -167,61 +170,63 @@ class _FlightDetailPageState extends State<FlightDetailPage> {
children: [
Text(
flight.name,
style: Theme.of(context).textTheme.headlineSmall!.copyWith(
color: Theme.of(context).textTheme.headlineSmall!.color,
style: Theme.of(context).textTheme.headlineMedium!.copyWith(
color: Theme.of(context).colorScheme.onSurface,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 10),
Divider(color: Theme.of(context).dividerColor),
Divider(color: Colors.grey[300]),
_buildImageAndDetailRow(
context,
l10n.drone,
_associatedDrone?.name ?? l10n.unknown,
_droneDisplayImage,
Icons.flight_takeoff,
accentColor,
),
_buildImageAndDetailRow(
context,
l10n.battery,
_associatedBattery?.name ?? l10n.unknown,
_batteryDisplayImage,
Icons.battery_std,
accentColor,
),
_buildDetailRow(
l10n.startTime,
'${startDate.toLocal().toString().split(' ')[0]} ${startDate.toLocal().toString().split(' ')[1].substring(0, 5)}',
accentColor),
'${startDate.toLocal().toString().split(' ')[0]} ${startDate.toLocal().toString().split(' ')[1].substring(0, 5)}'),
_buildDetailRow(
l10n.endTime,
'${endDate.toLocal().toString().split(' ')[0]} ${endDate.toLocal().toString().split(' ')[1].substring(0, 5)}',
accentColor),
_buildDetailRow(l10n.duration,
_formatDuration(flight.startTimestamp, flight.endTimestamp),
accentColor),
'${endDate.toLocal().toString().split(' ')[0]} ${endDate.toLocal().toString().split(' ')[1].substring(0, 5)}'),
_buildDetailRow(
l10n.duration,
_formatDuration(
flight.startTimestamp, flight.endTimestamp)),
],
),
),
),
if (flight.locationLat != null && flight.locationLong != null) ...[
Text(
l10n.flightLocation,
style: Theme.of(context).textTheme.headlineSmall,
style: Theme.of(context).textTheme.headlineSmall!.copyWith(color: Colors.white),
),
const SizedBox(height: 15),
Container(
height: 300,
decoration: BoxDecoration(
color: Theme.of(context).cardTheme.color,
color: Colors.grey[300],
borderRadius: BorderRadius.circular(15),
),
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
child: FlutterMap(
options: MapOptions(
initialCenter: LatLng(flight.locationLat!, flight.locationLong!),
initialCenter: LatLng(
flight.locationLat!, flight.locationLong!),
initialZoom: 15.0,
interactionOptions: const InteractionOptions(
flags: InteractiveFlag.all & ~InteractiveFlag.rotate,
@ -229,18 +234,20 @@ class _FlightDetailPageState extends State<FlightDetailPage> {
),
children: [
TileLayer(
urlTemplate: "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
urlTemplate:
"https://tile.openstreetmap.org/{z}/{x}/{y}.png",
userAgentPackageName: 'com.example.rtime',
),
MarkerLayer(
markers: [
Marker(
point: LatLng(flight.locationLat!, flight.locationLong!),
point: LatLng(
flight.locationLat!, flight.locationLong!),
width: 80,
height: 80,
child: Icon(
child: const Icon(
Icons.location_on,
color: accentColor,
color: Colors.red,
size: 40.0,
),
),
@ -255,7 +262,10 @@ class _FlightDetailPageState extends State<FlightDetailPage> {
Center(
child: Text(
l10n.noLocationData,
style: Theme.of(context).textTheme.titleMedium,
style: Theme.of(context)
.textTheme
.titleMedium!
.copyWith(color: Colors.white70),
),
),
],
@ -266,7 +276,8 @@ class _FlightDetailPageState extends State<FlightDetailPage> {
);
}
Widget _buildDetailRow(String label, String value, Color labelColor) {
Widget _buildDetailRow(String label, String value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
@ -277,7 +288,7 @@ class _FlightDetailPageState extends State<FlightDetailPage> {
child: Text(
'$label:',
style: Theme.of(context).textTheme.titleSmall!.copyWith(
color: labelColor,
color: Theme.of(context).colorScheme.secondary,
fontWeight: FontWeight.bold,
),
),
@ -287,7 +298,7 @@ class _FlightDetailPageState extends State<FlightDetailPage> {
child: Text(
value,
style: Theme.of(context).textTheme.titleMedium!.copyWith(
color: Theme.of(context).textTheme.bodyLarge!.color,
color: Theme.of(context).colorScheme.onSurface,
),
),
),
@ -296,57 +307,61 @@ class _FlightDetailPageState extends State<FlightDetailPage> {
);
}
Widget _buildImageAndDetailRow(
BuildContext context, String label, String value, Image? displayImage, IconData defaultIcon, Color labelColor) {
BuildContext context, String label, String value, Image? displayImage, IconData defaultIcon) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Expanded(
flex: 2,
child: Text(
'$label:',
style: Theme.of(context).textTheme.titleSmall!.copyWith(
color: labelColor,
fontWeight: FontWeight.bold,
),
Container(
width: 40,
height: 40,
margin: const EdgeInsets.only(right: 12),
decoration: BoxDecoration(
color: Colors.blueGrey[800],
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.blueGrey[600]!, width: 1),
image: displayImage != null
? DecorationImage(
image: displayImage.image,
fit: BoxFit.cover,
)
: null,
),
child: displayImage == null
? Icon(
defaultIcon,
size: 24,
color: Colors.blueGrey[400],
)
: null,
),
Expanded(
flex: 3,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(
flex: 2,
child: Text(
value,
style: Theme.of(context).textTheme.titleMedium!.copyWith(
color: Theme.of(context).textTheme.bodyLarge!.color,
'$label:',
style: Theme.of(context).textTheme.titleSmall!.copyWith(
color: Theme.of(context).colorScheme.secondary,
fontWeight: FontWeight.bold,
),
),
),
Container(
width: 40,
height: 40,
margin: const EdgeInsets.only(left: 12),
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Theme.of(context).dividerColor, width: 1),
image: displayImage != null
? DecorationImage(
image: displayImage.image,
fit: BoxFit.cover,
)
: null,
Expanded(
flex: 3,
child: Text(
value,
style: Theme.of(context).textTheme.titleMedium!.copyWith(
color: Theme.of(context).colorScheme.onSurface,
),
),
child: displayImage == null
? Icon(
defaultIcon,
size: 24,
color: Theme.of(context).iconTheme.color,
)
: null,
),
],
),

View File

@ -1,3 +1,4 @@
import 'package:flutter/material.dart';
import 'package:rtime/models/drone.dart';
import 'package:rtime/models/battery.dart';
@ -13,8 +14,6 @@ import 'package:rtime/pages/drone_detail_page.dart';
import 'package:rtime/pages/battery_detail_page.dart';
import 'package:rtime/db/db_helper.dart';
import 'package:rtime/pages/flight_detail_page.dart';
import 'package:provider/provider.dart';
import 'package:rtime/providers/color_provider.dart';
import 'package:rtime/widgets/page_transition_animations.dart';
@ -48,8 +47,6 @@ class _HomePageState extends State<HomePage> {
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
final customAccentColor = Provider.of<ColorProvider>(context).accentColor;
return Scaffold(
backgroundColor: Theme.of(context).primaryColor,
@ -69,10 +66,10 @@ class _HomePageState extends State<HomePage> {
children: [
Text(
l10n.appTitle,
style: TextStyle(
style: const TextStyle(
fontSize: 48,
fontWeight: FontWeight.bold,
color: customAccentColor,
color: Colors.lightBlueAccent,
fontFamily: 'Montserrat',
),
),
@ -80,6 +77,7 @@ class _HomePageState extends State<HomePage> {
icon:
const Icon(Icons.settings, size: 30, color: Colors.white70),
onPressed: () {
Navigator.of(context).push(
SlideRightPageRoute(
page: const SettingsPage(),
@ -113,6 +111,7 @@ class _HomePageState extends State<HomePage> {
margin: const EdgeInsets.only(right: 16),
child: InkWell(
onTap: () {
Navigator.of(context).push(
SlideUpPageRoute(
page: const NewDronePage(),
@ -130,7 +129,7 @@ class _HomePageState extends State<HomePage> {
const SizedBox(height: 10),
Text(l10n.addDrone,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleSmall!.copyWith(color: Colors.white)), // Texte blanc
style: Theme.of(context).textTheme.titleSmall),
],
),
),
@ -147,6 +146,7 @@ class _HomePageState extends State<HomePage> {
margin: const EdgeInsets.only(right: 16),
child: InkWell(
onTap: () {
Navigator.of(context).push(
SlideUpPageRoute(
page: const NewDronePage(),
@ -164,7 +164,7 @@ class _HomePageState extends State<HomePage> {
const SizedBox(height: 10),
Text(l10n.addDrone,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleSmall!.copyWith(color: Colors.white)), // Texte blanc
style: Theme.of(context).textTheme.titleSmall),
],
),
),
@ -174,11 +174,13 @@ class _HomePageState extends State<HomePage> {
return DroneCard(
drone: drones[index],
onTap: () {
Navigator.of(context).push(
SlideRightPageRoute(
page: DroneDetailPage(drone: drones[index]),
),
).then((result) {
if (result == true) {
_loadData();
}
@ -216,6 +218,7 @@ class _HomePageState extends State<HomePage> {
margin: const EdgeInsets.only(right: 16),
child: InkWell(
onTap: () {
Navigator.of(context).push(
SlideUpPageRoute(
page: const NewBatteryPage(),
@ -233,12 +236,12 @@ class _HomePageState extends State<HomePage> {
const SizedBox(height: 10),
Text(l10n.addBattery,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleSmall!.copyWith(color: Colors.white)), // Texte blanc
style: Theme.of(context).textTheme.titleSmall),
],
),
),
),
),
);
);
} else {
final batteries = snapshot.data!;
return ListView.builder(
@ -250,6 +253,7 @@ class _HomePageState extends State<HomePage> {
margin: const EdgeInsets.only(right: 16),
child: InkWell(
onTap: () {
Navigator.of(context).push(
SlideUpPageRoute(
page: const NewBatteryPage(),
@ -267,7 +271,7 @@ class _HomePageState extends State<HomePage> {
const SizedBox(height: 10),
Text(l10n.addBattery,
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleSmall!.copyWith(color: Colors.white)), // Texte blanc
style: Theme.of(context).textTheme.titleSmall),
],
),
),
@ -277,11 +281,13 @@ class _HomePageState extends State<HomePage> {
return BatteryCard(
battery: batteries[index],
onTap: () {
Navigator.of(context).push(
SlideRightPageRoute(
page: BatteryDetailPage(battery: batteries[index]),
),
).then((result) {
if (result == true) {
_loadData();
}
@ -319,7 +325,7 @@ class _HomePageState extends State<HomePage> {
style: Theme.of(context)
.textTheme
.titleMedium!
.copyWith(color: Theme.of(context).colorScheme.onBackground),
.copyWith(color: Colors.white70),
),
);
} else {
@ -335,15 +341,16 @@ class _HomePageState extends State<HomePage> {
child: ListTile(
contentPadding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 12),
leading: Icon(Icons.flight_takeoff,
leading: const Icon(Icons.flight_takeoff,
color: Colors.orangeAccent, size: 32),
title: Text(
'${flight.name} - ${DateTime.fromMillisecondsSinceEpoch(flight.startTimestamp * 1000).toLocal().toString().split(' ')[0]}',
style: Theme.of(context).textTheme.titleMedium,
),
trailing: Icon(Icons.arrow_forward_ios,
size: 20, color: Theme.of(context).colorScheme.onSurface),
trailing: const Icon(Icons.arrow_forward_ios,
size: 20, color: Colors.white54),
onTap: () {
Navigator.of(context).push(
SlideRightPageRoute(
page: FlightDetailPage(flight: flight),
@ -363,6 +370,7 @@ class _HomePageState extends State<HomePage> {
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () {
Navigator.of(context).push(
SlideUpPageRoute(
page: const NewFlightPage(),
@ -371,9 +379,9 @@ class _HomePageState extends State<HomePage> {
},
label: Text(
l10n.newFlight,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: Colors.white), // Texte blanc
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
icon: const Icon(Icons.add_to_photos, size: 28, color: Colors.white), // Icône blanche
icon: const Icon(Icons.add_to_photos, size: 28),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
);

View File

@ -28,7 +28,9 @@ class _NewBatteryPageState extends State<NewBatteryPage> {
super.dispose();
}
Future<void> _pickImage(ImageSource source) async {
final l10n = AppLocalizations.of(context)!;
final uuid = await ImagesManager.instance.createImage(source);
if (uuid != null) {
final loadedImage = await ImagesManager.instance.loadImage(uuid);
@ -36,11 +38,23 @@ class _NewBatteryPageState extends State<NewBatteryPage> {
_selectedImageUuid = uuid;
_displayImage = loadedImage;
});
if (mounted) {
}
} else {
if (mounted) {
}
}
}
void _saveBattery() async {
if (_formKey.currentState!.validate()) {
final l10n = AppLocalizations.of(context)!;
final newBattery = Battery(
name: _nameController.text.trim(),
type: _typeController.text.trim(),
@ -51,9 +65,18 @@ class _NewBatteryPageState extends State<NewBatteryPage> {
try {
await DbHelper.instance.insertBattery(newBattery);
if (mounted) {
Navigator.of(context).pop();
}
} catch (e) {}
} catch (e) {
if (mounted) {
}
}
}
}
@ -75,33 +98,33 @@ class _NewBatteryPageState extends State<NewBatteryPage> {
key: _formKey,
child: ListView(
children: [
Center(
child: Column(
children: [
GestureDetector(
onTap: () => _pickImage(ImageSource.camera),
child: Container(
width: 150,
height: 150,
decoration: BoxDecoration(
color: Colors.blueGrey[800],
borderRadius: BorderRadius.circular(15),
border: Border.all(color: Colors.blueGrey[600]!, width: 2),
image: _displayImage != null
? DecorationImage(
image: _displayImage!.image,
fit: BoxFit.cover,
)
: null,
),
child: _displayImage == null
? Icon(
Icons.camera_alt,
size: 60,
color: Colors.blueGrey[400],
Container(
width: 150,
height: 150,
decoration: BoxDecoration(
color: Colors.blueGrey[800],
borderRadius: BorderRadius.circular(15),
border: Border.all(color: Colors.lightBlueAccent, width: 2),
image: _displayImage != null
? DecorationImage(
image: _displayImage!.image,
fit: BoxFit.cover,
)
: null,
),
child: _displayImage == null
? Icon(
Icons.camera_alt,
size: 60,
color: Colors.blueGrey[400],
)
: null,
),
const SizedBox(height: 10),
Text(l10n.batteryImage,
@ -116,7 +139,7 @@ class _NewBatteryPageState extends State<NewBatteryPage> {
label: Text(l10n.takePhoto),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blueGrey[700],
foregroundColor: Colors.white, // Set text color to white
foregroundColor: Colors.white,
),
),
const SizedBox(width: 10),
@ -126,7 +149,7 @@ class _NewBatteryPageState extends State<NewBatteryPage> {
label: Text(l10n.chooseFromGallery),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blueGrey[700],
foregroundColor: Colors.white, // Set text color to white
foregroundColor: Colors.white,
),
),
],
@ -140,11 +163,11 @@ class _NewBatteryPageState extends State<NewBatteryPage> {
decoration: InputDecoration(
labelText: l10n.batteryName,
labelStyle: const TextStyle(color: Colors.white70),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueGrey[600]!),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.white30),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueGrey[600]!),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.lightBlueAccent),
),
),
style: const TextStyle(color: Colors.white),
@ -161,11 +184,11 @@ class _NewBatteryPageState extends State<NewBatteryPage> {
decoration: InputDecoration(
labelText: l10n.batteryType,
labelStyle: const TextStyle(color: Colors.white70),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueGrey[600]!),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.white30),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueGrey[600]!),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.lightBlueAccent),
),
),
style: const TextStyle(color: Colors.white),
@ -183,11 +206,11 @@ class _NewBatteryPageState extends State<NewBatteryPage> {
decoration: InputDecoration(
labelText: l10n.batteryVoltage,
labelStyle: const TextStyle(color: Colors.white70),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueGrey[600]!),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.white30),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueGrey[600]!),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.lightBlueAccent),
),
),
style: const TextStyle(color: Colors.white),
@ -205,14 +228,15 @@ class _NewBatteryPageState extends State<NewBatteryPage> {
Center(
child: ElevatedButton(
onPressed: _saveBattery,
style: Theme.of(context).elevatedButtonTheme.style?.copyWith(
padding: MaterialStateProperty.all(
const EdgeInsets.symmetric(horizontal: 40, vertical: 15)),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
)),
foregroundColor: MaterialStateProperty.all(Colors.white), // Set text color to white
),
style: ElevatedButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.secondary,
foregroundColor: Colors.black,
padding:
const EdgeInsets.symmetric(horizontal: 40, vertical: 15),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
child: Text(
l10n.saveBattery,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),

View File

@ -24,7 +24,9 @@ class _NewDronePageState extends State<NewDronePage> {
super.dispose();
}
Future<void> _pickImage(ImageSource source) async {
final l10n = AppLocalizations.of(context)!;
final uuid = await ImagesManager.instance.createImage(source);
if (uuid != null) {
final loadedImage = await ImagesManager.instance.loadImage(uuid);
@ -32,11 +34,23 @@ class _NewDronePageState extends State<NewDronePage> {
_selectedImageUuid = uuid;
_displayImage = loadedImage;
});
if (mounted) {
}
} else {
if (mounted) {
}
}
}
void _saveDrone() async {
if (_formKey.currentState!.validate()) {
final l10n = AppLocalizations.of(context)!;
final newDrone = Drone(
name: _nameController.text.trim(),
imageUuid: _selectedImageUuid,
@ -45,9 +59,18 @@ class _NewDronePageState extends State<NewDronePage> {
try {
await DbHelper.instance.insertDrone(newDrone);
if (mounted) {
Navigator.of(context).pop();
}
} catch (e) {}
} catch (e) {
if (mounted) {
}
}
}
}
@ -69,33 +92,33 @@ class _NewDronePageState extends State<NewDronePage> {
key: _formKey,
child: ListView(
children: [
Center(
child: Column(
children: [
GestureDetector(
onTap: () => _pickImage(ImageSource.camera),
child: Container(
width: 150,
height: 150,
decoration: BoxDecoration(
color: Colors.blueGrey[800],
borderRadius: BorderRadius.circular(15),
border: Border.all(color: Colors.blueGrey[600]!, width: 2),
image: _displayImage != null
? DecorationImage(
image: _displayImage!.image,
fit: BoxFit.cover,
)
: null,
),
child: _displayImage == null
? Icon(
Icons.camera_alt,
size: 60,
color: Colors.blueGrey[400],
Container(
width: 150,
height: 150,
decoration: BoxDecoration(
color: Colors.blueGrey[800],
borderRadius: BorderRadius.circular(15),
border: Border.all(color: Colors.lightBlueAccent, width: 2),
image: _displayImage != null
? DecorationImage(
image: _displayImage!.image,
fit: BoxFit.cover,
)
: null,
),
child: _displayImage == null
? Icon(
Icons.camera_alt,
size: 60,
color: Colors.blueGrey[400],
)
: null,
),
const SizedBox(height: 10),
Text(l10n.droneImage,
@ -110,7 +133,7 @@ class _NewDronePageState extends State<NewDronePage> {
label: Text(l10n.takePhoto),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blueGrey[700],
foregroundColor: Colors.white, // Set text color to white
foregroundColor: Colors.white,
),
),
const SizedBox(width: 10),
@ -120,7 +143,7 @@ class _NewDronePageState extends State<NewDronePage> {
label: Text(l10n.chooseFromGallery),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blueGrey[700],
foregroundColor: Colors.white, // Set text color to white
foregroundColor: Colors.white,
),
),
],
@ -134,11 +157,11 @@ class _NewDronePageState extends State<NewDronePage> {
decoration: InputDecoration(
labelText: l10n.droneName,
labelStyle: const TextStyle(color: Colors.white70),
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueGrey[600]!),
enabledBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.white30),
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(color: Colors.blueGrey[600]!),
focusedBorder: const OutlineInputBorder(
borderSide: BorderSide(color: Colors.lightBlueAccent),
),
),
style: const TextStyle(color: Colors.white),
@ -153,14 +176,15 @@ class _NewDronePageState extends State<NewDronePage> {
Center(
child: ElevatedButton(
onPressed: _saveDrone,
style: Theme.of(context).elevatedButtonTheme.style?.copyWith(
padding: MaterialStateProperty.all(
const EdgeInsets.symmetric(horizontal: 40, vertical: 15)),
shape: MaterialStateProperty.all(RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
)),
foregroundColor: MaterialStateProperty.all(Colors.white), // Set text color to white
),
style: ElevatedButton.styleFrom(
backgroundColor: Theme.of(context).colorScheme.secondary,
foregroundColor: Colors.black,
padding:
const EdgeInsets.symmetric(horizontal: 40, vertical: 15),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10),
),
),
child: Text(
l10n.saveDrone,
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.bold),

View File

@ -8,8 +8,6 @@ import 'dart:async';
import 'package:geolocator/geolocator.dart';
import 'package:flutter_map/flutter_map.dart';
import 'package:latlong2/latlong.dart';
import 'package:provider/provider.dart';
import 'package:rtime/providers/color_provider.dart';
class NewFlightPage extends StatefulWidget {
const NewFlightPage({super.key});
@ -19,9 +17,11 @@ class NewFlightPage extends StatefulWidget {
}
class _NewFlightPageState extends State<NewFlightPage> {
late Future<List<Drone>> _dronesFuture;
late Future<List<Battery>> _batteriesFuture;
Drone? selectedDrone;
Battery? selectedBattery;
bool isFlightActive = false;
@ -30,12 +30,15 @@ class _NewFlightPageState extends State<NewFlightPage> {
String formattedTime = '00:00:00';
int? flightStartTime;
bool useGpsLocation = false;
Position? currentPosition;
bool isGettingLocation = false;
final MapController _mapController = MapController();
bool _initialMapCentered = false;
@override
@ -44,6 +47,7 @@ class _NewFlightPageState extends State<NewFlightPage> {
_loadAvailableItems();
}
void _loadAvailableItems() {
_dronesFuture = DbHelper.instance.getDrones();
_batteriesFuture = DbHelper.instance.getBatteries();
@ -55,6 +59,8 @@ class _NewFlightPageState extends State<NewFlightPage> {
super.dispose();
}
Future<void> _getCurrentLocation() async {
if (!mounted) return;
@ -69,7 +75,9 @@ class _NewFlightPageState extends State<NewFlightPage> {
serviceEnabled = await Geolocator.isLocationServiceEnabled();
if (!serviceEnabled) {
if (mounted) {}
if (mounted) {
}
if (mounted) {
setState(() {
useGpsLocation = false;
@ -87,7 +95,9 @@ class _NewFlightPageState extends State<NewFlightPage> {
if (permission == LocationPermission.denied) {
permission = await Geolocator.requestPermission();
if (permission == LocationPermission.denied) {
if (mounted) {}
if (mounted) {
}
if (mounted) {
setState(() {
useGpsLocation = false;
@ -103,7 +113,9 @@ class _NewFlightPageState extends State<NewFlightPage> {
}
if (permission == LocationPermission.deniedForever) {
if (mounted) {}
if (mounted) {
}
if (mounted) {
setState(() {
useGpsLocation = false;
@ -126,6 +138,7 @@ class _NewFlightPageState extends State<NewFlightPage> {
setState(() {
currentPosition = position;
if (_initialMapCentered && _mapController.camera.center != LatLng(position.latitude, position.longitude)) {
_mapController.move(
LatLng(currentPosition!.latitude, currentPosition!.longitude),
@ -134,9 +147,13 @@ class _NewFlightPageState extends State<NewFlightPage> {
}
});
}
if (mounted) {}
if (mounted) {
}
} catch (e) {
if (mounted) {}
if (mounted) {
}
if (mounted) {
setState(() {
useGpsLocation = false;
@ -152,10 +169,12 @@ class _NewFlightPageState extends State<NewFlightPage> {
}
}
void _startFlight() {
final l10n = AppLocalizations.of(context)!;
if (selectedDrone == null || selectedBattery == null) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(l10n.selectDroneBattery)),
);
@ -168,7 +187,10 @@ class _NewFlightPageState extends State<NewFlightPage> {
});
_getCurrentLocation().then((_) {
if (useGpsLocation && currentPosition == null) {
return;
}
@ -179,6 +201,7 @@ class _NewFlightPageState extends State<NewFlightPage> {
}
}
void _proceedToStartFlight() {
final l10n = AppLocalizations.of(context)!;
@ -194,21 +217,26 @@ class _NewFlightPageState extends State<NewFlightPage> {
}
});
});
}
Future<void> _stopFlight() async {
final l10n = AppLocalizations.of(context)!;
stopwatch.stop();
timer?.cancel();
final int flightEndTime = DateTime.now().millisecondsSinceEpoch ~/ 1000;
final Duration flightDuration = stopwatch.elapsed;
final Flight newFlight = Flight(
name:
'${selectedDrone!.name} - ${DateTime.fromMillisecondsSinceEpoch(flightStartTime! * 1000).toLocal().toString().split(' ')[0]}',
name: '${selectedDrone!.name} - ${DateTime.fromMillisecondsSinceEpoch(flightStartTime! * 1000).toLocal().toString().split(' ')[0]}',
startTimestamp: flightStartTime!,
endTimestamp: flightEndTime,
droneId: selectedDrone!.id!,
@ -218,11 +246,17 @@ class _NewFlightPageState extends State<NewFlightPage> {
);
try {
await DbHelper.instance.insertFlight(newFlight);
if (mounted) {}
if (mounted) {
}
} catch (e) {
if (mounted) {}
if (mounted) {
}
} finally {
setState(() {
isFlightActive = false;
stopwatch.reset();
@ -241,6 +275,7 @@ class _NewFlightPageState extends State<NewFlightPage> {
}
}
String _formatDuration(Duration duration) {
String twoDigits(int n) => n.toString().padLeft(2, '0');
String hours = twoDigits(duration.inHours);
@ -252,7 +287,6 @@ class _NewFlightPageState extends State<NewFlightPage> {
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
final colorProvider = Provider.of<ColorProvider>(context);
return Scaffold(
backgroundColor: Theme.of(context).primaryColor,
@ -266,6 +300,7 @@ class _NewFlightPageState extends State<NewFlightPage> {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Text(
l10n.chooseDrone,
style: Theme.of(context).textTheme.headlineSmall,
@ -312,7 +347,7 @@ class _NewFlightPageState extends State<NewFlightPage> {
items: drones.map<DropdownMenuItem<Drone>>((Drone drone) {
return DropdownMenuItem<Drone>(
value: drone,
child: Text(drone.name, style: Theme.of(context).textTheme.titleMedium!.copyWith(color: Colors.white)), // Texte blanc
child: Text(drone.name),
);
}).toList(),
),
@ -322,6 +357,8 @@ class _NewFlightPageState extends State<NewFlightPage> {
),
),
),
Text(
l10n.chooseBattery,
style: Theme.of(context).textTheme.headlineSmall,
@ -368,7 +405,7 @@ class _NewFlightPageState extends State<NewFlightPage> {
items: batteries.map<DropdownMenuItem<Battery>>((Battery battery) {
return DropdownMenuItem<Battery>(
value: battery,
child: Text('${battery.name} (${battery.voltage}V)', style: Theme.of(context).textTheme.titleMedium!.copyWith(color: Colors.white)), // Texte blanc
child: Text('${battery.name} (${battery.voltage}V)'),
);
}).toList(),
),
@ -378,6 +415,8 @@ class _NewFlightPageState extends State<NewFlightPage> {
),
),
),
Card(
margin: const EdgeInsets.only(bottom: 30),
child: ListTile(
@ -401,9 +440,11 @@ class _NewFlightPageState extends State<NewFlightPage> {
},
activeColor: Theme.of(context).colorScheme.primary,
),
leading: Icon(Icons.location_on, color: colorProvider.accentColor),
leading: Icon(Icons.location_on, color: Theme.of(context).colorScheme.secondary),
),
),
if (currentPosition != null && useGpsLocation)
Container(
margin: const EdgeInsets.only(bottom: 20),
@ -420,6 +461,7 @@ class _NewFlightPageState extends State<NewFlightPage> {
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(15),
child: FlutterMap(
mapController: _mapController,
@ -454,9 +496,9 @@ class _NewFlightPageState extends State<NewFlightPage> {
point: LatLng(currentPosition!.latitude, currentPosition!.longitude),
width: 80,
height: 80,
child: Icon(
child: const Icon(
Icons.location_on,
color: colorProvider.accentColor,
color: Colors.red,
size: 40,
),
),
@ -466,26 +508,30 @@ class _NewFlightPageState extends State<NewFlightPage> {
),
),
),
Center(
child: Text(
formattedTime,
style: TextStyle(
style: const TextStyle(
fontSize: 72,
fontWeight: FontWeight.bold,
color: colorProvider.accentColor,
color: Colors.lightBlueAccent,
fontFamily: 'RobotoMono',
),
),
),
const SizedBox(height: 40),
Center(
child: isFlightActive
? ElevatedButton.icon(
onPressed: _stopFlight,
icon: const Icon(Icons.stop, size: 30, color: Colors.white), // Icône blanche
icon: const Icon(Icons.stop, size: 30),
label: Text(
l10n.stopFlight,
style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: Colors.white), // Texte blanc
style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.redAccent,
@ -500,22 +546,21 @@ class _NewFlightPageState extends State<NewFlightPage> {
: (isGettingLocation
? Column(
children: [
CircularProgressIndicator(color: colorProvider.accentColor),
const CircularProgressIndicator(color: Colors.tealAccent),
const SizedBox(height: 10),
Text(l10n.obtainingLocation,
style: Theme.of(context).textTheme.titleSmall),
Text(l10n.obtainingLocation, style: Theme.of(context).textTheme.titleSmall),
],
)
: ElevatedButton.icon(
onPressed: _startFlight,
icon: const Icon(Icons.flight_takeoff, size: 30, color: Colors.white), // Icône blanche
icon: const Icon(Icons.flight_takeoff, size: 30),
label: Text(
l10n.startFlight,
style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold, color: Colors.white), // Texte blanc
style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold),
),
style: ElevatedButton.styleFrom(
backgroundColor: colorProvider.accentColor,
foregroundColor: Theme.of(context).colorScheme.onPrimary,
backgroundColor: Colors.tealAccent,
foregroundColor: Colors.black,
padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 20),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),

View File

@ -1,11 +1,8 @@
// pages/settings_page.dart
import 'package:flutter/material.dart';
import 'package:rtime/l10n/app_localizations.dart';
import 'package:provider/provider.dart';
import 'package:rtime/providers/local_provider.dart';
import 'package:rtime/providers/theme_provider.dart';
import 'package:rtime/providers/color_provider.dart';
import 'package:flutter_colorpicker/flutter_colorpicker.dart';
class SettingsPage extends StatefulWidget {
const SettingsPage({super.key});
@ -15,29 +12,11 @@ class SettingsPage extends StatefulWidget {
}
class _SettingsPageState extends State<SettingsPage> {
// Initialize with a default color or the current accent color
late Color _pickerColor; // Use late to initialize in initState
@override
void initState() {
super.initState();
// Initialize _pickerColor with the current accent color from the ColorProvider
_pickerColor = Provider.of<ColorProvider>(context, listen: false).accentColor;
}
void _onColorChanged(Color color) {
setState(() => _pickerColor = color);
}
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
final currentLocale = Localizations.localeOf(context);
final themeProvider = Provider.of<ThemeProvider>(context);
final colorProvider = Provider.of<ColorProvider>(context);
// REMOVE THIS LINE:
// _pickerColor = colorProvider.accentColor;
return Scaffold(
backgroundColor: Theme.of(context).colorScheme.background,
@ -49,149 +28,97 @@ class _SettingsPageState extends State<SettingsPage> {
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
l10n.languageSetting,
style: Theme.of(context).textTheme.headlineSmall,
),
const SizedBox(height: 10),
Card(
color: Theme.of(context).cardTheme.color,
child: Column(
children: [
ListTile(
title: Text(l10n.english, style: Theme.of(context).textTheme.titleMedium),
trailing: currentLocale.languageCode == 'en'
? Icon(Icons.check_circle, color: Theme.of(context).colorScheme.secondary)
: null,
onTap: () {
final localeProvider = Provider.of<LocaleProvider>(context, listen: false);
localeProvider.setLocale(const Locale('en', ''));
},
),
ListTile(
title: Text(l10n.french, style: Theme.of(context).textTheme.titleMedium),
trailing: currentLocale.languageCode == 'fr'
? Icon(Icons.check_circle, color: Theme.of(context).colorScheme.secondary)
: null,
onTap: () {
final localeProvider = Provider.of<LocaleProvider>(context, listen: false);
localeProvider.setLocale(const Locale('fr', ''));
},
),
],
),
),
const SizedBox(height: 30),
Text(
l10n.themeSetting,
style: Theme.of(context).textTheme.headlineSmall,
),
const SizedBox(height: 10),
Card(
color: Theme.of(context).cardTheme.color,
child: Column(
children: [
ListTile(
title: Text(l10n.themeSystem, style: Theme.of(context).textTheme.titleMedium),
trailing: themeProvider.themeMode == ThemeMode.system
? Icon(Icons.check_circle, color: Theme.of(context).colorScheme.secondary)
: null,
onTap: () {
themeProvider.setThemeMode(ThemeMode.system);
},
),
ListTile(
title: Text(l10n.themeLight, style: Theme.of(context).textTheme.titleMedium),
trailing: themeProvider.themeMode == ThemeMode.light
? Icon(Icons.check_circle, color: Theme.of(context).colorScheme.secondary)
: null,
onTap: () {
themeProvider.setThemeMode(ThemeMode.light);
},
),
ListTile(
title: Text(l10n.themeDark, style: Theme.of(context).textTheme.titleMedium),
trailing: themeProvider.themeMode == ThemeMode.dark
? Icon(Icons.check_circle, color: Theme.of(context).colorScheme.secondary)
: null,
onTap: () {
themeProvider.setThemeMode(ThemeMode.dark);
},
),
],
),
),
const SizedBox(height: 30),
Text(
l10n.customColorSetting,
style: Theme.of(context).textTheme.headlineSmall,
),
const SizedBox(height: 10),
Card(
color: Theme.of(context).cardTheme.color,
child: ListTile(
title: Text(
l10n.selectButtonColor,
style: Theme.of(context).textTheme.titleMedium,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
l10n.languageSetting,
style: Theme.of(context).textTheme.headlineSmall,
),
const SizedBox(height: 10),
Card(
color: Theme.of(context).cardTheme.color,
child: Column(
children: [
ListTile(
title: Text(l10n.english, style: Theme.of(context).textTheme.titleMedium),
trailing: currentLocale.languageCode == 'en'
? Icon(Icons.check_circle, color: Theme.of(context).colorScheme.secondary)
: null,
onTap: () {
final localeProvider = Provider.of<LocaleProvider>(context, listen: false);
localeProvider.setLocale(const Locale('en', ''));
},
),
trailing: Container(
width: 30,
height: 30,
decoration: BoxDecoration(
// This should always reflect the current accent color from the provider
color: colorProvider.accentColor,
shape: BoxShape.circle,
border: Border.all(color: Theme.of(context).dividerColor),
),
ListTile(
title: Text(l10n.french, style: Theme.of(context).textTheme.titleMedium),
trailing: currentLocale.languageCode == 'fr'
? Icon(Icons.check_circle, color: Theme.of(context).colorScheme.secondary)
: null,
onTap: () {
final localeProvider = Provider.of<LocaleProvider>(context, listen: false);
localeProvider.setLocale(const Locale('fr', ''));
},
),
onTap: () {
// When the dialog is opened, ensure _pickerColor reflects the *current* accent color
// so that the color picker starts with the color currently in use.
setState(() {
_pickerColor = colorProvider.accentColor;
});
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text(l10n.pickColor),
content: SingleChildScrollView(
child: ColorPicker(
pickerColor: _pickerColor,
onColorChanged: _onColorChanged,
pickerAreaHeightPercent: 0.8,
enableAlpha: false,
displayThumbColor: true,
paletteType: PaletteType.hsv,
),
),
actions: <Widget>[
TextButton(
child: Text(l10n.cancel),
onPressed: () {
Navigator.of(context).pop();
},
),
TextButton(
child: Text(l10n.select),
onPressed: () {
colorProvider.setAccentColor(_pickerColor);
Navigator.of(context).pop();
},
),
],
);
},
);
},
),
],
),
],
),
),
const SizedBox(height: 30),
Text(
l10n.themeSetting,
style: Theme.of(context).textTheme.headlineSmall,
),
const SizedBox(height: 10),
Card(
color: Theme.of(context).cardTheme.color,
child: Column(
children: [
ListTile(
title: Text(l10n.themeSystem, style: Theme.of(context).textTheme.titleMedium),
trailing: themeProvider.themeMode == ThemeMode.system
? Icon(Icons.check_circle, color: Theme.of(context).colorScheme.secondary)
: null,
onTap: () {
themeProvider.setThemeMode(ThemeMode.system);
},
),
ListTile(
title: Text(l10n.themeLight, style: Theme.of(context).textTheme.titleMedium),
trailing: themeProvider.themeMode == ThemeMode.light
? Icon(Icons.check_circle, color: Theme.of(context).colorScheme.secondary)
: null,
onTap: () {
themeProvider.setThemeMode(ThemeMode.light);
},
),
ListTile(
title: Text(l10n.themeDark, style: Theme.of(context).textTheme.titleMedium),
trailing: themeProvider.themeMode == ThemeMode.dark
? Icon(Icons.check_circle, color: Theme.of(context).colorScheme.secondary)
: null,
onTap: () {
themeProvider.setThemeMode(ThemeMode.dark);
},
),
],
),
),
],
),
),
);

View File

@ -1,31 +0,0 @@
// providers/color_provider.dart
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class ColorProvider extends ChangeNotifier {
Color _accentColor = Colors.blue.shade600;
Color get accentColor => _accentColor;
ColorProvider() {
_loadAccentColor();
}
void _loadAccentColor() async {
final prefs = await SharedPreferences.getInstance();
final int? colorValue = prefs.getInt('customAccentColor');
if (colorValue != null) {
_accentColor = Color(colorValue);
}
notifyListeners();
}
void setAccentColor(Color color) async {
if (_accentColor != color) {
_accentColor = color;
notifyListeners();
final prefs = await SharedPreferences.getInstance();
await prefs.setInt('customAccentColor', color.value);
}
}
}

View File

@ -1,4 +1,3 @@
// providers/local_provider.dart
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
@ -7,10 +6,12 @@ class LocaleProvider extends ChangeNotifier {
Locale? get locale => _locale;
LocaleProvider() {
_loadLocale();
}
void _loadLocale() async {
final prefs = await SharedPreferences.getInstance();
final languageCode = prefs.getString('languageCode');
@ -24,12 +25,14 @@ class LocaleProvider extends ChangeNotifier {
notifyListeners();
}
void setLocale(Locale newLocale) async {
if (_locale == newLocale) return;
_locale = newLocale;
notifyListeners();
final prefs = await SharedPreferences.getInstance();
await prefs.setString('languageCode', newLocale.languageCode);
if (newLocale.countryCode != null) {
@ -39,6 +42,7 @@ class LocaleProvider extends ChangeNotifier {
}
}
void clearLocale() async {
_locale = null;
notifyListeners();

View File

@ -1,4 +1,3 @@
// providers/theme_provider.dart
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';

View File

@ -1,83 +0,0 @@
import os
import sys
import re
def clean_comments_in_file(filepath):
"""
Supprime le reste de la ligne à partir de '//' dans un fichier donné,
en essayant d'éviter les URL. Gère aussi les commentaires /* ... */.
"""
try:
with open(filepath, 'r', encoding='utf-8') as f_read:
content = f_read.read()
# Première passe : supprimer les commentaires /* ... */
# Utilise re.DOTALL pour que . corresponde aussi aux retours à la ligne
# et non-greedy quantifier *?
content = re.sub(r'/\*.*?\*/', '', content, flags=re.DOTALL)
cleaned_lines = []
for line in content.splitlines():
# Vérifie si la ligne contient une URL avant de chercher un commentaire
if re.search(r'https?://', line):
# Si une URL est trouvée, nous sommes très prudents.
# Nous ne supprimons les commentaires que s'ils sont CLAIREMENT après une URL et non mélangés
# Cela reste une heuristique et n'est pas parfait.
comment_index = line.find('//')
if comment_index != -1 and not re.search(r'["\']https?://.*?//', line): # Évite les // dans les URLs entre guillemets
# On tente de voir si le commentaire est vraiment à la fin de la ligne,
# après d'éventuelles guillemets.
# Ceci est une simplification et peut encore échouer.
if comment_index > line.rfind('"') and comment_index > line.rfind("'"):
cleaned_lines.append(line[:comment_index].rstrip())
else:
cleaned_lines.append(line) # Conserve la ligne si le // est potentiellement dans une chaîne/URL
else:
cleaned_lines.append(line)
else:
# Si pas d'URL, on peut être plus agressif avec les //
if '//' in line:
index = line.find('//')
cleaned_lines.append(line[:index].rstrip())
else:
cleaned_lines.append(line)
# Rejoindre les lignes avec des retours à la ligne.
# Ajoute un retour à la ligne final si le fichier en avait un.
final_content = '\n'.join(cleaned_lines)
if content.endswith('\n') and not final_content.endswith('\n'):
final_content += '\n'
with open(filepath, 'w', encoding='utf-8') as f_write:
f_write.write(final_content)
print(f"Commentaires nettoyés dans : {filepath}")
except Exception as e:
print(f"Erreur lors du traitement de {filepath} : {e}")
def main():
if len(sys.argv) < 2:
print("Usage: python clean_comments.py <path_to_directory>")
print("Exemple: python clean_comments.py ./mon_projet_flutter")
sys.exit(1)
target_directory = sys.argv[1]
if not os.path.isdir(target_directory):
print(f"Erreur : Le chemin '{target_directory}' n'est pas un répertoire valide.")
sys.exit(1)
print(f"Nettoyage des commentaires '//' et '/* ... */' dans le répertoire : {target_directory}")
print("-" * 70)
for root, _, files in os.walk(target_directory):
for file in files:
filepath = os.path.join(root, file)
# Filtrez les types de fichiers que vous souhaitez traiter
if filepath.endswith(('.dart', '.js', '.ts', '.java', '.cpp', '.c', '.h', '.py')):
clean_comments_in_file(filepath)
print("-" * 70)
print("Nettoyage terminé.")
if __name__ == "__main__":
main()

View File

@ -270,14 +270,6 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_colorpicker:
dependency: "direct main"
description:
name: flutter_colorpicker
sha256: "969de5f6f9e2a570ac660fb7b501551451ea2a1ab9e2097e89475f60e07816ea"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
flutter_lints:
dependency: "direct dev"
description:

View File

@ -30,7 +30,7 @@ environment:
dependencies:
flutter:
sdk: flutter
flutter_colorpicker: ^1.0.0
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.8

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 10 KiB