Link between front-end and back-end
This commit is contained in:
87
lib/widgets/battery_card.dart
Normal file
87
lib/widgets/battery_card.dart
Normal file
@ -0,0 +1,87 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rtime/models/battery.dart';
|
||||
import 'package:rtime/images_manager.dart';
|
||||
|
||||
class BatteryCard extends StatelessWidget {
|
||||
final Battery battery;
|
||||
final VoidCallback? onTap;
|
||||
|
||||
const BatteryCard({
|
||||
super.key,
|
||||
required this.battery,
|
||||
this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final BorderRadius cardBorderRadius =
|
||||
Theme.of(context).cardTheme.shape is RoundedRectangleBorder
|
||||
? (Theme.of(context).cardTheme.shape as RoundedRectangleBorder).borderRadius as BorderRadius
|
||||
: BorderRadius.circular(12);
|
||||
|
||||
return Card(
|
||||
margin: const EdgeInsets.only(right: 16),
|
||||
child: InkWell(
|
||||
onTap: onTap,
|
||||
borderRadius: cardBorderRadius,
|
||||
child: ClipRRect(
|
||||
borderRadius: cardBorderRadius,
|
||||
child: SizedBox(
|
||||
width: 140,
|
||||
height: 170,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 80,
|
||||
height: 80,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.blueGrey[700]
|
||||
: Colors.grey[200],
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: battery.imageUuid != null && battery.imageUuid!.isNotEmpty
|
||||
? FutureBuilder<Image?>(
|
||||
future: ImagesManager.instance.loadImage(battery.imageUuid!),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const Center(child: CircularProgressIndicator(color: Colors.tealAccent));
|
||||
} else if (snapshot.hasError || !snapshot.hasData || snapshot.data == null) {
|
||||
return Icon(Icons.broken_image, size: 50, color: Colors.blueGrey[400]);
|
||||
} else {
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: snapshot.data!,
|
||||
);
|
||||
}
|
||||
},
|
||||
)
|
||||
: Icon(Icons.battery_charging_full, size: 50, color: Theme.of(context).brightness == Brightness.dark ? Colors.tealAccent : Colors.green.shade400),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
battery.name,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
Text(
|
||||
'${battery.voltage}V - ${battery.type}',
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(color: Theme.of(context).brightness == Brightness.dark ? Colors.white70 : Colors.black54),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
82
lib/widgets/drone_cart.dart
Normal file
82
lib/widgets/drone_cart.dart
Normal file
@ -0,0 +1,82 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:rtime/models/drone.dart';
|
||||
import 'package:rtime/images_manager.dart';
|
||||
|
||||
class DroneCard extends StatelessWidget {
|
||||
final Drone drone;
|
||||
final VoidCallback? onTap;
|
||||
|
||||
const DroneCard({
|
||||
super.key,
|
||||
required this.drone,
|
||||
this.onTap,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
final BorderRadius cardBorderRadius =
|
||||
Theme.of(context).cardTheme.shape is RoundedRectangleBorder
|
||||
? (Theme.of(context).cardTheme.shape as RoundedRectangleBorder).borderRadius as BorderRadius
|
||||
: BorderRadius.circular(12);
|
||||
|
||||
return Card(
|
||||
margin: const EdgeInsets.only(right: 16),
|
||||
|
||||
child: InkWell(
|
||||
onTap: onTap,
|
||||
|
||||
borderRadius: cardBorderRadius,
|
||||
child: ClipRRect(
|
||||
borderRadius: cardBorderRadius,
|
||||
child: SizedBox(
|
||||
width: 140,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Container(
|
||||
width: 80,
|
||||
height: 80,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).brightness == Brightness.dark
|
||||
? Colors.blueGrey[700]
|
||||
: Colors.grey[200],
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: drone.imageUuid != null && drone.imageUuid!.isNotEmpty
|
||||
? FutureBuilder<Image?>(
|
||||
future: ImagesManager.instance.loadImage(drone.imageUuid!),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return const Center(child: CircularProgressIndicator(color: Colors.lightBlueAccent));
|
||||
} else if (snapshot.hasError || !snapshot.hasData || snapshot.data == null) {
|
||||
return Icon(Icons.broken_image, size: 50, color: Colors.blueGrey[400]);
|
||||
} else {
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
child: snapshot.data!,
|
||||
);
|
||||
}
|
||||
},
|
||||
)
|
||||
: Icon(Icons.airplanemode_active, size: 50, color: Theme.of(context).brightness == Brightness.dark ? Colors.lightBlueAccent : Colors.blue.shade400),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
drone.name,
|
||||
textAlign: TextAlign.center,
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
88
lib/widgets/page_transition_animations.dart
Normal file
88
lib/widgets/page_transition_animations.dart
Normal file
@ -0,0 +1,88 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
||||
class FadePageRoute extends PageRouteBuilder {
|
||||
final Widget page;
|
||||
FadePageRoute({required this.page})
|
||||
: super(
|
||||
pageBuilder: (
|
||||
BuildContext context,
|
||||
Animation<double> animation,
|
||||
Animation<double> secondaryAnimation,
|
||||
) =>
|
||||
page,
|
||||
transitionsBuilder: (
|
||||
BuildContext context,
|
||||
Animation<double> animation,
|
||||
Animation<double> secondaryAnimation,
|
||||
Widget child,
|
||||
) =>
|
||||
FadeTransition(
|
||||
opacity: animation,
|
||||
child: child,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
class SlideRightPageRoute extends PageRouteBuilder {
|
||||
final Widget page;
|
||||
SlideRightPageRoute({required this.page})
|
||||
: super(
|
||||
pageBuilder: (
|
||||
BuildContext context,
|
||||
Animation<double> animation,
|
||||
Animation<double> secondaryAnimation,
|
||||
) =>
|
||||
page,
|
||||
transitionsBuilder: (
|
||||
BuildContext context,
|
||||
Animation<double> animation,
|
||||
Animation<double> secondaryAnimation,
|
||||
Widget child,
|
||||
) {
|
||||
const begin = Offset(1.0, 0.0);
|
||||
const end = Offset.zero;
|
||||
const curve = Curves.ease;
|
||||
|
||||
var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
|
||||
|
||||
return SlideTransition(
|
||||
position: animation.drive(tween),
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
class SlideUpPageRoute extends PageRouteBuilder {
|
||||
final Widget page;
|
||||
SlideUpPageRoute({required this.page})
|
||||
: super(
|
||||
pageBuilder: (
|
||||
BuildContext context,
|
||||
Animation<double> animation,
|
||||
Animation<double> secondaryAnimation,
|
||||
) =>
|
||||
page,
|
||||
transitionsBuilder: (
|
||||
BuildContext context,
|
||||
Animation<double> animation,
|
||||
Animation<double> secondaryAnimation,
|
||||
Widget child,
|
||||
) {
|
||||
const begin = Offset(0.0, 1.0);
|
||||
const end = Offset.zero;
|
||||
const curve = Curves.easeOut;
|
||||
|
||||
var tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
|
||||
|
||||
return SlideTransition(
|
||||
position: animation.drive(tween),
|
||||
child: child,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user