Skip to content

Commit ff6ec48

Browse files
committed
Auto upload check image already exist, material 3 and design
1 parent b6d9171 commit ff6ec48

30 files changed

Lines changed: 972 additions & 591 deletions

l10n/app_en.arb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,7 @@
875875
"settings_autoUploadDestination": "Destination",
876876
"settings_autoUploadDestinationInvalid": "Invalid destination album",
877877
"settings_autoUploadDestinationInfo": "Please select the album or sub-album into which photos and videos will be auto-uploaded.",
878+
"settings_autoUploadDuplicateInfo": "Photos that are already in this Piwigo won't be uploaded.",
878879
"settings_autoUploadFrequency": "Every",
879880
"settings_autoUploadFrequencyMinutes": "{count, plural, =1{1 minute} other{{count} minutes}}",
880881
"@settings_autoUploadFrequencyMinutes" : {

lib/api/albums.dart

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import 'authentication.dart';
1212
Map<String, dynamic> tryParseJson(String data) {
1313
try {
1414
return json.decode(data);
15-
} on FormatException catch (e) {
15+
} on FormatException catch (_) {
1616
debugPrint('Invalid json data');
1717
debugPrint(data);
1818
int start = data.indexOf('{');
@@ -49,7 +49,8 @@ Future<ApiResult<List<AlbumModel>>> fetchAlbums(int albumID) async {
4949
);
5050

5151
if (response.statusCode == 200) {
52-
List<dynamic> jsonAlbums = tryParseJson(response.data)['result']['categories'];
52+
List<dynamic> jsonAlbums =
53+
tryParseJson(response.data)['result']['categories'];
5354
List<AlbumModel> albums = List<AlbumModel>.from(jsonAlbums.map(
5455
(album) {
5556
bool canUpload = false;
@@ -86,7 +87,8 @@ Future<ApiResult<List<AlbumModel>>> fetchCommunityAlbums(int albumID) async {
8687
);
8788

8889
if (response.statusCode == 200) {
89-
List<dynamic> jsonAlbums = json.decode(response.data)['result']['categories'];
90+
List<dynamic> jsonAlbums =
91+
json.decode(response.data)['result']['categories'];
9092
List<AlbumModel> albums = List<AlbumModel>.from(jsonAlbums.map(
9193
(album) => AlbumModel.fromJson(album),
9294
));
@@ -204,7 +206,10 @@ Future<ApiResult<bool>> moveAlbum(int catId, int parentCatId) async {
204206
return ApiResult(error: ApiErrors.moveAlbumError);
205207
}
206208

207-
Future<ApiResult<bool>> editAlbum({required String name, required int albumId, String description = ''}) async {
209+
Future<ApiResult<bool>> editAlbum(
210+
{required String name,
211+
required int albumId,
212+
String description = ''}) async {
208213
Map<String, String> queries = {
209214
'format': 'json',
210215
'method': 'pwg.categories.setInfo',

lib/api/images.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -479,8 +479,6 @@ Future<bool> editImage(ImageModel image,
479479
return false;
480480
}
481481

482-
Future<int?> checkImageExist(File file) async {}
483-
484482
/// Return a list of files that are not in the server
485483
Future<List<File>> checkImagesNotExist(List<File> files) async {
486484
Map<String, File> md5sumList = {};

lib/components/appbars/settings_app_bar.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ class _SettingsAppBarState extends State<SettingsAppBar> {
3333
}
3434

3535
// In case 0%-100% of the expanded height is viewed
36-
double scrollDelta = (_expandedHeight - widget.scrollController.offset) / _expandedHeight;
36+
double scrollDelta =
37+
(_expandedHeight - widget.scrollController.offset) / _expandedHeight;
3738
double scrollPercent = (scrollDelta * 2 - 1);
3839
return (1 - scrollPercent) * delta * basePadding + basePadding;
3940
}
@@ -49,6 +50,8 @@ class _SettingsAppBarState extends State<SettingsAppBar> {
4950
),
5051
pinned: true,
5152
expandedHeight: _expandedHeight,
53+
elevation: 5.0,
54+
scrolledUnderElevation: 5.0,
5255
flexibleSpace: FlexibleSpaceBar(
5356
titlePadding: EdgeInsets.symmetric(
5457
horizontal: _horizontalTitlePadding,

lib/components/cards/album_card.dart

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,15 @@ class AlbumCard extends StatelessWidget {
6767
icon: Icons.edit,
6868
),
6969
AlbumCardAction(
70-
backgroundColor: const Color(0xFF4B4B4B), // Todo: Theme grey action color
70+
backgroundColor:
71+
const Color(0xFF4B4B4B), // Todo: Theme grey action color
7172
foregroundColor: Colors.white,
7273
autoClose: true,
7374
onPressed: onMove,
7475
icon: Icons.drive_file_move,
7576
),
7677
AlbumCardAction(
77-
backgroundColor: Theme.of(context).errorColor,
78+
backgroundColor: Theme.of(context).colorScheme.error,
7879
foregroundColor: Colors.white,
7980
autoClose: true,
8081
onPressed: onDelete,
@@ -100,7 +101,8 @@ class AlbumCard extends StatelessWidget {
100101
width: kAlbumAnchorRadius * 2.0 + 1.0,
101102
decoration: BoxDecoration(
102103
color: Theme.of(context).primaryColor,
103-
border: Border.all(color: Theme.of(context).primaryColor, width: 1.0),
104+
border: Border.all(
105+
color: Theme.of(context).primaryColor, width: 1.0),
104106
),
105107
),
106108
),
@@ -120,7 +122,8 @@ class AlbumCard extends StatelessWidget {
120122
padding: const EdgeInsets.all(8.0).copyWith(right: 0.0),
121123
decoration: BoxDecoration(
122124
color: Theme.of(context).cardColor,
123-
border: Border.all(color: Theme.of(context).cardColor, width: 1.0),
125+
border:
126+
Border.all(color: Theme.of(context).cardColor, width: 1.0),
124127
),
125128
child: AlbumCardContent(
126129
album: album,

lib/components/cards/image_card.dart

Lines changed: 65 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -27,74 +27,81 @@ class ImageCard extends StatelessWidget {
2727
return GestureDetector(
2828
onTap: onPressed,
2929
onLongPress: onLongPress,
30-
child: Stack(
31-
fit: StackFit.expand,
32-
children: [
33-
_buildThumbnail(context),
34-
Positioned(
35-
bottom: 0,
36-
right: 0,
37-
left: 0,
38-
child: Column(
39-
mainAxisSize: MainAxisSize.min,
40-
crossAxisAlignment: CrossAxisAlignment.stretch,
41-
children: [
42-
Row(
43-
mainAxisAlignment: MainAxisAlignment.start,
44-
crossAxisAlignment: CrossAxisAlignment.center,
45-
children: [
46-
if (image.isVideo)
47-
Padding(
48-
padding: const EdgeInsets.all(2.0),
49-
child: Icon(
50-
Icons.local_movies,
51-
color: Color(0xFFFFFFFF),
52-
size: 12,
53-
shadows: AppShadows.icon,
30+
child: ClipRRect(
31+
borderRadius: BorderRadius.circular(5.0),
32+
child: Stack(
33+
fit: StackFit.expand,
34+
children: [
35+
_buildThumbnail(context),
36+
Positioned(
37+
bottom: 0,
38+
right: 0,
39+
left: 0,
40+
child: Column(
41+
mainAxisSize: MainAxisSize.min,
42+
crossAxisAlignment: CrossAxisAlignment.stretch,
43+
children: [
44+
Row(
45+
mainAxisAlignment: MainAxisAlignment.start,
46+
crossAxisAlignment: CrossAxisAlignment.center,
47+
children: [
48+
if (image.isVideo)
49+
Padding(
50+
padding: const EdgeInsets.all(2.0),
51+
child: Icon(
52+
Icons.local_movies,
53+
color: Color(0xFFFFFFFF),
54+
size: 12,
55+
shadows: AppShadows.icon,
56+
),
5457
),
55-
),
56-
if (image.favorite)
57-
Padding(
58-
padding: const EdgeInsets.all(2.0),
59-
child: Icon(
60-
Icons.favorite,
61-
color: Color(0xFFFFFFFF),
62-
size: 12,
63-
shadows: AppShadows.icon,
58+
if (image.favorite)
59+
Padding(
60+
padding: const EdgeInsets.all(2.0),
61+
child: Icon(
62+
Icons.favorite,
63+
color: Color(0xFFFFFFFF),
64+
size: 12,
65+
shadows: AppShadows.icon,
66+
),
6467
),
68+
],
69+
),
70+
if (Preferences.getShowThumbnailTitle)
71+
Container(
72+
padding: const EdgeInsets.all(2.0),
73+
decoration: BoxDecoration(
74+
gradient: LinearGradient(
75+
colors: [
76+
Colors.black,
77+
Colors.black.withOpacity(0),
78+
],
79+
begin: Alignment.bottomCenter,
80+
end: Alignment.topCenter),
81+
),
82+
child: AutoSizeText(
83+
image.name,
84+
maxLines: 1,
85+
maxFontSize: 14,
86+
minFontSize: 8,
87+
textAlign: TextAlign.center,
88+
overflow: TextOverflow.ellipsis,
89+
style: TextStyle(color: Colors.white, fontSize: 14),
6590
),
66-
],
67-
),
68-
if (Preferences.getShowThumbnailTitle)
69-
Container(
70-
padding: const EdgeInsets.all(2.0),
71-
decoration: BoxDecoration(
72-
gradient: LinearGradient(colors: [
73-
Colors.black,
74-
Colors.black.withOpacity(0),
75-
], begin: Alignment.bottomCenter, end: Alignment.topCenter),
76-
),
77-
child: AutoSizeText(
78-
image.name,
79-
maxLines: 1,
80-
maxFontSize: 14,
81-
minFontSize: 8,
82-
textAlign: TextAlign.center,
83-
overflow: TextOverflow.ellipsis,
84-
style: TextStyle(color: Colors.white, fontSize: 14),
8591
),
86-
),
87-
],
92+
],
93+
),
8894
),
89-
),
90-
..._buildSelectOverlay(context),
91-
],
95+
..._buildSelectOverlay(context),
96+
],
97+
),
9298
),
9399
);
94100
}
95101

96102
Widget _buildThumbnail(context) {
97-
final String? imageUrl = image.getDerivativeFromString(Preferences.getImageThumbnailSize)?.url;
103+
final String? imageUrl =
104+
image.getDerivativeFromString(Preferences.getImageThumbnailSize)?.url;
98105
return CachedNetworkImage(
99106
imageUrl: imageUrl ?? '',
100107
fadeInDuration: const Duration(milliseconds: 300),

lib/components/fields/app_field.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,14 @@ class AppField extends StatelessWidget {
100100
errorBorder: OutlineInputBorder(
101101
borderRadius: BorderRadius.circular(10.0),
102102
borderSide: BorderSide(
103-
color: Theme.of(context).errorColor,
103+
color: Theme.of(context).colorScheme.error,
104104
width: 1.0,
105105
),
106106
),
107107
focusedErrorBorder: OutlineInputBorder(
108108
borderRadius: BorderRadius.circular(10.0),
109109
borderSide: BorderSide(
110-
color: Theme.of(context).errorColor,
110+
color: Theme.of(context).colorScheme.error,
111111
width: 2.0,
112112
),
113113
),
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import 'package:flutter/material.dart';
2+
3+
class LoadingOverlay extends StatelessWidget {
4+
const LoadingOverlay({Key? key}) : super(key: key);
5+
6+
@override
7+
Widget build(BuildContext context) {
8+
return const Material(
9+
color: Colors.black38,
10+
child: Center(
11+
child: CircularProgressIndicator(),
12+
),
13+
);
14+
}
15+
}

lib/components/modals/add_tags_modal.dart

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,10 @@ class _AddTagsModalState extends State<AddTagsModal> {
5555
await _onRefresh();
5656
try {
5757
setState(() {
58-
_selectedTagList.add(_tagList.where((tag) => tag.id == addedTag.id).first);
58+
_selectedTagList
59+
.add(_tagList.where((tag) => tag.id == addedTag.id).first);
5960
});
60-
} on StateError catch (e) {
61+
} on StateError catch (_) {
6162
debugPrint('Can\'t fetch new tag');
6263
}
6364
}
@@ -77,7 +78,7 @@ class _AddTagsModalState extends State<AddTagsModal> {
7778
@override
7879
Widget build(BuildContext context) {
7980
return BottomSheet(
80-
backgroundColor: Theme.of(context).backgroundColor,
81+
backgroundColor: Theme.of(context).colorScheme.background,
8182
enableDrag: false,
8283
onClosing: () {},
8384
shape: const RoundedRectangleBorder(
@@ -132,7 +133,8 @@ class _AddTagsModalState extends State<AddTagsModal> {
132133
}),
133134
),
134135
Padding(
135-
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
136+
padding:
137+
const EdgeInsets.symmetric(vertical: 8.0, horizontal: 16.0),
136138
child: PiwigoButton(
137139
color: Theme.of(context).primaryColor,
138140
onPressed: () => Navigator.of(context).pop(),
@@ -146,7 +148,8 @@ class _AddTagsModalState extends State<AddTagsModal> {
146148
}
147149

148150
Widget get _tagLists {
149-
List<TagModel> unselectedTags = _tagList.where((tag) => !_selectedTagList.contains(tag)).toList();
151+
List<TagModel> unselectedTags =
152+
_tagList.where((tag) => !_selectedTagList.contains(tag)).toList();
150153
return RefreshIndicator(
151154
onRefresh: _onRefresh,
152155
child: Theme(
@@ -192,7 +195,9 @@ class _AddTagsModalState extends State<AddTagsModal> {
192195
}
193196

194197
class TagWrap extends StatelessWidget {
195-
const TagWrap({Key? key, this.tags = const [], this.removeAction = true, this.onTap}) : super(key: key);
198+
const TagWrap(
199+
{Key? key, this.tags = const [], this.removeAction = true, this.onTap})
200+
: super(key: key);
196201

197202
final List<TagModel> tags;
198203
final bool removeAction;

lib/components/modals/create_album_modal.dart

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ class CreateAlbumModal extends StatefulWidget {
1818
}
1919

2020
class _CreateAlbumModalState extends State<CreateAlbumModal> {
21-
final RoundedLoadingButtonController _btnController = RoundedLoadingButtonController();
21+
final RoundedLoadingButtonController _btnController =
22+
RoundedLoadingButtonController();
2223
final TextEditingController _descriptionController = TextEditingController();
2324

2425
String _name = '';
@@ -101,9 +102,7 @@ Future<void> showCreateAlbumModal(BuildContext context, int parentId) async {
101102
await showModalBottomSheet(
102103
context: context,
103104
isScrollControlled: true,
104-
builder: (_) => Padding(
105-
padding: MediaQuery.of(context).padding,
106-
child: CreateAlbumModal(albumId: parentId),
107-
),
105+
useSafeArea: true,
106+
builder: (_) => CreateAlbumModal(albumId: parentId),
108107
);
109108
}

0 commit comments

Comments
 (0)