kopia lustrzana https://gitlab.com/mysocialportal/relatica
174 wiersze
5.6 KiB
Dart
174 wiersze
5.6 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:logging/logging.dart';
|
|
|
|
import '../controls/async_value_widget.dart';
|
|
import '../controls/error_message_widget.dart';
|
|
import '../controls/padding.dart';
|
|
import '../controls/standard_appbar.dart';
|
|
import '../controls/status_and_refresh_button.dart';
|
|
import '../models/auth/profile.dart';
|
|
import '../riverpod_controllers/account_services.dart';
|
|
import '../riverpod_controllers/gallery_services.dart';
|
|
|
|
class GalleryBrowsersScreen extends ConsumerWidget {
|
|
static final _logger = Logger('$GalleryBrowsersScreen');
|
|
|
|
const GalleryBrowsersScreen({super.key});
|
|
|
|
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<void> renameGallery(
|
|
BuildContext context,
|
|
WidgetRef ref,
|
|
Profile profile,
|
|
String galleryName,
|
|
) async {
|
|
final newName = await showDialog<String>(
|
|
context: context,
|
|
barrierDismissible: false,
|
|
builder: (BuildContext context) {
|
|
var controller = TextEditingController(text: galleryName);
|
|
return Form(
|
|
child: AlertDialog(
|
|
title: const Text('Rename Gallery'),
|
|
content: TextFormField(
|
|
controller: controller,
|
|
autovalidateMode: AutovalidateMode.always,
|
|
validator: validNameChecker,
|
|
),
|
|
actions: <Widget>[
|
|
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, galleryName); // showDialog() returns true
|
|
},
|
|
),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
) ??
|
|
'';
|
|
|
|
if (newName.isEmpty || newName == galleryName) {
|
|
return;
|
|
}
|
|
|
|
await ref
|
|
.read(galleryProvider(profile, galleryName).notifier)
|
|
.rename(newName);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context, WidgetRef ref) {
|
|
_logger.finer('Building');
|
|
final profile = ref.watch(activeProfileProvider);
|
|
final loading = switch (ref.watch(galleryListProvider(profile))) {
|
|
AsyncData() => false,
|
|
_ => true,
|
|
};
|
|
return Scaffold(
|
|
appBar: StandardAppBar.build(context, 'Galleries', actions: [
|
|
StatusAndRefreshButton3(
|
|
executing: loading,
|
|
refreshFunction: () async => await ref
|
|
.read(galleryListProvider(profile).notifier)
|
|
.updateGalleries(),
|
|
busyColor: Theme.of(context).colorScheme.surface,
|
|
),
|
|
]),
|
|
body: RefreshIndicator(
|
|
onRefresh: () async {
|
|
await ref
|
|
.read(galleryListProvider(profile).notifier)
|
|
.updateGalleries();
|
|
},
|
|
child: buildBody(context, ref, profile),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget buildBody(BuildContext context, WidgetRef ref, Profile profile) {
|
|
return AsyncValueWidget(ref.watch(galleryListProvider(profile)),
|
|
loadingBuilder: (_, __) => const Center(
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
Text('Loading galleries'),
|
|
VerticalPadding(),
|
|
CircularProgressIndicator(),
|
|
],
|
|
),
|
|
),
|
|
valueBuilder: (context, ref, galleryListResult) {
|
|
return galleryListResult.fold(
|
|
onSuccess: (galleries) {
|
|
if (galleries.isEmpty) {
|
|
return const SingleChildScrollView(
|
|
child: Center(
|
|
child: Text('No Galleries'),
|
|
),
|
|
);
|
|
}
|
|
|
|
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,
|
|
ref,
|
|
profile,
|
|
gallery.name,
|
|
),
|
|
child: const Text('Rename'),
|
|
),
|
|
);
|
|
},
|
|
separatorBuilder: (context, index) {
|
|
return const Divider();
|
|
},
|
|
itemCount: galleries.length,
|
|
);
|
|
},
|
|
onError: (error) => ErrorMessageWidget(message: error.message),
|
|
);
|
|
});
|
|
}
|
|
}
|