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:kiwi/kiwi.dart';
|
|
|
|
import 'package:logging/logging.dart';
|
|
|
|
import 'package:nc_photos/account.dart';
|
2021-07-25 07:00:38 +02:00
|
|
|
import 'package:nc_photos/app_localizations.dart';
|
2021-04-10 06:28:12 +02:00
|
|
|
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 {
|
2021-09-15 08:58:06 +02:00
|
|
|
const 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-08-29 13:51:43 +02:00
|
|
|
message: L10n.global().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-09-15 08:58:06 +02:00
|
|
|
title: Text(e.name),
|
2021-04-10 06:28:12 +02:00
|
|
|
),
|
|
|
|
))
|
|
|
|
.toList() +
|
|
|
|
newAlbumOptions,
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void _onStateChange(BuildContext context, ListAlbumBlocState state) {
|
|
|
|
if (state is ListAlbumBlocInit) {
|
|
|
|
_items.clear();
|
|
|
|
} else if (state is ListAlbumBlocSuccess || state is ListAlbumBlocLoading) {
|
2021-08-13 12:38:46 +02:00
|
|
|
_transformItems(state.items);
|
2021-04-10 06:28:12 +02:00
|
|
|
} else if (state is ListAlbumBlocFailure) {
|
2021-08-13 12:38:46 +02:00
|
|
|
_transformItems(state.items);
|
2021-04-10 06:28:12 +02:00
|
|
|
SnackBarManager().showSnackBar(SnackBar(
|
2021-08-29 13:51:43 +02:00
|
|
|
content: Text(exception_util.toUserString(state.exception)),
|
2021-04-10 06:28:12 +02:00
|
|
|
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);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-08-13 12:38:46 +02:00
|
|
|
void _transformItems(List<ListAlbumBlocItem> items) {
|
|
|
|
final sortedAlbums = items
|
|
|
|
.map((e) => e.album)
|
2021-07-09 12:50:33 +02:00
|
|
|
.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");
|
|
|
|
}
|