nc-photos/lib/widget/album_picker_dialog.dart

182 lines
5.4 KiB
Dart
Raw Normal View History

2021-04-10 06:28:12 +02:00
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:kiwi/kiwi.dart';
import 'package:logging/logging.dart';
import 'package:nc_photos/account.dart';
import 'package:nc_photos/bloc/list_album.dart';
import 'package:nc_photos/entity/album.dart';
2021-06-24 18:26:56 +02:00
import 'package:nc_photos/entity/album/provider.dart';
2021-04-10 06:28:12 +02:00
import 'package:nc_photos/exception_util.dart' as exception_util;
2021-07-09 12:50:33 +02:00
import 'package:nc_photos/iterable_extension.dart';
2021-04-10 06:28:12 +02:00
import 'package:nc_photos/k.dart' as k;
import 'package:nc_photos/snack_bar_manager.dart';
2021-04-17 10:59:16 +02:00
import 'package:nc_photos/theme.dart';
2021-04-10 06:28:12 +02:00
import 'package:nc_photos/widget/new_album_dialog.dart';
2021-07-09 12:50:33 +02:00
import 'package:tuple/tuple.dart';
2021-04-10 06:28:12 +02:00
class AlbumPickerDialog extends StatefulWidget {
AlbumPickerDialog({
2021-07-23 22:05:57 +02:00
Key? key,
required this.account,
2021-04-10 06:28:12 +02:00
}) : super(key: key);
@override
createState() => _AlbumPickerDialogState();
final Account account;
}
class _AlbumPickerDialogState extends State<AlbumPickerDialog> {
@override
initState() {
super.initState();
_initBloc();
}
@override
build(BuildContext context) {
return BlocListener<ListAlbumBloc, ListAlbumBlocState>(
bloc: _bloc,
listener: (context, state) => _onStateChange(context, state),
child: BlocBuilder<ListAlbumBloc, ListAlbumBlocState>(
bloc: _bloc,
builder: (context, state) => _buildContent(context, state),
),
);
}
void _initBloc() {
ListAlbumBloc bloc;
final blocId =
"${widget.account.scheme}://${widget.account.username}@${widget.account.address}";
try {
_log.fine("[_initBloc] Resolving bloc for '$blocId'");
bloc = KiwiContainer().resolve<ListAlbumBloc>("ListAlbumBloc($blocId)");
} catch (_) {
// no created instance for this account, make a new one
_log.info("[_initBloc] New bloc instance for account: ${widget.account}");
bloc = ListAlbumBloc();
KiwiContainer().registerInstance<ListAlbumBloc>(bloc,
name: "ListAlbumBloc($blocId)");
}
_bloc = bloc;
if (_bloc.state is ListAlbumBlocInit) {
_log.info("[_initBloc] Initialize bloc");
_reqQuery();
} else {
// process the current state
2021-07-23 22:05:57 +02:00
WidgetsBinding.instance!.addPostFrameCallback((_) {
2021-07-03 13:32:23 +02:00
setState(() {
_onStateChange(context, _bloc.state);
});
});
2021-04-10 06:28:12 +02:00
}
}
Widget _buildContent(BuildContext context, ListAlbumBlocState state) {
final newAlbumOptions = [
SimpleDialogOption(
onPressed: () => _onNewAlbumPressed(context),
child: Tooltip(
2021-07-23 22:05:57 +02:00
message: AppLocalizations.of(context)!.createAlbumTooltip,
2021-04-17 10:59:16 +02:00
child: Center(
child: Icon(
Icons.add,
color: AppTheme.getSecondaryTextColor(context),
),
2021-04-10 06:28:12 +02:00
),
),
),
];
return Visibility(
visible: _isVisible,
child: SimpleDialog(
2021-07-05 07:48:49 +02:00
contentPadding: const EdgeInsets.symmetric(vertical: 8),
2021-04-10 06:28:12 +02:00
children: _items
.map((e) => SimpleDialogOption(
2021-07-05 07:48:49 +02:00
padding: const EdgeInsets.symmetric(horizontal: 8),
2021-04-10 06:28:12 +02:00
onPressed: () => _onItemPressed(context, e),
child: ListTile(
2021-07-05 07:48:49 +02:00
dense: true,
2021-04-10 06:28:12 +02:00
title: Text("${e.name}"),
),
))
.toList() +
newAlbumOptions,
),
);
}
void _onStateChange(BuildContext context, ListAlbumBlocState state) {
if (state is ListAlbumBlocInit) {
_items.clear();
} else if (state is ListAlbumBlocSuccess || state is ListAlbumBlocLoading) {
_transformItems(state.albums);
} else if (state is ListAlbumBlocFailure) {
_transformItems(state.albums);
2021-04-10 06:28:12 +02:00
SnackBarManager().showSnackBar(SnackBar(
content: Text(exception_util.toUserString(state.exception, context)),
duration: k.snackBarDurationNormal,
));
} else if (state is ListAlbumBlocInconsistent) {
_reqQuery();
}
}
void _onItemPressed(BuildContext context, Album album) {
Navigator.of(context).pop(album);
}
void _onNewAlbumPressed(BuildContext context) {
setState(() {
_isVisible = false;
});
showDialog(
context: context,
builder: (_) => NewAlbumDialog(
account: widget.account,
2021-06-29 11:44:35 +02:00
isAllowDynamic: false,
2021-04-10 06:28:12 +02:00
),
).then((value) {
Navigator.of(context).pop(value);
}).catchError((e, stacktrace) {
_log.severe(
"[_onNewAlbumPressed] Failed while showDialog", e, stacktrace);
Navigator.of(context).pop(e);
});
}
void _transformItems(List<Album> albums) {
2021-07-09 12:50:33 +02:00
final sortedAlbums = albums
.where((element) => element.provider is AlbumStaticProvider)
.map((e) => Tuple2(e.provider.latestItemTime ?? e.lastUpdated, e))
.sorted((a, b) {
// then sort in descending order
final tmp = b.item1.compareTo(a.item1);
if (tmp != 0) {
return tmp;
} else {
return a.item2.name.compareTo(b.item2.name);
}
}).map((e) => e.item2);
2021-04-10 06:28:12 +02:00
_items.clear();
2021-07-09 12:50:33 +02:00
_items.addAll(sortedAlbums);
2021-04-10 06:28:12 +02:00
}
void _reqQuery() {
_bloc.add(ListAlbumBlocQuery(widget.account));
}
2021-07-23 22:05:57 +02:00
late ListAlbumBloc _bloc;
2021-04-10 06:28:12 +02:00
final _items = <Album>[];
var _isVisible = true;
static final _log =
Logger("widget.album_picker_dialog._AlbumPickerDialogState");
}