import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import '/features/core/data/constants/const_colors.dart'; import '/features/core/data/constants/const_durations.dart'; import '/features/core/data/constants/const_media.dart'; import '/features/core/widgets/gap.dart'; import '/features/core/widgets/mcg_scaffold.dart'; import '/features/core/widgets/state/multi_value_listenable_builder.dart'; import '/features/core/widgets/state/view_model_builder.dart'; import '/features/home/widgets/custom_wrap.dart'; import '../../data/enums/search_option.dart'; import '../../data/models/image_model.dart'; import 'gallery_view_model.dart'; part 'downloaded_gallery_view.dart'; part 'search_gallery_view.dart'; class GalleryView extends StatelessWidget { const GalleryView({super.key}); @override Widget build(BuildContext context) { return ViewModelBuilder( viewModelBuilder: () => GalleryViewModel.locate, builder: (context, final model) => McgScaffold( bodyBuilderWaiter: model.isInitialised, forceInternetCheck: true, appBar: AppBar( centerTitle: true, primary: true, title: ValueListenableBuilder( valueListenable: model.isSearchingListenable, builder: (context, final isSearching, _) => AnimatedSwitcher( duration: ConstDurations.quarterDefaultAnimationDuration, child: !isSearching ? Center(child: Text(model.strings.gallery)) : _SearchBox(galleryViewModel: model), ), ), actions: [ Padding( padding: const EdgeInsets.only(right: 40), child: MultiValueListenableBuilder( valueListenables: [ model.isDisplayingPressingPrompt, model.isSearchingListenable, ], builder: (context, final values, child) => !model.isDisplayingPressingPrompt.value ? IconButton( isSelected: model.isSearchingListenable.value, icon: const Icon(Icons.search), selectedIcon: const Icon(Icons.close), onPressed: model.searchPressed, ) : const SizedBox.shrink(), ), ) ], ), body: Center( child: ValueListenableBuilder( valueListenable: model.isDisplayingPressingPrompt, builder: (context, final isDisplayingPressingPrompt, _) => AnimatedSwitcher( duration: ConstDurations.defaultAnimationDuration, child: isDisplayingPressingPrompt ? ElevatedButton( onPressed: model.onPromptPressed, child: Text(model.strings.startLoadingPrompt), ) : SingleChildScrollView( child: FutureBuilder( future: model.initImageFetchIsDone, builder: (context, final snapshot) { switch (snapshot.connectionState) { case ConnectionState.none: case ConnectionState.waiting: case ConnectionState.active: return const CircularProgressIndicator(); case ConnectionState.done: return ValueListenableBuilder( valueListenable: model.isSearchingListenable, builder: (context, final isSearching, _) => AnimatedSwitcher( duration: ConstDurations.oneAndHalfDefaultAnimationDuration, child: !isSearching ? Column( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ ValueListenableBuilder( valueListenable: model.isViewingFavouriteListenable, builder: (context, final isViewingFavourites, child) => Row( mainAxisAlignment: MainAxisAlignment.center, children: [ ConstMedia.buildIcon( ConstMedia.favStarOutline, width: 24, height: 24, ), Switch( value: isViewingFavourites, onChanged: model.onFavouriteViewChange, ), ConstMedia.buildIcon( ConstMedia.favStarFilled, width: 24, height: 24, ), ], ), ), _DownloadedGalleryView(galleryViewModel: model), ], ) : _SearchGalleryView(galleryViewModel: model), ), ); } }, ), ), ), ), ), ), ); } } class _SearchBox extends StatelessWidget { const _SearchBox({ required this.galleryViewModel, super.key, }); final GalleryViewModel galleryViewModel; @override Widget build(BuildContext context) { return Row( children: [ ValueListenableBuilder( valueListenable: galleryViewModel.searchOptionListenable, builder: (context, final searchOption, _) => Padding( padding: const EdgeInsets.only(top: 8), child: DropdownButton( underline: const SizedBox.shrink(), borderRadius: BorderRadius.circular(24), items: [ for (final searchOption in SearchOption.values) DropdownMenuItem( value: searchOption, child: Center(child: Text(searchOption.name)), ), ], value: searchOption, onChanged: galleryViewModel.onSearchOptionChanged, ), ), ), const Gap(18), Expanded( child: TextField( autofocus: true, decoration: InputDecoration( hintText: galleryViewModel.strings.searchForImage, ), onChanged: galleryViewModel.onSearchTermUpdate, ), ), ], ); } }