Skip to content

Commit

Permalink
Fixed album image refresh
Browse files Browse the repository at this point in the history
  • Loading branch information
ReightI committed Feb 28, 2023
1 parent 9846add commit 6378793
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 105 deletions.
52 changes: 37 additions & 15 deletions lib/views/album/album_view_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ class _AlbumViewPageState extends State<AlbumViewPage> {
late AlbumModel _currentAlbum;

late final Future<List<ApiResult>> _data;
List<ImageModel> _imageList = [];
List<AlbumModel> _albumList = [];
List<ImageModel>? _imageList;
List<AlbumModel>? _albumList;
List<ImageModel> _selectedList = [];

int _page = 0;
Expand All @@ -63,6 +63,11 @@ class _AlbumViewPageState extends State<AlbumViewPage> {

bool get _hasNonFavorites => _selectedList.where((image) => !image.favorite).isNotEmpty;

bool get _enableLoad {
if (_imageList == null || _imageList!.isEmpty) return false;
return _currentAlbum.nbImages > _imageList!.length;
}

List<AlbumModel> _parseAlbums(List<AlbumModel> albums) {
albums.removeWhere((album) {
if (album.id == widget.album.id) {
Expand All @@ -75,7 +80,8 @@ class _AlbumViewPageState extends State<AlbumViewPage> {
}

Future<void> _loadMoreImages() async {
if (_currentAlbum.nbImages <= _imageList.length) return;
if (_imageList == null) return;
if (_currentAlbum.nbImages <= _imageList!.length) return;
ApiResult<List<ImageModel>> result = await fetchImages(widget.album.id, _page + 1);
if (result.hasError || !result.hasData) {
_refreshController.loadFailed();
Expand All @@ -84,7 +90,7 @@ class _AlbumViewPageState extends State<AlbumViewPage> {
}
setState(() {
_page += 1;
_imageList.addAll(result.data!);
_imageList!.addAll(result.data!);
});
_refreshController.loadComplete();
}
Expand All @@ -102,7 +108,7 @@ class _AlbumViewPageState extends State<AlbumViewPage> {
_page = 0;
_albumList = _parseAlbums(albumsResult.data!);
_imageList = imagesResult.data!;
_selectedList.removeWhere((image) => !_imageList.contains(image));
_selectedList.removeWhere((image) => !(_imageList ?? []).contains(image));
});
_refreshController.refreshCompleted();
}
Expand Down Expand Up @@ -161,7 +167,7 @@ class _AlbumViewPageState extends State<AlbumViewPage> {
child: SmartRefresher(
controller: _refreshController,
scrollController: _scrollController,
enablePullUp: _imageList.isNotEmpty && _currentAlbum.nbImages > _imageList.length,
enablePullUp: _enableLoad,
onLoading: _loadMoreImages,
onRefresh: _onRefresh,
header: MaterialClassicHeader(
Expand Down Expand Up @@ -192,9 +198,9 @@ class _AlbumViewPageState extends State<AlbumViewPage> {
_albumGrid(snapshot),
_imageGrid(snapshot),
SizedBox(
height: 72,
height: 72.0,
child: Padding(
padding: const EdgeInsets.all(8),
padding: const EdgeInsets.all(8.0),
child: Text(
appStrings.imageCount(_currentAlbum.nbTotalImages),
style: Theme.of(context).textTheme.titleSmall,
Expand Down Expand Up @@ -411,15 +417,21 @@ class _AlbumViewPageState extends State<AlbumViewPage> {
}

Widget _albumGrid(AsyncSnapshot snapshot) {
if (_albumList.isEmpty) {
// initialize album list
if (_albumList == null) {
final ApiResult<List<AlbumModel>> result = snapshot.data!.first as ApiResult<List<AlbumModel>>;
List<AlbumModel> albums = _parseAlbums(result.data!);
if (albums.isEmpty) return const SizedBox();
// if only albums has error
if (!result.hasData) {
return Center(
child: Text(appStrings.categoryImageList_noDataError),
);
}
_albumList = _parseAlbums(result.data!);
}
if (_albumList!.isEmpty) return const SizedBox();
return AlbumGridView(
isAdmin: widget.isAdmin,
albumList: _albumList,
albumList: _albumList!,
onTap: _onTapAlbum,
onEdit: _onEditAlbum,
onDelete: _onDeleteAlbum,
Expand All @@ -428,14 +440,24 @@ class _AlbumViewPageState extends State<AlbumViewPage> {
}

Widget _imageGrid(AsyncSnapshot snapshot) {
if (_imageList.isEmpty && _page == 0) {
// Initialize image list
if (_imageList == null) {
final ApiResult<List<ImageModel>> result = snapshot.data!.last as ApiResult<List<ImageModel>>;
// if only images has error
if (!result.hasData) {
return Center(
child: Text(appStrings.categoryImageList_noDataError),
);
}
_imageList = result.data!;
// Refresh after build (for _enableLoad)
WidgetsBinding.instance.addPostFrameCallback((timeStamp) => setState(() {}));
}
_selectedList = _imageList.where((image) => _selectedList.contains(image)).toList();
if (_imageList!.isEmpty) return const SizedBox();
// rebuild current selection with new images
_selectedList = _imageList!.where((image) => _selectedList.contains(image)).toList();
return ImageGridView(
imageList: _imageList,
imageList: _imageList!,
selectedList: _selectedList,
onTapImage: _onTapPhoto,
onSelectImage: (image) => setState(() {
Expand Down
134 changes: 44 additions & 90 deletions lib/views/upload/upload_status_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,8 @@ class UploadStatusPage extends StatefulWidget {
}

class _UploadStatusPageState extends State<UploadStatusPage> {
final PageController _pageController = PageController();
final ScrollController _scrollController = ScrollController();

int _page = 0;

@override
Widget build(BuildContext context) {
return Scaffold(
Expand All @@ -31,110 +28,67 @@ class _UploadStatusPageState extends State<UploadStatusPage> {
style: Theme.of(context).appBarTheme.titleTextStyle,
),
),
body: PageView(
controller: _pageController,
onPageChanged: (page) => setState(() {
_page = page;
}),
children: [
_buildUploadList,
_buildHistoryList,
],
),
body: _buildUploadList,
floatingActionButton: ScrollUpFloatingButton(
controller: _scrollController,
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: _page,
onTap: (index) => _pageController.animateToPage(
index,
duration: const Duration(milliseconds: 300),
curve: Curves.ease,
),
items: [
BottomNavigationBarItem(
icon: Icon(Icons.list),
label: appStrings.uploadList_uploading,
),
BottomNavigationBarItem(
icon: Icon(Icons.history),
label: appStrings.uploadList_history,
),
],
),
);
}

Widget get _buildUploadList {
return Consumer<UploadNotifier>(builder: (context, uploadNotifier, child) {
if (uploadNotifier.uploadList.isEmpty) {
if (uploadNotifier.uploadList.isEmpty && uploadNotifier.uploadHistoryList.isEmpty) {
return Center(
child: Text(appStrings.uploadList_empty),
);
}
return ListView.separated(
padding: EdgeInsets.symmetric(vertical: 8.0),
itemCount: uploadNotifier.uploadList.length,
controller: _scrollController,
itemCount: uploadNotifier.uploadList.length + uploadNotifier.uploadHistoryList.length,
itemBuilder: (context, index) {
UploadItem item = uploadNotifier.uploadList[index];
return ListTile(
dense: true,
leading: ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child: AspectRatio(
aspectRatio: 1,
child: Image.file(
item.file,
fit: BoxFit.cover,
late UploadItem item;
if (index < uploadNotifier.uploadList.length) {
item = uploadNotifier.uploadList[index];
return ListTile(
dense: true,
leading: ClipRRect(
borderRadius: BorderRadius.circular(5.0),
child: AspectRatio(
aspectRatio: 1,
child: Image.file(
item.file,
fit: BoxFit.cover,
),
),
),
),
title: Text(
item.file.path.split('/').last,
style: Theme.of(context).textTheme.bodyMedium,
),
subtitle: StreamBuilder<double>(
stream: item.progress.stream,
initialData: 0.0,
builder: (context, snapshot) {
if (snapshot.hasData) {
return LinearProgressIndicator(
backgroundColor: Theme.of(context).colorScheme.secondary.withOpacity(0.3),
value: min(snapshot.data!, 1.0),
);
}
return LinearProgressIndicator();
},
),
trailing: IconButton(
onPressed: () {
item.cancelToken.cancel();
uploadNotifier.itemUploadCompleted(item);
},
icon: Icon(Icons.close),
),
);
},
separatorBuilder: (context, index) {
return const Divider();
},
);
});
}

Widget get _buildHistoryList {
return Consumer<UploadNotifier>(builder: (context, uploadNotifier, child) {
if (uploadNotifier.uploadHistoryList.isEmpty) {
return Center(
child: Text(appStrings.uploadList_empty),
);
}
return ListView.separated(
controller: _scrollController,
padding: EdgeInsets.symmetric(vertical: 8.0),
itemCount: uploadNotifier.uploadHistoryList.length,
itemBuilder: (context, index) {
UploadItem item = uploadNotifier.uploadHistoryList[index];
title: Text(
item.file.path.split('/').last,
style: Theme.of(context).textTheme.bodyMedium,
),
subtitle: StreamBuilder<double>(
stream: item.progress.stream,
initialData: 0.0,
builder: (context, snapshot) {
if (snapshot.hasData) {
return LinearProgressIndicator(
backgroundColor: Theme.of(context).colorScheme.secondary.withOpacity(0.3),
value: min(snapshot.data!, 1.0),
);
}
return LinearProgressIndicator();
},
),
trailing: IconButton(
onPressed: () {
item.cancelToken.cancel();
uploadNotifier.itemUploadCompleted(item);
},
icon: Icon(Icons.close),
),
);
}
item = uploadNotifier.uploadHistoryList[index - uploadNotifier.uploadList.length];
return ListTile(
dense: true,
leading: ClipRRect(
Expand Down

0 comments on commit 6378793

Please sign in to comment.