w_lidoflt.dart 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. import 'package:flutter/material.dart';
  2. import 'package:gap/gap.dart';
  3. import 'package:jiffy/jiffy.dart';
  4. import 'package:tp5/core/utils.dart';
  5. import 'package:tp5/lido/model/Lidoapi_list.dart';
  6. import 'package:tp5/roster/widgets/w_citypair.dart';
  7. import 'package:tp5/roster/widgets/w_fnum.dart';
  8. import 'package:tp5/roster/widgets/w_hour.dart';
  9. import 'package:tp5/widgets/my_row.dart';
  10. class WLidoflt extends StatelessWidget {
  11. const WLidoflt(
  12. {super.key, required this.lidoapilist, this.onTap, this.iata = true});
  13. final LidoapiList lidoapilist;
  14. final bool iata;
  15. final dynamic onTap;
  16. _estDepTime() => Column(
  17. children: [
  18. Text(
  19. Jiffy.parseFromMillisecondsSinceEpoch(
  20. lidoapilist.leg?.estimatedDepartureTime ?? 0,
  21. isUtc: true)
  22. .format(pattern: "ddMMMyy"),
  23. style: const TextStyle(fontSize: 12, color: Colors.grey),
  24. ),
  25. WHour(
  26. jiffy: Jiffy.parseFromMillisecondsSinceEpoch(
  27. lidoapilist.leg?.estimatedDepartureTime ?? 0,
  28. isUtc: true)),
  29. ],
  30. );
  31. _fnumCitypair() => Row(
  32. children: [
  33. WFnum(
  34. al: iata
  35. ? (lidoapilist.leg?.commercialAirlineIata ?? "++")
  36. : (lidoapilist.leg?.commercialAirlineIcao ?? "+++"),
  37. fnum: lidoapilist.leg?.flightNumber ?? "---"),
  38. const Gap(10),
  39. WCitypair(
  40. iata1: iata
  41. ? (lidoapilist.leg?.departureAirport ?? "---")
  42. : (lidoapilist.leg?.departureAirportIcao ?? "----"),
  43. iata2: iata
  44. ? (lidoapilist.leg?.destinationAirport ?? "---")
  45. : (lidoapilist.leg?.destinationAirportIcao ?? "----"),
  46. size: 14,
  47. )
  48. ],
  49. );
  50. _aircraft() => Row(children: [
  51. Text(lidoapilist.leg?.aircraftDetails?.aircraftIcaoType ?? "---",
  52. style: const TextStyle(
  53. color: Colors.grey, fontWeight: FontWeight.w600)),
  54. const Gap(10),
  55. Text(
  56. lidoapilist.leg?.aircraftDetails?.aircraftRegistration ?? "---",
  57. style: const TextStyle(fontSize: 14, color: Colors.yellow),
  58. ),
  59. ]);
  60. _schedCtot() => Row(
  61. children: [
  62. if (lidoapilist.leg?.estimatedDepartureTime !=
  63. lidoapilist.leg?.scheduledDepartureTime) ...[
  64. const Text(
  65. "Sched",
  66. style: TextStyle(color: Colors.white38, fontSize: 10),
  67. ),
  68. const Gap(5),
  69. WHour(
  70. jiffy: Jiffy.parseFromMillisecondsSinceEpoch(
  71. lidoapilist.leg?.scheduledDepartureTime ?? 0,
  72. isUtc: true),
  73. size: 12,
  74. color: Colors.grey[500],
  75. ),
  76. const Gap(10)
  77. ],
  78. if (lidoapilist.leg?.ctot != null) ...[
  79. const Text(
  80. "CTOT ",
  81. style: TextStyle(color: Colors.white24, fontSize: 10),
  82. ),
  83. WHour(
  84. jiffy: Jiffy.parseFromMillisecondsSinceEpoch(
  85. lidoapilist.leg?.ctot ?? 0,
  86. isUtc: true),
  87. size: 12,
  88. color: Colors.orange,
  89. )
  90. ]
  91. ],
  92. );
  93. _fuel() => Column(crossAxisAlignment: CrossAxisAlignment.end, children: [
  94. Text(
  95. "ZFW ${kilo2ton(lidoapilist.leg?.weight?.plannedZfw)}",
  96. style: const TextStyle(color: Colors.grey),
  97. ),
  98. Column(
  99. children: [
  100. Text(
  101. "Fuel ${kilo2ton(lidoapilist.leg?.fuel?.blockFuel)}",
  102. style: const TextStyle(
  103. color: Colors.cyan, fontWeight: FontWeight.w700),
  104. ),
  105. Text(
  106. "Max xtra +${kilo2ton(lidoapilist.leg?.fuel?.possibleExtra, ceil: true)}",
  107. style: const TextStyle(color: Colors.amber, fontSize: 10),
  108. ),
  109. ],
  110. ),
  111. Text(
  112. "Trip ${kilo2ton(lidoapilist.leg?.fuel?.tripFuel)} / ${Duration(minutes: lidoapilist.leg?.fuel?.totalTripTimeMinutes ?? 0).tohhmm}",
  113. style: const TextStyle(
  114. color: Colors.green, fontWeight: FontWeight.w600, fontSize: 10),
  115. ),
  116. // Text("Trip ${kilo2ton(lidoapilist.leg?.fuel?.tripFuel)}"),
  117. ]);
  118. _ofpVer() => Column(crossAxisAlignment: CrossAxisAlignment.center, children: [
  119. Text(
  120. "OFP ${lidoapilist.leg?.ofpNumber}",
  121. style: const TextStyle(
  122. color: Colors.white54, fontWeight: FontWeight.w600),
  123. ),
  124. Text(
  125. // ignore: unnecessary_string_interpolations
  126. "${Jiffy.parseFromMillisecondsSinceEpoch(lidoapilist.lastGenerated ?? 0, isUtc: true).format(pattern: "ddMMMyy")}",
  127. style: const TextStyle(color: Colors.white, fontSize: 12),
  128. ),
  129. Text(
  130. // ignore: unnecessary_string_interpolations
  131. "${Jiffy.parseFromMillisecondsSinceEpoch(lidoapilist.lastGenerated ?? 0, isUtc: true).format(pattern: "HH:mm")}",
  132. style: const TextStyle(color: Colors.white70, fontSize: 14),
  133. ),
  134. ]);
  135. _crew() => Row(children: [
  136. const Text("Crew: ",
  137. style: TextStyle(fontSize: 10, color: Colors.white30)),
  138. if (lidoapilist.leg?.crewMembers.isNotEmpty ?? false)
  139. Text(
  140. "${lidoapilist.leg?.crewMembers.map((e) => e.name?.capitalize())}",
  141. style: const TextStyle(
  142. color: Colors.white60,
  143. fontWeight: FontWeight.w400,
  144. fontSize: 12),
  145. )
  146. else
  147. const Text("-----"),
  148. ]);
  149. _fuelOrder() => Row(
  150. children: [
  151. const Text("Fuel order: ",
  152. style: TextStyle(fontSize: 10, color: Colors.white30)),
  153. Text(
  154. "${lidoapilist.latestFuelOrder["fuelOrder"]}",
  155. style: const TextStyle(
  156. color: Colors.white60,
  157. fontWeight: FontWeight.w400,
  158. fontSize: 12),
  159. ),
  160. Text(
  161. " by ${lidoapilist.latestFuelOrder["source"]}",
  162. style: const TextStyle(
  163. color: Colors.white54,
  164. fontWeight: FontWeight.w300,
  165. fontSize: 12),
  166. ),
  167. ],
  168. );
  169. @override
  170. Widget build(BuildContext context) {
  171. return InkWell(
  172. onTap: onTap,
  173. child: Card(
  174. color: Colors.grey[900],
  175. shape: RoundedRectangleBorder(
  176. borderRadius: BorderRadius.circular(6.0),
  177. ),
  178. elevation: 8.0,
  179. margin: const EdgeInsets.symmetric(horizontal: 10.0, vertical: 6.0),
  180. child: Padding(
  181. padding: const EdgeInsets.all(8.0),
  182. child: MyRow(crossAxisAlignment: CrossAxisAlignment.start, children: [
  183. _estDepTime(),
  184. const Gap(20),
  185. Column(
  186. children: [
  187. Row(children: [
  188. Column(
  189. crossAxisAlignment: CrossAxisAlignment.start,
  190. children: [
  191. _fnumCitypair(),
  192. _aircraft(),
  193. _schedCtot(),
  194. ],
  195. ),
  196. const Gap(20),
  197. _fuel(),
  198. const Gap(20),
  199. _ofpVer(),
  200. ]),
  201. const Gap(5),
  202. Row(
  203. crossAxisAlignment: CrossAxisAlignment.start,
  204. mainAxisAlignment: MainAxisAlignment.start,
  205. children: [
  206. _crew(),
  207. if (lidoapilist.latestFuelOrder != null) _fuelOrder(),
  208. ],
  209. ),
  210. ],
  211. )
  212. ]),
  213. ),
  214. ),
  215. );
  216. }
  217. kilo2ton(int? k, {bool ceil = true}) {
  218. if (k == null) return null;
  219. const double conversionFactor = 0.001;
  220. double tons = k * conversionFactor;
  221. if (ceil) {
  222. return "${double.parse(((tons * 10).ceilToDouble() / 10).toStringAsFixed(1))}T";
  223. } else {
  224. return "${double.parse(((tons * 10).floorToDouble() / 10).toStringAsFixed(1))}T";
  225. }
  226. }
  227. }