You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
4.5 KiB

import 'package:flutter/widgets.dart';
import 'package:hooks_riverpod/hooks_riverpod.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/providers.dart';
import 'package:info_tren/utils/default_ui_design.dart';
class SelectTrainSuggestions extends ConsumerWidget {
final List<TrainsResult> choices;
final String? currentInput;
final void Function(String trainNumber) onTrainSelected;
const SelectTrainSuggestions({required this.choices, this.currentInput, required this.onTrainSelected, super.key, });
@override
Widget build(BuildContext context, WidgetRef ref) {
final uiDesign = ref.watch(uiDesignProvider);
switch(uiDesign) {
case UiDesign.MATERIAL:
return SelectTrainSuggestionsMaterial(
choices: choices,
onTrainSelected: onTrainSelected,
currentInput: currentInput,
);
case UiDesign.CUPERTINO:
return SelectTrainSuggestionsCupertino(
choices: choices,
onTrainSelected: onTrainSelected,
currentInput: currentInput,
);
default:
throw UnmatchedUiDesignException(uiDesign);
}
}
}
abstract class SelectTrainSuggestionsShared extends StatelessWidget {
String getUseCurrentInputWidgetText(String currentInput) => 'Caută trenul cu numărul $currentInput';
Widget getUseCurrentInputWidget(String currentInput, void Function(String) onTrainSelected);
final List<TrainsResult> choices;
final String? currentInput;
final void Function(String trainNumber) onTrainSelected;
const SelectTrainSuggestionsShared({
required this.choices,
this.currentInput,
required this.onTrainSelected,
super.key,
});
@override
Widget build(BuildContext context) {
var slivers = choices.map((c) => c.company).toSet().map((operator) => OperatorAutocompleteSliver(
operatorName: operator,
trains: choices.where((c) => c.company == operator).toList(),
onTrainSelected: onTrainSelected,
)).toList();
return CustomScrollView(
slivers: <Widget>[
...slivers,
SliverToBoxAdapter(
child: currentInput != null && int.tryParse(currentInput!) != null ? getUseCurrentInputWidget(currentInput!, onTrainSelected) : Container(),
),
SliverToBoxAdapter(
child: Container(
height: MediaQuery.of(context).viewPadding.bottom,
),
),
],
);
}
}
class OperatorAutocompleteSliver extends ConsumerWidget {
final String operatorName;
final List<TrainsResult> trains;
final void Function(String) onTrainSelected;
const OperatorAutocompleteSliver({
super.key,
required this.operatorName,
required this.trains,
required this.onTrainSelected,
});
Widget mapTrainToItem(TrainsResult train, UiDesign uiDesign) {
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, WidgetRef ref) {
final uiDesign = ref.watch(uiDesignProvider);
if (trains.isEmpty) {
return SliverToBoxAdapter(child: Container(),);
}
return SliverPrototypeExtentList(
prototypeItem: Column(
children: <Widget>[
mapTrainToItem(const TrainsResult(company: 'Company', number: '123', rank: 'R'), uiDesign),
],
),
delegate: SliverChildBuilderDelegate(
(context, index) {
return Column(
children: <Widget>[
mapTrainToItem(trains[index], uiDesign),
],
);
},
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);
}