nc-photos/lib/widget/pending_albums.dart

221 lines
6.7 KiB
Dart
Raw Normal View History

2021-08-20 19:02:13 +02:00
import 'package:flutter/material.dart';
import 'package:flutter/widgets.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';
import 'package:nc_photos/bloc/list_pending_shared_album.dart';
import 'package:nc_photos/entity/album.dart';
import 'package:nc_photos/entity/file.dart';
import 'package:nc_photos/entity/file/data_source.dart';
import 'package:nc_photos/exception_util.dart' as exception_util;
import 'package:nc_photos/iterable_extension.dart';
import 'package:nc_photos/k.dart' as k;
import 'package:nc_photos/pref.dart';
import 'package:nc_photos/snack_bar_manager.dart';
import 'package:nc_photos/theme.dart';
import 'package:nc_photos/use_case/import_potential_shared_album.dart';
import 'package:nc_photos/widget/album_browser_util.dart' as album_browser_util;
import 'package:nc_photos/widget/builder/album_grid_item_builder.dart';
import 'package:nc_photos/widget/empty_list_indicator.dart';
import 'package:tuple/tuple.dart';
class PendingAlbumsArguments {
PendingAlbumsArguments(this.account);
final Account account;
}
class PendingAlbums extends StatefulWidget {
static const routeName = "/pending-albums";
2021-08-22 13:13:53 +02:00
static Route buildRoute(PendingAlbumsArguments args) => MaterialPageRoute(
2021-08-20 19:02:13 +02:00
builder: (context) => PendingAlbums.fromArgs(args),
);
2021-09-15 08:58:06 +02:00
const PendingAlbums({
2021-08-20 19:02:13 +02:00
Key? key,
required this.account,
}) : super(key: key);
PendingAlbums.fromArgs(PendingAlbumsArguments args, {Key? key})
: this(
key: key,
account: args.account,
);
@override
createState() => _PendingAlbumsState();
final Account account;
}
class _PendingAlbumsState extends State<PendingAlbums> {
@override
initState() {
super.initState();
_importPotentialSharedAlbum().then((_) {
_bloc.add(ListPendingSharedAlbumBlocQuery(widget.account));
});
Pref.inst().setNewSharedAlbum(false);
}
@override
build(BuildContext context) {
return AppTheme(
child: Scaffold(
body: BlocListener<ListPendingSharedAlbumBloc,
ListPendingSharedAlbumBlocState>(
bloc: _bloc,
listener: (context, state) => _onStateChange(context, state),
child: BlocBuilder<ListPendingSharedAlbumBloc,
ListPendingSharedAlbumBlocState>(
bloc: _bloc,
builder: (context, state) => _buildContent(context, state),
),
),
),
);
}
Widget _buildContent(
BuildContext context, ListPendingSharedAlbumBlocState state) {
if (state is ListPendingSharedAlbumBlocSuccess && _items.isEmpty) {
return Column(
children: [
AppBar(
2021-09-15 08:58:06 +02:00
title: const Text("Sharing with you"),
2021-08-20 19:02:13 +02:00
elevation: 0,
),
Expanded(
child: EmptyListIndicator(
icon: Icons.share_outlined,
text: L10n.global().listEmptyText,
2021-08-20 19:02:13 +02:00
),
),
],
);
} else {
return Stack(
children: [
Theme(
data: Theme.of(context).copyWith(
colorScheme: Theme.of(context).colorScheme.copyWith(
secondary: AppTheme.getOverscrollIndicatorColor(context),
),
2021-08-20 19:02:13 +02:00
),
child: CustomScrollView(
slivers: [
2021-09-15 08:58:06 +02:00
const SliverAppBar(
2021-08-20 19:02:13 +02:00
title: Text("Sharing with you"),
),
SliverPadding(
padding: const EdgeInsets.all(8),
sliver: SliverStaggeredGrid.extentBuilder(
maxCrossAxisExtent: 256,
mainAxisSpacing: 8,
itemCount: _items.length,
itemBuilder: _buildItem,
staggeredTileBuilder: (_) =>
const StaggeredTile.count(1, 1),
),
),
],
),
),
if (!_isReady || state is ListPendingSharedAlbumBlocLoading)
2021-09-15 08:58:06 +02:00
const Align(
2021-08-20 19:02:13 +02:00
alignment: Alignment.bottomCenter,
2021-09-15 08:58:06 +02:00
child: LinearProgressIndicator(),
2021-08-20 19:02:13 +02:00
),
],
);
}
}
Widget _buildItem(BuildContext context, int index) {
final item = _items[index];
return Stack(
children: [
AlbumGridItemBuilder(
account: widget.account,
album: item.album,
).build(context),
Positioned.fill(
child: Material(
type: MaterialType.transparency,
child: InkWell(
onTap: () => _onItemTap(context, item),
),
),
),
],
);
2021-08-20 19:02:13 +02:00
}
void _onStateChange(
BuildContext context, ListPendingSharedAlbumBlocState state) {
if (state is ListPendingSharedAlbumBlocSuccess ||
state is ListPendingSharedAlbumBlocLoading) {
_transformItems(state.items);
} else if (state is ListPendingSharedAlbumBlocFailure) {
SnackBarManager().showSnackBar(SnackBar(
content: Text(exception_util.toUserString(state.exception)),
2021-08-20 19:02:13 +02:00
duration: k.snackBarDurationNormal,
));
} else if (state is ListPendingSharedAlbumBlocInconsistent) {
_bloc.add(ListPendingSharedAlbumBlocQuery(widget.account));
}
_isReady = true;
}
void _onItemTap(BuildContext context, _GridItem item) {
album_browser_util.open(context, widget.account, item.album);
}
void _transformItems(List<ListPendingSharedAlbumBlocItem> items) {
final sortedAlbums = items
.map((e) => Tuple2(
e.album.provider.latestItemTime ?? e.album.lastUpdated, e.album))
.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);
_items.clear();
_items.addAll(sortedAlbums.map((e) => _GridItem(e)));
}
Future<void> _importPotentialSharedAlbum() async {
2021-09-15 08:58:06 +02:00
const fileRepo = FileRepo(FileWebdavDataSource());
2021-08-20 19:02:13 +02:00
// don't want the potential albums to be cached at this moment
final albumRepo = AlbumRepo(AlbumRemoteDataSource());
try {
await ImportPotentialSharedAlbum(fileRepo, albumRepo)(widget.account);
} catch (e, stacktrace) {
_log.shout(
"[_importPotentialSharedAlbum] Failed while ImportPotentialSharedAlbum",
e,
stacktrace);
}
}
final _bloc = ListPendingSharedAlbumBloc();
bool _isReady = false;
2021-09-15 08:58:06 +02:00
final _items = <_GridItem>[];
2021-08-20 19:02:13 +02:00
2021-08-22 13:13:53 +02:00
static final _log = Logger("widget.pending_albums._PendingAlbumsState");
2021-08-20 19:02:13 +02:00
}
class _GridItem {
_GridItem(this.album);
Album album;
}