Skip to content

Commit 6378793

Browse files
committed
Fixed album image refresh
1 parent 9846add commit 6378793

2 files changed

Lines changed: 81 additions & 105 deletions

File tree

lib/views/album/album_view_page.dart

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ class _AlbumViewPageState extends State<AlbumViewPage> {
4545
late AlbumModel _currentAlbum;
4646

4747
late final Future<List<ApiResult>> _data;
48-
List<ImageModel> _imageList = [];
49-
List<AlbumModel> _albumList = [];
48+
List<ImageModel>? _imageList;
49+
List<AlbumModel>? _albumList;
5050
List<ImageModel> _selectedList = [];
5151

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

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

66+
bool get _enableLoad {
67+
if (_imageList == null || _imageList!.isEmpty) return false;
68+
return _currentAlbum.nbImages > _imageList!.length;
69+
}
70+
6671
List<AlbumModel> _parseAlbums(List<AlbumModel> albums) {
6772
albums.removeWhere((album) {
6873
if (album.id == widget.album.id) {
@@ -75,7 +80,8 @@ class _AlbumViewPageState extends State<AlbumViewPage> {
7580
}
7681

7782
Future<void> _loadMoreImages() async {
78-
if (_currentAlbum.nbImages <= _imageList.length) return;
83+
if (_imageList == null) return;
84+
if (_currentAlbum.nbImages <= _imageList!.length) return;
7985
ApiResult<List<ImageModel>> result = await fetchImages(widget.album.id, _page + 1);
8086
if (result.hasError || !result.hasData) {
8187
_refreshController.loadFailed();
@@ -84,7 +90,7 @@ class _AlbumViewPageState extends State<AlbumViewPage> {
8490
}
8591
setState(() {
8692
_page += 1;
87-
_imageList.addAll(result.data!);
93+
_imageList!.addAll(result.data!);
8894
});
8995
_refreshController.loadComplete();
9096
}
@@ -102,7 +108,7 @@ class _AlbumViewPageState extends State<AlbumViewPage> {
102108
_page = 0;
103109
_albumList = _parseAlbums(albumsResult.data!);
104110
_imageList = imagesResult.data!;
105-
_selectedList.removeWhere((image) => !_imageList.contains(image));
111+
_selectedList.removeWhere((image) => !(_imageList ?? []).contains(image));
106112
});
107113
_refreshController.refreshCompleted();
108114
}
@@ -161,7 +167,7 @@ class _AlbumViewPageState extends State<AlbumViewPage> {
161167
child: SmartRefresher(
162168
controller: _refreshController,
163169
scrollController: _scrollController,
164-
enablePullUp: _imageList.isNotEmpty && _currentAlbum.nbImages > _imageList.length,
170+
enablePullUp: _enableLoad,
165171
onLoading: _loadMoreImages,
166172
onRefresh: _onRefresh,
167173
header: MaterialClassicHeader(
@@ -192,9 +198,9 @@ class _AlbumViewPageState extends State<AlbumViewPage> {
192198
_albumGrid(snapshot),
193199
_imageGrid(snapshot),
194200
SizedBox(
195-
height: 72,
201+
height: 72.0,
196202
child: Padding(
197-
padding: const EdgeInsets.all(8),
203+
padding: const EdgeInsets.all(8.0),
198204
child: Text(
199205
appStrings.imageCount(_currentAlbum.nbTotalImages),
200206
style: Theme.of(context).textTheme.titleSmall,
@@ -411,15 +417,21 @@ class _AlbumViewPageState extends State<AlbumViewPage> {
411417
}
412418

413419
Widget _albumGrid(AsyncSnapshot snapshot) {
414-
if (_albumList.isEmpty) {
420+
// initialize album list
421+
if (_albumList == null) {
415422
final ApiResult<List<AlbumModel>> result = snapshot.data!.first as ApiResult<List<AlbumModel>>;
416-
List<AlbumModel> albums = _parseAlbums(result.data!);
417-
if (albums.isEmpty) return const SizedBox();
423+
// if only albums has error
424+
if (!result.hasData) {
425+
return Center(
426+
child: Text(appStrings.categoryImageList_noDataError),
427+
);
428+
}
418429
_albumList = _parseAlbums(result.data!);
419430
}
431+
if (_albumList!.isEmpty) return const SizedBox();
420432
return AlbumGridView(
421433
isAdmin: widget.isAdmin,
422-
albumList: _albumList,
434+
albumList: _albumList!,
423435
onTap: _onTapAlbum,
424436
onEdit: _onEditAlbum,
425437
onDelete: _onDeleteAlbum,
@@ -428,14 +440,24 @@ class _AlbumViewPageState extends State<AlbumViewPage> {
428440
}
429441

430442
Widget _imageGrid(AsyncSnapshot snapshot) {
431-
if (_imageList.isEmpty && _page == 0) {
443+
// Initialize image list
444+
if (_imageList == null) {
432445
final ApiResult<List<ImageModel>> result = snapshot.data!.last as ApiResult<List<ImageModel>>;
446+
// if only images has error
447+
if (!result.hasData) {
448+
return Center(
449+
child: Text(appStrings.categoryImageList_noDataError),
450+
);
451+
}
433452
_imageList = result.data!;
453+
// Refresh after build (for _enableLoad)
434454
WidgetsBinding.instance.addPostFrameCallback((timeStamp) => setState(() {}));
435455
}
436-
_selectedList = _imageList.where((image) => _selectedList.contains(image)).toList();
456+
if (_imageList!.isEmpty) return const SizedBox();
457+
// rebuild current selection with new images
458+
_selectedList = _imageList!.where((image) => _selectedList.contains(image)).toList();
437459
return ImageGridView(
438-
imageList: _imageList,
460+
imageList: _imageList!,
439461
selectedList: _selectedList,
440462
onTapImage: _onTapPhoto,
441463
onSelectImage: (image) => setState(() {

lib/views/upload/upload_status_page.dart

Lines changed: 44 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,8 @@ class UploadStatusPage extends StatefulWidget {
1515
}
1616

1717
class _UploadStatusPageState extends State<UploadStatusPage> {
18-
final PageController _pageController = PageController();
1918
final ScrollController _scrollController = ScrollController();
2019

21-
int _page = 0;
22-
2320
@override
2421
Widget build(BuildContext context) {
2522
return Scaffold(
@@ -31,110 +28,67 @@ class _UploadStatusPageState extends State<UploadStatusPage> {
3128
style: Theme.of(context).appBarTheme.titleTextStyle,
3229
),
3330
),
34-
body: PageView(
35-
controller: _pageController,
36-
onPageChanged: (page) => setState(() {
37-
_page = page;
38-
}),
39-
children: [
40-
_buildUploadList,
41-
_buildHistoryList,
42-
],
43-
),
31+
body: _buildUploadList,
4432
floatingActionButton: ScrollUpFloatingButton(
4533
controller: _scrollController,
4634
),
47-
bottomNavigationBar: BottomNavigationBar(
48-
currentIndex: _page,
49-
onTap: (index) => _pageController.animateToPage(
50-
index,
51-
duration: const Duration(milliseconds: 300),
52-
curve: Curves.ease,
53-
),
54-
items: [
55-
BottomNavigationBarItem(
56-
icon: Icon(Icons.list),
57-
label: appStrings.uploadList_uploading,
58-
),
59-
BottomNavigationBarItem(
60-
icon: Icon(Icons.history),
61-
label: appStrings.uploadList_history,
62-
),
63-
],
64-
),
6535
);
6636
}
6737

6838
Widget get _buildUploadList {
6939
return Consumer<UploadNotifier>(builder: (context, uploadNotifier, child) {
70-
if (uploadNotifier.uploadList.isEmpty) {
40+
if (uploadNotifier.uploadList.isEmpty && uploadNotifier.uploadHistoryList.isEmpty) {
7141
return Center(
7242
child: Text(appStrings.uploadList_empty),
7343
);
7444
}
7545
return ListView.separated(
7646
padding: EdgeInsets.symmetric(vertical: 8.0),
77-
itemCount: uploadNotifier.uploadList.length,
47+
controller: _scrollController,
48+
itemCount: uploadNotifier.uploadList.length + uploadNotifier.uploadHistoryList.length,
7849
itemBuilder: (context, index) {
79-
UploadItem item = uploadNotifier.uploadList[index];
80-
return ListTile(
81-
dense: true,
82-
leading: ClipRRect(
83-
borderRadius: BorderRadius.circular(5.0),
84-
child: AspectRatio(
85-
aspectRatio: 1,
86-
child: Image.file(
87-
item.file,
88-
fit: BoxFit.cover,
50+
late UploadItem item;
51+
if (index < uploadNotifier.uploadList.length) {
52+
item = uploadNotifier.uploadList[index];
53+
return ListTile(
54+
dense: true,
55+
leading: ClipRRect(
56+
borderRadius: BorderRadius.circular(5.0),
57+
child: AspectRatio(
58+
aspectRatio: 1,
59+
child: Image.file(
60+
item.file,
61+
fit: BoxFit.cover,
62+
),
8963
),
9064
),
91-
),
92-
title: Text(
93-
item.file.path.split('/').last,
94-
style: Theme.of(context).textTheme.bodyMedium,
95-
),
96-
subtitle: StreamBuilder<double>(
97-
stream: item.progress.stream,
98-
initialData: 0.0,
99-
builder: (context, snapshot) {
100-
if (snapshot.hasData) {
101-
return LinearProgressIndicator(
102-
backgroundColor: Theme.of(context).colorScheme.secondary.withOpacity(0.3),
103-
value: min(snapshot.data!, 1.0),
104-
);
105-
}
106-
return LinearProgressIndicator();
107-
},
108-
),
109-
trailing: IconButton(
110-
onPressed: () {
111-
item.cancelToken.cancel();
112-
uploadNotifier.itemUploadCompleted(item);
113-
},
114-
icon: Icon(Icons.close),
115-
),
116-
);
117-
},
118-
separatorBuilder: (context, index) {
119-
return const Divider();
120-
},
121-
);
122-
});
123-
}
124-
125-
Widget get _buildHistoryList {
126-
return Consumer<UploadNotifier>(builder: (context, uploadNotifier, child) {
127-
if (uploadNotifier.uploadHistoryList.isEmpty) {
128-
return Center(
129-
child: Text(appStrings.uploadList_empty),
130-
);
131-
}
132-
return ListView.separated(
133-
controller: _scrollController,
134-
padding: EdgeInsets.symmetric(vertical: 8.0),
135-
itemCount: uploadNotifier.uploadHistoryList.length,
136-
itemBuilder: (context, index) {
137-
UploadItem item = uploadNotifier.uploadHistoryList[index];
65+
title: Text(
66+
item.file.path.split('/').last,
67+
style: Theme.of(context).textTheme.bodyMedium,
68+
),
69+
subtitle: StreamBuilder<double>(
70+
stream: item.progress.stream,
71+
initialData: 0.0,
72+
builder: (context, snapshot) {
73+
if (snapshot.hasData) {
74+
return LinearProgressIndicator(
75+
backgroundColor: Theme.of(context).colorScheme.secondary.withOpacity(0.3),
76+
value: min(snapshot.data!, 1.0),
77+
);
78+
}
79+
return LinearProgressIndicator();
80+
},
81+
),
82+
trailing: IconButton(
83+
onPressed: () {
84+
item.cancelToken.cancel();
85+
uploadNotifier.itemUploadCompleted(item);
86+
},
87+
icon: Icon(Icons.close),
88+
),
89+
);
90+
}
91+
item = uploadNotifier.uploadHistoryList[index - uploadNotifier.uploadList.length];
13892
return ListTile(
13993
dense: true,
14094
leading: ClipRRect(

0 commit comments

Comments
 (0)