nc-photos/app/lib/widget/places_browser.dart

153 lines
4.9 KiB
Dart
Raw Normal View History

2023-12-13 16:06:13 +01:00
import 'dart:async';
2022-08-28 17:35:29 +02:00
import 'package:collection/collection.dart';
2023-12-13 16:06:13 +01:00
import 'package:copy_with/copy_with.dart';
2022-08-28 17:35:29 +02:00
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/app_localizations.dart';
2023-12-13 16:06:13 +01:00
import 'package:nc_photos/bloc_util.dart';
import 'package:nc_photos/controller/account_controller.dart';
import 'package:nc_photos/controller/places_controller.dart';
import 'package:nc_photos/entity/collection/builder.dart';
2023-12-13 16:06:13 +01:00
import 'package:nc_photos/exception_event.dart';
2022-08-28 17:35:29 +02:00
import 'package:nc_photos/exception_util.dart' as exception_util;
import 'package:nc_photos/k.dart' as k;
import 'package:nc_photos/snack_bar_manager.dart';
import 'package:nc_photos/theme.dart';
import 'package:nc_photos/use_case/list_location_group.dart';
import 'package:nc_photos/widget/about_geocoding_dialog.dart';
import 'package:nc_photos/widget/collection_browser.dart';
2022-08-28 17:35:29 +02:00
import 'package:nc_photos/widget/collection_list_item.dart';
2022-12-18 07:20:51 +01:00
import 'package:nc_photos/widget/network_thumbnail.dart';
2023-12-13 16:06:13 +01:00
import 'package:nc_photos/widget/page_visibility_mixin.dart';
2022-12-16 16:01:04 +01:00
import 'package:np_codegen/np_codegen.dart';
2023-12-13 16:06:13 +01:00
import 'package:to_string/to_string.dart';
2022-12-16 16:01:04 +01:00
part 'places_browser.g.dart';
2023-12-13 16:06:13 +01:00
part 'places_browser/bloc.dart';
part 'places_browser/state_event.dart';
part 'places_browser/type.dart';
part 'places_browser/view.dart';
2022-08-28 17:35:29 +02:00
2023-12-13 16:06:13 +01:00
typedef _BlocBuilder = BlocBuilder<_Bloc, _State>;
typedef _BlocListener = BlocListener<_Bloc, _State>;
2022-08-28 17:35:29 +02:00
/// Show a list of all people associated with this account
2023-12-13 16:06:13 +01:00
class PlacesBrowser extends StatelessWidget {
2022-08-28 17:35:29 +02:00
static const routeName = "/places-browser";
2023-12-13 16:06:13 +01:00
static Route buildRoute() => MaterialPageRoute(
builder: (_) => const PlacesBrowser(),
2022-08-28 17:35:29 +02:00
);
2023-12-13 16:06:13 +01:00
const PlacesBrowser({super.key});
2022-08-28 17:35:29 +02:00
@override
2023-12-13 16:06:13 +01:00
Widget build(BuildContext context) {
final accountController = context.read<AccountController>();
return BlocProvider(
create: (_) => _Bloc(
account: accountController.account,
placesController: accountController.placesController,
),
child: const _WrappedPlacesBrowser(),
);
}
}
2022-08-28 17:35:29 +02:00
2023-12-13 16:06:13 +01:00
class _WrappedPlacesBrowser extends StatefulWidget {
const _WrappedPlacesBrowser();
@override
State<StatefulWidget> createState() => _WrappedPlacesBrowserState();
2022-08-28 17:35:29 +02:00
}
2022-12-16 16:01:04 +01:00
@npLog
2023-12-13 16:06:13 +01:00
class _WrappedPlacesBrowserState extends State<_WrappedPlacesBrowser>
with RouteAware, PageVisibilityMixin {
2022-08-28 17:35:29 +02:00
@override
2023-12-13 16:06:13 +01:00
void initState() {
2022-08-28 17:35:29 +02:00
super.initState();
2023-12-13 16:06:13 +01:00
_bloc.add(const _LoadPlaces());
2022-08-28 17:35:29 +02:00
}
@override
2023-12-13 16:06:13 +01:00
Widget build(BuildContext context) {
return MultiBlocListener(
listeners: [
_BlocListener(
listenWhen: (previous, current) => previous.places != current.places,
listener: (context, state) {
_bloc.add(_TransformItems(state.places));
},
2022-08-28 17:35:29 +02:00
),
2023-12-13 16:06:13 +01:00
_BlocListener(
listenWhen: (previous, current) => previous.error != current.error,
listener: (context, state) {
if (state.error != null && isPageVisible()) {
SnackBarManager().showSnackBar(SnackBar(
content: Text(exception_util.toUserString(state.error!.error)),
duration: k.snackBarDurationNormal,
));
}
},
),
],
child: Scaffold(
body: Stack(
children: [
RefreshIndicator(
onRefresh: () async {
_bloc.add(const _Reload());
await _bloc.stream.first;
},
child: CustomScrollView(
slivers: [
const _AppBar(),
SliverToBoxAdapter(
child: _BlocBuilder(
buildWhen: (previous, current) =>
previous.isLoading != current.isLoading,
builder: (context, state) => state.isLoading
? const LinearProgressIndicator()
: const SizedBox(height: 4),
),
),
_CountryList(
onTap: (_, item) {
_onTap(context, item);
},
),
const SliverToBoxAdapter(
child: SizedBox(height: 8),
),
_ContentList(
onTap: (_, item) {
_onTap(context, item);
},
),
],
2022-08-28 17:35:29 +02:00
),
2022-11-12 10:55:33 +01:00
),
],
2022-08-28 17:35:29 +02:00
),
2023-12-13 16:06:13 +01:00
),
2022-08-28 17:35:29 +02:00
);
}
2023-12-13 16:06:13 +01:00
void _onTap(BuildContext context, _Item item) {
Navigator.pushNamed(
context,
CollectionBrowser.routeName,
arguments: CollectionBrowserArguments(
2023-12-13 16:06:13 +01:00
CollectionBuilder.byLocationGroup(_bloc.account, item.place),
),
);
2022-08-28 17:35:29 +02:00
}
2023-12-13 16:06:13 +01:00
late final _bloc = context.read<_Bloc>();
2023-07-22 20:57:01 +02:00
}