import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:logging/logging.dart'; import 'package:provider/provider.dart'; import '../controls/padding.dart'; import '../controls/standard_appbar.dart'; import '../controls/status_and_refresh_button.dart'; import '../globals.dart'; import '../models/gallery_data.dart'; import '../services/gallery_service.dart'; import '../services/network_status_service.dart'; import '../utils/active_profile_selector.dart'; class GalleryBrowsersScreen extends StatelessWidget { static final _logger = Logger('$GalleryBrowsersScreen'); String? validNameChecker(String? text) { final newName = text ?? ''; if (newName.isEmpty) { return 'Name cannot be empty'; } if (!RegExp( r"^[a-zA-Z0-9 ]+$", ).hasMatch(newName)) { return 'Name must be only letters and numbers'; } return null; } Future renameGallery( BuildContext context, GalleryService service, GalleryData gallery, ) async { final newName = await showDialog( context: context, barrierDismissible: false, builder: (BuildContext context) { var controller = TextEditingController(text: gallery.name); return Form( child: AlertDialog( title: const Text('Rename Gallery'), content: TextFormField( controller: controller, autovalidateMode: AutovalidateMode.always, validator: validNameChecker, ), actions: [ ElevatedButton( child: const Text('OK'), onPressed: () { if (validNameChecker(controller.text) != null) { return; } Navigator.pop(context, controller.text); // showDialog() returns true }, ), ElevatedButton( child: const Text('Cancel'), onPressed: () { Navigator.pop( context, gallery.name); // showDialog() returns true }, ), ], ), ); }, ) ?? ''; if (newName.isEmpty || newName == gallery.name) { return; } await service.renameGallery(gallery, newName); } @override Widget build(BuildContext context) { _logger.finest('Building'); final service = context .watch>() .activeEntry .value; final nss = getIt(); return Scaffold( appBar: StandardAppBar.build(context, 'Galleries', actions: [ StatusAndRefreshButton( valueListenable: nss.imageGalleryLoadingStatus, refreshFunction: () async => await service.updateGalleries(), busyColor: Theme.of(context).colorScheme.background, ), ]), body: RefreshIndicator( onRefresh: () async { await service.updateGalleries(); }, child: buildBody(context, service), ), ); } Widget buildBody(BuildContext context, GalleryService service) { final galleries = service.getGalleries(); if (galleries.isEmpty && service.loaded) { return const SingleChildScrollView( child: Center( child: Text('No Galleries'), ), ); } if (galleries.isEmpty) { return Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: const [ Text('Loading galleries'), VerticalPadding(), CircularProgressIndicator(), ], ), ); } return ListView.separated( itemBuilder: (context, index) { final gallery = galleries[index]; return ListTile( onTap: () => context.push('/gallery/show', extra: gallery.name), title: Text(gallery.name), subtitle: Text( '#Photos: ${gallery.count}, Created: ${gallery.created}', style: Theme.of(context).textTheme.bodySmall, ), trailing: ElevatedButton( onPressed: () async => await renameGallery( context, service, gallery, ), child: const Text('Rename'), ), ); }, separatorBuilder: (context, index) { return const Divider(); }, itemCount: galleries.length, ); } }