Skip to content

Commit 9846add

Browse files
committed
Added cache manager
1 parent 8012d8e commit 9846add

7 files changed

Lines changed: 134 additions & 119 deletions

File tree

lib/components/cards/album_card.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ class AlbumCardContent extends StatelessWidget {
198198
return CachedNetworkImage(
199199
imageUrl: album.urlRepresentative!,
200200
fit: BoxFit.cover,
201+
fadeInDuration: const Duration(milliseconds: 300),
201202
progressIndicatorBuilder: (context, url, download) {
202203
if (download.downloaded >= (download.totalSize ?? 0)) {
203204
return const SizedBox();

lib/components/cards/image_card.dart

Lines changed: 97 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -30,55 +30,7 @@ class ImageCard extends StatelessWidget {
3030
child: Stack(
3131
fit: StackFit.expand,
3232
children: [
33-
Builder(builder: (context) {
34-
final String? imageUrl = image.getDerivativeFromString(Preferences.getImageThumbnailSize)?.url;
35-
return CachedNetworkImage(
36-
imageUrl: imageUrl ?? '',
37-
imageBuilder: (context, provider) => Hero(
38-
tag: "<hero image ${image.id}>",
39-
child: Image(
40-
image: provider,
41-
fit: BoxFit.cover,
42-
errorBuilder: (context, o, s) {
43-
debugPrint("$o\n$s");
44-
return FittedBox(
45-
fit: BoxFit.cover,
46-
child: Container(
47-
padding: const EdgeInsets.all(16.0),
48-
decoration: BoxDecoration(
49-
color: Theme.of(context).scaffoldBackgroundColor,
50-
),
51-
child: const Icon(Icons.broken_image_outlined),
52-
),
53-
);
54-
},
55-
),
56-
),
57-
progressIndicatorBuilder: (context, url, download) {
58-
if (download.downloaded >= (download.totalSize ?? 0)) {
59-
return const SizedBox();
60-
}
61-
return Center(
62-
child: CircularProgressIndicator(
63-
value: download.progress,
64-
),
65-
);
66-
},
67-
errorWidget: (context, url, error) {
68-
debugPrint("[$url] $error");
69-
return FittedBox(
70-
fit: BoxFit.cover,
71-
child: Container(
72-
padding: const EdgeInsets.all(16.0),
73-
decoration: BoxDecoration(
74-
color: Theme.of(context).scaffoldBackgroundColor,
75-
),
76-
child: const Icon(Icons.broken_image_outlined),
77-
),
78-
);
79-
},
80-
);
81-
}),
33+
_buildThumbnail(context),
8234
Positioned(
8335
bottom: 0,
8436
right: 0,
@@ -135,54 +87,106 @@ class ImageCard extends StatelessWidget {
13587
],
13688
),
13789
),
138-
AnimatedOpacity(
139-
duration: selectDuration,
140-
curve: selectCurve,
141-
opacity: selected == true ? 0.5 : 0.0,
142-
child: Container(
143-
color: Colors.black,
144-
child: const Center(),
145-
),
90+
..._buildSelectOverlay(context),
91+
],
92+
),
93+
);
94+
}
95+
96+
Widget _buildThumbnail(context) {
97+
final String? imageUrl = image.getDerivativeFromString(Preferences.getImageThumbnailSize)?.url;
98+
return CachedNetworkImage(
99+
imageUrl: imageUrl ?? '',
100+
fadeInDuration: const Duration(milliseconds: 300),
101+
imageBuilder: (context, provider) => Hero(
102+
tag: "<hero image ${image.id}>",
103+
child: Image(
104+
image: provider,
105+
fit: BoxFit.cover,
106+
errorBuilder: (context, o, s) {
107+
debugPrint("$o\n$s");
108+
return _buildErrorWidget(context);
109+
},
110+
),
111+
),
112+
progressIndicatorBuilder: (context, url, download) {
113+
if (download.downloaded >= (download.totalSize ?? 0)) {
114+
return const SizedBox();
115+
}
116+
return Center(
117+
child: CircularProgressIndicator(
118+
value: download.progress,
146119
),
147-
Positioned(
148-
top: 4,
149-
right: 4,
150-
child: Stack(
151-
children: [
152-
AnimatedScale(
153-
duration: selectDuration,
154-
curve: selectCurve,
155-
scale: selected == false ? 1 : 0,
156-
child: AnimatedOpacity(
157-
duration: selectDuration,
158-
curve: selectCurve,
159-
opacity: selected == false ? 1 : 0,
160-
child: Container(
161-
height: 20,
162-
width: 20,
163-
decoration: BoxDecoration(
164-
shape: BoxShape.circle,
165-
border: Border.all(color: Theme.of(context).primaryColor),
166-
color: Colors.black.withOpacity(0.3),
167-
),
168-
),
169-
),
170-
),
171-
AnimatedScale(
172-
duration: selectDuration,
173-
curve: selectCurve,
174-
scale: selected == true ? 1 : 0,
175-
child: AnimatedOpacity(
176-
duration: selectDuration,
177-
curve: selectCurve,
178-
opacity: selected == true ? 1 : 0,
179-
child: Icon(Icons.check_circle, size: 20),
120+
);
121+
},
122+
errorWidget: (context, url, error) {
123+
debugPrint("[$url] $error");
124+
return _buildErrorWidget(context);
125+
},
126+
);
127+
}
128+
129+
List<Widget> _buildSelectOverlay(context) {
130+
return [
131+
AnimatedOpacity(
132+
duration: selectDuration,
133+
curve: selectCurve,
134+
opacity: selected == true ? 0.5 : 0.0,
135+
child: Container(
136+
color: Colors.black,
137+
child: const Center(),
138+
),
139+
),
140+
Positioned(
141+
top: 4,
142+
right: 4,
143+
child: Stack(
144+
children: [
145+
AnimatedScale(
146+
duration: selectDuration,
147+
curve: selectCurve,
148+
scale: selected == false ? 1 : 0,
149+
child: AnimatedOpacity(
150+
duration: selectDuration,
151+
curve: selectCurve,
152+
opacity: selected == false ? 1 : 0,
153+
child: Container(
154+
height: 20,
155+
width: 20,
156+
decoration: BoxDecoration(
157+
shape: BoxShape.circle,
158+
border: Border.all(color: Theme.of(context).primaryColor),
159+
color: Colors.black.withOpacity(0.3),
180160
),
181161
),
182-
],
162+
),
183163
),
184-
),
185-
],
164+
AnimatedScale(
165+
duration: selectDuration,
166+
curve: selectCurve,
167+
scale: selected == true ? 1 : 0,
168+
child: AnimatedOpacity(
169+
duration: selectDuration,
170+
curve: selectCurve,
171+
opacity: selected == true ? 1 : 0,
172+
child: Icon(Icons.check_circle, size: 20),
173+
),
174+
),
175+
],
176+
),
177+
),
178+
];
179+
}
180+
181+
Widget _buildErrorWidget(BuildContext context) {
182+
return FittedBox(
183+
fit: BoxFit.cover,
184+
child: Container(
185+
padding: const EdgeInsets.all(16.0),
186+
decoration: BoxDecoration(
187+
color: Theme.of(context).scaffoldBackgroundColor,
188+
),
189+
child: const Icon(Icons.broken_image_outlined),
186190
),
187191
);
188192
}

lib/components/fields/app_field.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ class AppField extends StatelessWidget {
4545
decoration: BoxDecoration(
4646
borderRadius: BorderRadius.circular(10.0),
4747
color: color ?? Theme.of(context).inputDecorationTheme.fillColor,
48-
//border: error ? Border.all(color: Theme.of(context).errorColor, width: 1) : null,
4948
),
5049
child: TextFormField(
5150
controller: controller,

lib/views/authentication/login_form_view.dart

Lines changed: 29 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -173,16 +173,7 @@ class _LoginFormViewState extends State<LoginFormView> {
173173
});
174174
},
175175
textInputAction: TextInputAction.next,
176-
prefix: Row(
177-
mainAxisSize: MainAxisSize.min,
178-
children: [
179-
Padding(
180-
padding: const EdgeInsets.symmetric(horizontal: 8.0),
181-
child: const Icon(Icons.public),
182-
),
183-
_securedPrefix,
184-
],
185-
),
176+
prefix: _securedPrefix,
186177
hint: 'example.piwigo.com',
187178
error: _urlError,
188179
),
@@ -211,7 +202,10 @@ class _LoginFormViewState extends State<LoginFormView> {
211202
}),
212203
child: Padding(
213204
padding: const EdgeInsets.all(8.0),
214-
child: Icon(Icons.clear),
205+
child: Icon(
206+
Icons.clear,
207+
color: Theme.of(context).colorScheme.secondary,
208+
),
215209
),
216210
)
217211
: null,
@@ -251,7 +245,10 @@ class _LoginFormViewState extends State<LoginFormView> {
251245
}),
252246
child: Padding(
253247
padding: const EdgeInsets.all(8.0),
254-
child: Icon(Icons.clear),
248+
child: Icon(
249+
Icons.clear,
250+
color: Theme.of(context).colorScheme.secondary,
251+
),
255252
),
256253
)
257254
: null,
@@ -279,19 +276,28 @@ class _LoginFormViewState extends State<LoginFormView> {
279276
onTap: () => setState(() {
280277
_isSecured = !_isSecured;
281278
}),
282-
child: Stack(
283-
clipBehavior: Clip.none,
279+
child: Row(
280+
mainAxisSize: MainAxisSize.min,
284281
children: [
285-
Text(
286-
'${_isSecured ? 'https' : 'http'}://',
287-
style: Theme.of(context).textTheme.bodyMedium,
282+
Padding(
283+
padding: const EdgeInsets.symmetric(horizontal: 8.0),
284+
child: const Icon(Icons.public),
288285
),
289-
Positioned(
290-
top: Theme.of(context).textTheme.bodyMedium?.fontSize,
291-
child: Text(
292-
!_isSecured ? 'https' : 'http',
293-
style: Theme.of(context).textTheme.bodyMedium?.copyWith(fontSize: 11),
294-
),
286+
Stack(
287+
clipBehavior: Clip.none,
288+
children: [
289+
Text(
290+
'${_isSecured ? 'https' : 'http'}://',
291+
style: Theme.of(context).textTheme.bodyMedium,
292+
),
293+
Positioned(
294+
top: Theme.of(context).textTheme.bodyMedium?.fontSize,
295+
child: Text(
296+
!_isSecured ? 'https' : 'http',
297+
style: Theme.of(context).textTheme.bodyMedium?.copyWith(fontSize: 11),
298+
),
299+
),
300+
],
295301
),
296302
],
297303
),

lib/views/image/video_view.dart

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -462,8 +462,6 @@ class VideoPlayerView extends StatefulWidget {
462462
}
463463

464464
class _VideoPlayerViewState extends State<VideoPlayerView> {
465-
static const Duration overlayAnimationDuration = Duration(milliseconds: 300);
466-
static const Curve overlayAnimationCurve = Curves.ease;
467465
late VideoPlayerController _videoPlayerController;
468466
late PlayerProvider _provider;
469467
ChewieController? _chewieController;

lib/views/settings/settings_view_page.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:io';
22
import 'dart:math';
33

44
import 'package:flutter/material.dart';
5+
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
56
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
67
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
78
import 'package:package_info_plus/package_info_plus.dart';
@@ -89,6 +90,7 @@ class _SettingsViewPageState extends State<SettingsViewPage> {
8990
Future<double?> _getCacheSize() async {
9091
int? totalSize = 0;
9192
final cacheDir = await getTemporaryDirectory();
93+
9294
try {
9395
if (cacheDir.existsSync()) {
9496
cacheDir.listSync(recursive: true, followLinks: false).forEach((FileSystemEntity entity) {
@@ -107,9 +109,13 @@ class _SettingsViewPageState extends State<SettingsViewPage> {
107109

108110
Future<void> _clearCache() async {
109111
final cacheDir = await getTemporaryDirectory();
112+
final imageCache = DefaultCacheManager();
113+
110114
if (cacheDir.existsSync()) {
111115
cacheDir.deleteSync(recursive: true);
112116
}
117+
await imageCache.emptyCache();
118+
113119
setState(() {});
114120
}
115121

pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ dependencies:
5454
flutter_image_compress: ^1.1.3 # Remove metadata
5555
permission_handler: ^8.3.0 # Check and asks for permissions
5656
share_plus: ^4.4.0 # Share files
57+
flutter_cache_manager: ^3.3.0 # Handles network image cache
5758

5859
# Translations
5960
flutter_localizations:

0 commit comments

Comments
 (0)