import 'package:flutter/widgets.dart'; import 'package:info_tren/components/select_train_suggestions/select_train_suggestions_cupertino.dart'; import 'package:info_tren/components/select_train_suggestions/select_train_suggestions_material.dart'; import 'package:info_tren/models.dart'; import 'package:info_tren/utils/default_ui_design.dart'; class SelectTrainSuggestions extends StatefulWidget { final UiDesign? uiDesign; final List choices; final String? currentInput; final void Function(String trainNumber) onTrainSelected; const SelectTrainSuggestions({Key? key, required this.uiDesign, required this.choices, this.currentInput, required this.onTrainSelected }) : super(key: key); @override SelectTrainSuggestionsState createState() { final uiDesign = this.uiDesign ?? defaultUiDesign; switch(uiDesign) { case UiDesign.MATERIAL: return SelectTrainSuggestionsStateMaterial(); case UiDesign.CUPERTINO: return SelectTrainSuggestionsStateCupertino(); default: throw UnmatchedUiDesignException(uiDesign); } } } abstract class SelectTrainSuggestionsState extends State { String getUseCurrentInputWidgetText(String currentInput) => 'Caută trenul cu numărul ${widget.currentInput}'; Widget getUseCurrentInputWidget(String currentInput, void Function(String) onTrainSelected); @override Widget build(BuildContext context) { var slivers = widget.choices.map((c) => c.company).toSet().map((operator) => OperatorAutocompleteSliver( uiDesign: widget.uiDesign, operatorName: operator, trains: widget.choices.where((c) => c.company == operator).toList(), onTrainSelected: widget.onTrainSelected, )).toList(); return CustomScrollView( slivers: [ ...slivers, SliverToBoxAdapter( child: widget.currentInput != null && int.tryParse(widget.currentInput!) != null ? getUseCurrentInputWidget(widget.currentInput!, widget.onTrainSelected) : Container(), ), SliverToBoxAdapter( child: Container( height: MediaQuery.of(context).viewPadding.bottom, ), ), ], ); } } class OperatorAutocompleteSliver extends StatelessWidget { final UiDesign? uiDesign; final String operatorName; final List trains; final void Function(String) onTrainSelected; const OperatorAutocompleteSliver({ Key? key, required this.uiDesign, required this.operatorName, required this.trains, required this.onTrainSelected }) : super(key: key); Widget mapTrainToItem(TrainsResult train) { final uiDesign = this.uiDesign ?? defaultUiDesign; switch (uiDesign) { case UiDesign.MATERIAL: return OperatorAutocompleteTileMaterial( onTrainSelected: onTrainSelected, operatorName: operatorName, train: train, ); case UiDesign.CUPERTINO: return OperatorAutocompleteTileCupertino( onTrainSelected: onTrainSelected, operatorName: operatorName, train: train, ); default: throw UnmatchedUiDesignException(uiDesign); } } @override Widget build(BuildContext context) { if (trains.isEmpty) { return SliverToBoxAdapter(child: Container(),); } return SliverPrototypeExtentList( prototypeItem: Column( children: [ mapTrainToItem(const TrainsResult(company: 'Company', number: '123', rank: 'R')), ], ), delegate: SliverChildBuilderDelegate( (context, index) { return Column( children: [ mapTrainToItem(trains[index]), ], ); }, childCount: trains.length, addSemanticIndexes: true, ), ); } } abstract class OperatorAutocompleteTile extends StatelessWidget { final String operatorName; final TrainsResult train; final void Function(String) onTrainSelected; const OperatorAutocompleteTile({ Key? key, required this.onTrainSelected, required this.operatorName, required this.train }) : super(key: key); }