// ignore: unused_import import 'package:collection/collection.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:gap/gap.dart'; import 'package:go_router/go_router.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:hive_flutter/hive_flutter.dart'; import 'package:jiffy/jiffy.dart'; import 'package:super_sliver_list/super_sliver_list.dart'; import 'package:tp5/core/basic_page.dart'; import 'package:tp5/core/utils.dart'; import 'package:tp5/csv/data.dart'; import 'package:tp5/flightslist/w_flt.dart'; import 'package:tp5/fltinfo/view/fltinfo_page.dart'; import 'package:tp5/roster/widgets/w_day.dart'; class FlightslistPage extends ConsumerStatefulWidget { const FlightslistPage({super.key}); @override ConsumerState createState() => _FlightslistPageState(); } class _FlightslistPageState extends ConsumerState { final _listController = ListController(); final _scrollController = ScrollController(); void scrolltonow() { final jumpindex = _aclegs.indexWhere((e) => e.jdep!.isSameOrAfter(_now)); if (jumpindex >= 0) { jumpToItem(jumpindex); } } void jumpToItem(int index) { try { if (_listController.isAttached && _scrollController.hasClients) { _listController.jumpToItem( //duration: (d) => const Duration(milliseconds: 700), index: index, scrollController: _scrollController, alignment: 0.75, //curve: (double estimatedDistance) => Curves.decelerate, ); } } catch (e) { print("flistlistpage: jumptoitemscroll controller"); } } bool showAllLegs = false; bool showInflightOnly = false; // bool _isfirstInDay(Acleg leg) => // leg == _aclegs.firstWhereOrNull((e) => (e.jdep?.yMEd == leg.jdep?.yMEd)); Widget get _acLegsWidget => Container( child: _aclegs.isEmpty ? const Text("No leg found !") : SuperListView.builder( delayPopulatingCacheArea: true, listController: _listController, controller: _scrollController, itemCount: _aclegs.length, itemBuilder: (context, index) { final leg = _aclegs.elementAt(index); return Column( children: [ // if (_isfirstInDay(leg)) if (index == 0 || leg.jdep?.yMEd != _aclegs.elementAt(index - 1).jdep?.yMEd) WDay( date: leg.jdep!, highlight: _now.yMEd == leg.jdep?.yMEd), InkWell( onTap: () => context.push("/fltinfo", extra: FltinfoParams( al: leg.FN_CARRIER, fnum: leg.FN_NUMBER, jdep: leg.jdep, jdes: leg.jarr, dep: leg.DEP_AP_ACTUAL, des: leg.ARR_AP_SCHED, )), child: WFlt(acleg: leg)), ], ); }, )); final bottomnavstyle = ElevatedButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5.0), ), backgroundColor: const Color.fromARGB(255, 0, 36, 53) //elevated btton background color ); TextEditingController ctrldep = TextEditingController(); TextEditingController ctrldes = TextEditingController(); TextEditingController ctrlairline = TextEditingController(); TextEditingController ctrlfnum = TextEditingController(); Widget _flightFilter(BuildContext context) { return Container( padding: const EdgeInsets.all(20), child: Column(mainAxisSize: MainAxisSize.min, children: [ Row( children: [ Expanded( child: TextField( decoration: const InputDecoration(labelText: "Departure Airport"), maxLength: 3, // Set maximum length controller: ctrldep, ), ), const SizedBox(width: 10), Expanded( child: TextField( decoration: const InputDecoration(labelText: "Arrival Airport"), maxLength: 3, // Set maximum length controller: ctrldes, ), ), ], ), const SizedBox(height: 15), Row( children: [ Expanded( child: TextField( controller: ctrlairline, decoration: const InputDecoration(labelText: "Airline IATA code"), maxLength: 2, // Set maximum length ), ), const SizedBox(width: 10), Expanded( child: TextField( controller: ctrlfnum, decoration: const InputDecoration(labelText: "Flight number"), maxLength: 6, // Set maximum length ), ), ], ), const SizedBox(height: 15), const SizedBox(height: 35), SizedBox( width: 360, child: ElevatedButton( onPressed: () async => Navigator.pop(context, { "dep": ctrldep.text.toUpperCase(), "des": ctrldes.text.toUpperCase(), "al": ctrlairline.text.toUpperCase(), "fnum": ctrlfnum.text.toUpperCase() }), // Close the bottom sheet style: ElevatedButton.styleFrom( backgroundColor: Colors.green, // Set button color to green shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15), // Add rounded corners ), padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 15), ), child: const Text( 'Flight filter', style: TextStyle(fontSize: 18, color: Colors.white), ), ), ), ])); } Map flightFilter = { "dep": "", "des": "", "al": "", "fnum": "" }; void _loadSearchFlights() { showInflightOnly = Hive.box("settings") .get("flightslist.filter.inflightonly", defaultValue: false); final filter = Hive.box("settings") .get("flightslist.filter.flights", defaultValue: {}); // print("flightslist: loadsearchflights: saved: $filter"); if (filter is Map) { for (var e in filter.keys) { flightFilter[e] = filter[e] ?? ""; } } } void _searchFlights(xcontext) async { ctrldep.text = flightFilter["dep"] ?? ""; ctrldes.text = flightFilter["des"] ?? ""; ctrlairline.text = flightFilter["al"] ?? ""; ctrlfnum.text = flightFilter["fnum"] ?? ""; final res = await showModalBottomSheet( context: context, builder: (context) => _flightFilter(xcontext)); if (res is Map) { Hive.box("settings").put("flightslist.filter.flights", (res)); setState(() { flightFilter = res; }); } } @override void initState() { _loadSearchFlights(); Future.delayed(const Duration(milliseconds: 700)).then((x) { scrolltonow(); }); super.initState(); } List _allAclegs = []; List get _aclegs => _allAclegs .where((leg) => (!showInflightOnly || (showInflightOnly && (leg.flt_status == "Inflight" || leg.flt_status == "Taxiout"))) && ((flightFilter["al"] == "" || leg.FN_CARRIER == flightFilter["al"]) && (flightFilter["fnum"] == "" || leg.FN_NUMBER == flightFilter["fnum"]) && (flightFilter["dep"] == "" || leg.DEP_AP_ACTUAL == flightFilter["dep"] || leg.DEP_SCHED_DT == flightFilter["dep"]) && (flightFilter["des"] == "" || leg.ARR_AP_ACTUAL == flightFilter["des"] || leg.ARR_AP_SCHED == flightFilter["des"]))) .toList(); Jiffy _now = Jiffy.now(); @override Widget build(BuildContext context) { final data = ref.watch(dataProvider); _allAclegs = data.acleg; _now = ref.watch(clockProvider); return BasicPage( appBar: AppBar( title: const Text('Flights List'), ), body: Center( child: Column( children: [ Expanded(child: _acLegsWidget), Row( mainAxisAlignment: MainAxisAlignment.end, children: [ data.aclegupdate != null ? Text("data retrieved ${data.aclegupdate?.from(_now)}", style: GoogleFonts.robotoMono( fontSize: 10, fontWeight: FontWeight.w300)) : Text("no data found", style: GoogleFonts.robotoMono( fontSize: 10, fontWeight: FontWeight.w300)) ], ) ], ), ), actions: [], bottomNavigationBar: Container( padding: const EdgeInsets.all(8), // color: Colors.black, decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Colors.grey[700]!, Colors.black, ], )), child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ ElevatedButton.icon( onPressed: () async { showInflightOnly = !showInflightOnly; setState(() {}); Future.delayed(Duration(milliseconds: 200)).then((x) { scrolltonow(); }); await Hive.box("settings") .put("flightslist.filter.inflightonly", showInflightOnly); }, icon: showInflightOnly ? Icon(Icons.flight_takeoff) : Icon(Icons.all_out), label: showInflightOnly ? Text("Inflight\nonly") : Text("All flight\nstatus"), style: bottomnavstyle, ), const Gap(10), Row( children: [ ElevatedButton.icon( onPressed: () { _searchFlights(context); }, icon: const Icon(Icons.manage_search), label: const Text("Filter\nFlights"), style: bottomnavstyle, ), const Gap(10), Column( mainAxisSize: MainAxisSize.min, children: flightFilter.keys .where((e) => flightFilter[e] != "") .map((e) => Text( "$e: ${flightFilter[e]}", style: const TextStyle( fontSize: 12, color: Colors.yellow), )) .toList()), const Gap(10), if (flightFilter.values.any((e) => e != "")) Badge( label: Text(flightFilter.values .where((e) => e != "") .length .toString()), child: IconButton.outlined( onPressed: () { for (var k in flightFilter.keys) { flightFilter[k] = ""; } Hive.box("settings") .delete("flightslist.filter.flights"); setState(() {}); }, icon: const Icon(Icons.filter_alt_off_rounded, size: 18)), ) ], ), ], ), ), ); } }