diff --git a/lib/src/ui/pages/details.dart b/lib/src/ui/pages/details.dart index b462477..a2e80f4 100644 --- a/lib/src/ui/pages/details.dart +++ b/lib/src/ui/pages/details.dart @@ -7,18 +7,37 @@ import 'package:anitrack/src/ui/widgets/dropdown.dart'; import 'package:anitrack/src/ui/widgets/image.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:get_it/get_it.dart'; -class DetailsPage extends StatelessWidget { - const DetailsPage({ +class DetailsPage extends StatefulWidget { + DetailsPage({ super.key, }); static MaterialPageRoute get route => MaterialPageRoute( - builder: (_) => const DetailsPage(), + builder: (_) => DetailsPage(), settings: const RouteSettings( name: detailsRoute, ), ); + + @override + DetailsPageState createState() => DetailsPageState(); +} + +class DetailsPageState extends State { + final TextEditingController _volumesOwnedController = TextEditingController(); + + @override + void initState() { + super.initState(); + + final state = GetIt.I.get().state; + + if (state.trackingType == TrackingMediumType.manga) { + _volumesOwnedController.text = '${(state.data as MangaTrackingData).volumesOwned}'; + } + } @override Widget build(BuildContext context) { @@ -67,51 +86,131 @@ class DetailsPage extends StatelessWidget { ], ), - DropdownSelector( - title: state.trackingType == TrackingMediumType.anime ? - 'Watch state' : - 'Read state', - onChanged: (MediumTrackingState newState) { - if (state.trackingType == TrackingMediumType.anime) { - context.read().add( - DetailsUpdatedEvent( - (state.data as AnimeTrackingData).copyWith( - state: newState, + Padding( + padding: const EdgeInsets.symmetric( + vertical: 8, + ), + child: DropdownSelector( + title: state.trackingType == TrackingMediumType.anime ? + 'Watch state' : + 'Read state', + onChanged: (MediumTrackingState newState) { + if (state.trackingType == TrackingMediumType.anime) { + context.read().add( + DetailsUpdatedEvent( + (state.data as AnimeTrackingData).copyWith( + state: newState, + ), ), - ), - ); - } else if (state.trackingType == TrackingMediumType.manga) { - context.read().add( - DetailsUpdatedEvent( - (state.data as MangaTrackingData).copyWith( - state: newState, + ); + } else if (state.trackingType == TrackingMediumType.manga) { + context.read().add( + DetailsUpdatedEvent( + (state.data as MangaTrackingData).copyWith( + state: newState, + ), ), - ), - ); - } - }, - values: [ - SelectorItem( - MediumTrackingState.ongoing, - MediumTrackingState.ongoing.toNameString(state.trackingType), - ), - SelectorItem( - MediumTrackingState.completed, - MediumTrackingState.completed.toNameString(state.trackingType), - ), - SelectorItem( - MediumTrackingState.planned, - MediumTrackingState.planned.toNameString(state.trackingType), - ), - SelectorItem( - MediumTrackingState.dropped, - MediumTrackingState.dropped.toNameString(state.trackingType), - ), - ], - initialValue: state.trackingType == TrackingMediumType.anime ? - (state.data as AnimeTrackingData).state : - (state.data as MangaTrackingData).state, + ); + } + }, + values: [ + SelectorItem( + MediumTrackingState.ongoing, + MediumTrackingState.ongoing.toNameString(state.trackingType), + ), + SelectorItem( + MediumTrackingState.completed, + MediumTrackingState.completed.toNameString(state.trackingType), + ), + SelectorItem( + MediumTrackingState.planned, + MediumTrackingState.planned.toNameString(state.trackingType), + ), + SelectorItem( + MediumTrackingState.dropped, + MediumTrackingState.dropped.toNameString(state.trackingType), + ), + ], + initialValue: state.trackingType == TrackingMediumType.anime ? + (state.data as AnimeTrackingData).state : + (state.data as MangaTrackingData).state, + ), ), + + if (state.trackingType == TrackingMediumType.manga) + Padding( + padding: const EdgeInsets.symmetric( + vertical: 8, + ), + child: Row( + children: [ + ElevatedButton( + onPressed: () { + final data = (state.data as MangaTrackingData); + if (data.volumesOwned == 0) return; + + _volumesOwnedController.text = '${data.volumesOwned - 1}'; + context.read().add( + DetailsUpdatedEvent( + data.copyWith( + volumesOwned: data.volumesOwned - 1, + ), + ), + ); + }, + child: Icon(Icons.remove), + ), + + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 16, + ), + child: TextField( + decoration: const InputDecoration( + border: OutlineInputBorder(), + labelText: 'Volumes owned', + ), + keyboardType: TextInputType.numberWithOptions( + signed: false, + decimal: false, + ), + textInputAction: TextInputAction.done, + controller: _volumesOwnedController, + onSubmitted: (value) { + final amount = int.parse(value); + if (amount < 0) return; + + context.read().add( + DetailsUpdatedEvent( + (state.data as MangaTrackingData).copyWith( + volumesOwned: amount, + ), + ), + ); + }, + ), + ), + ), + + ElevatedButton( + onPressed: () { + final data = (state.data as MangaTrackingData); + + _volumesOwnedController.text = '${data.volumesOwned + 1}'; + context.read().add( + DetailsUpdatedEvent( + data.copyWith( + volumesOwned: data.volumesOwned + 1, + ), + ), + ); + }, + child: Icon(Icons.add), + ), + ], + ), + ), ], ), );