@@ -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 }
0 commit comments