Skip to content

Commit a24611c

Browse files
Fix cached image cleanup
1 parent 8f9db18 commit a24611c

10 files changed

+446
-84
lines changed

lib/ui/camera_picker/model/camera_picker_cubit.dart

+29-13
Original file line numberDiff line numberDiff line change
@@ -27,34 +27,50 @@ class CameraPickerCubit extends Cubit<CameraPickerState> {
2727

2828
CameraPickerCubit(this._fs) : super(CameraPickerState.initial());
2929

30-
void load(XFileImage image) {
30+
@override
31+
Future<void> close() async {
32+
await _cleanup();
33+
34+
return super.close();
35+
}
36+
37+
Future<void> load(XFileImage image) async {
38+
if (state is! CameraPickerStateInitial) {
39+
await _cleanup();
40+
}
3141
emit(CameraPickerState.loaded(image: image));
3242
}
3343

3444
Future<void> reject() async {
3545
if (state case CameraPickerStateLoaded(:final image)) {
36-
await _removeImage(image);
37-
await image.evict();
3846
emit(CameraPickerState.rejected(image: image));
3947
}
4048
}
4149

4250
Future<void> accept(CameraPickerMetadata metadata) async {
4351
if (state case CameraPickerStateLoaded(:final image)) {
44-
await image.evict();
4552
emit(CameraPickerState.accepted(image: image, metadata: metadata));
4653
}
4754
}
4855

49-
Future<void> _removeImage(XFileImage image) async {
50-
try {
51-
await _fs.file(image.file.path).delete();
52-
} on Exception catch (e, stackTrace) {
53-
log().e(
54-
'Unable to delete cached image',
55-
error: e,
56-
stackTrace: stackTrace,
57-
);
56+
Future<void> _cleanup() async {
57+
switch (state) {
58+
case CameraPickerStateInitial():
59+
break;
60+
case CameraPickerStateAccepted(:final image):
61+
await image.evict();
62+
case CameraPickerStateLoaded(:final image) ||
63+
CameraPickerStateRejected(:final image):
64+
await image.evict();
65+
try {
66+
await _fs.file(image.file.path).delete();
67+
} on Exception catch (e, stackTrace) {
68+
log().e(
69+
'Unable to delete cached image',
70+
error: e,
71+
stackTrace: stackTrace,
72+
);
73+
}
5874
}
5975
}
6076
}

lib/ui/comparison/blink_comparison_page.dart

+25-27
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import 'package:blink_comparison/ui/comparison/model/blink_comparison_state.dart
2121
import 'package:blink_comparison/ui/comparison/model/comparison_settings_state.dart';
2222
import 'package:blink_comparison/ui/components/widget.dart';
2323
import 'package:blink_comparison/ui/model/showcase_cubit.dart';
24+
import 'package:blink_comparison/ui/model/xfile_image.dart';
25+
import 'package:file/file.dart';
2426
import 'package:flutter/material.dart';
2527
import 'package:flutter_bloc/flutter_bloc.dart';
2628
import 'package:showcaseview/showcaseview.dart';
@@ -37,7 +39,7 @@ final _blinkComparisonShowcaseKey = GlobalKey();
3739
@RoutePage()
3840
class BlinkComparisonPage extends StatefulWidget implements AutoRouteWrapper {
3941
final ImageProvider refImage;
40-
final ImageProvider takenPhoto;
42+
final XFileImage takenPhoto;
4143
final double aspectRatio;
4244

4345
const BlinkComparisonPage({
@@ -52,7 +54,7 @@ class BlinkComparisonPage extends StatefulWidget implements AutoRouteWrapper {
5254
return MultiBlocProvider(
5355
providers: [
5456
BlocProvider(
55-
create: (context) => BlinkComparisonCubit(),
57+
create: (context) => BlinkComparisonCubit(getIt<FileSystem>()),
5658
),
5759
BlocProvider(
5860
create: (context) => ComparisonSettingsCubit(getIt<AppSettings>()),
@@ -76,32 +78,22 @@ class _BlinkComparisonPageState extends State<BlinkComparisonPage> {
7678

7779
WidgetsBinding.instance.addPostFrameCallback((_) async {
7880
await Future.wait([
79-
context.read<ComparisonSettingsCubit>().load(),
80-
context.read<ShowcaseCubit>().load(),
81+
precacheImage(widget.takenPhoto, context),
82+
precacheImage(widget.refImage, context),
8183
]);
84+
if (mounted) {
85+
await Future.wait([
86+
context.read<BlinkComparisonCubit>().load(
87+
refImage: widget.refImage,
88+
takenPhoto: widget.takenPhoto,
89+
),
90+
context.read<ComparisonSettingsCubit>().load(),
91+
context.read<ShowcaseCubit>().load(),
92+
]);
93+
}
8294
});
8395
}
8496

85-
@override
86-
void didChangeDependencies() {
87-
Future.wait([
88-
precacheImage(widget.takenPhoto, context),
89-
precacheImage(widget.refImage, context),
90-
]).then(
91-
(_) {
92-
final c = context;
93-
if (c.mounted) {
94-
final cubit = c.read<BlinkComparisonCubit>();
95-
if (cubit.state case BlinkComparisonStateInitial()) {
96-
cubit.switchImage();
97-
}
98-
}
99-
},
100-
);
101-
102-
super.didChangeDependencies();
103-
}
104-
10597
@override
10698
Widget build(BuildContext context) {
10799
return BlocBuilder<ComparisonSettingsCubit, ComparisonSettingsState>(
@@ -188,11 +180,17 @@ class _BodyState extends State<_Body> {
188180
behavior: HitTestBehavior.translucent,
189181
onTap: () => _onSwitchImage(context),
190182
child: Center(
191-
child:
192-
BlocBuilder<BlinkComparisonCubit, BlinkComparisonState>(
183+
child: BlocConsumer<BlinkComparisonCubit,
184+
BlinkComparisonState>(
185+
listener: (context, state) async {
186+
if (state case BlinkComparisonStateLoaded()) {
187+
context.read<BlinkComparisonCubit>().switchImage();
188+
}
189+
},
193190
builder: (context, state) {
194191
return switch (state) {
195-
BlinkComparisonStateInitial() =>
192+
BlinkComparisonStateInitial() ||
193+
BlinkComparisonStateLoaded() =>
196194
const CircularProgressIndicator(),
197195
BlinkComparisonStateShowRefImage() =>
198196
widget.refImageWidget,

lib/ui/comparison/model/blink_comparison_cubit.dart

+70-7
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,83 @@
1515
// You should have received a copy of the GNU General Public License
1616
// along with Blink Comparison. If not, see <http://www.gnu.org/licenses/>.
1717

18+
import 'package:blink_comparison/logger.dart';
1819
import 'package:blink_comparison/ui/comparison/model/blink_comparison_state.dart';
20+
import 'package:blink_comparison/ui/model/xfile_image.dart';
21+
import 'package:file/file.dart';
22+
import 'package:flutter/widgets.dart';
1923
import 'package:flutter_bloc/flutter_bloc.dart';
2024

2125
class BlinkComparisonCubit extends Cubit<BlinkComparisonState> {
22-
BlinkComparisonCubit() : super(const BlinkComparisonState.initial());
26+
final FileSystem _fs;
27+
28+
BlinkComparisonCubit(this._fs) : super(const BlinkComparisonState.initial());
29+
30+
@override
31+
Future<void> close() async {
32+
await _cleanup();
33+
34+
return super.close();
35+
}
36+
37+
Future<void> load({
38+
required ImageProvider refImage,
39+
required XFileImage takenPhoto,
40+
}) async {
41+
if (state is! BlinkComparisonStateInitial) {
42+
await _cleanup();
43+
}
44+
emit(BlinkComparisonState.loaded(
45+
refImage: refImage,
46+
takenPhoto: takenPhoto,
47+
));
48+
}
2349

2450
void switchImage() {
2551
final newState = switch (state) {
26-
BlinkComparisonStateInitial() ||
27-
BlinkComparisonStateShowRefImage() =>
28-
const BlinkComparisonState.showTakenPhoto(),
29-
BlinkComparisonStateShowTakenPhoto() =>
30-
const BlinkComparisonState.showRefImage(),
52+
BlinkComparisonStateInitial() => null,
53+
BlinkComparisonStateLoaded(:final refImage, :final takenPhoto) ||
54+
BlinkComparisonStateShowRefImage(:final refImage, :final takenPhoto) =>
55+
BlinkComparisonState.showTakenPhoto(
56+
refImage: refImage,
57+
takenPhoto: takenPhoto,
58+
),
59+
BlinkComparisonStateShowTakenPhoto(:final refImage, :final takenPhoto) =>
60+
BlinkComparisonState.showRefImage(
61+
refImage: refImage,
62+
takenPhoto: takenPhoto,
63+
),
3164
};
32-
emit(newState);
65+
if (newState != null) {
66+
emit(newState);
67+
}
68+
}
69+
70+
Future<void> _cleanup() async {
71+
if (state
72+
case BlinkComparisonStateLoaded(
73+
:final refImage,
74+
:final takenPhoto,
75+
) ||
76+
BlinkComparisonStateShowRefImage(
77+
:final refImage,
78+
:final takenPhoto,
79+
) ||
80+
BlinkComparisonStateShowTakenPhoto(
81+
:final refImage,
82+
:final takenPhoto,
83+
)) {
84+
await refImage.evict();
85+
await takenPhoto.evict();
86+
try {
87+
await _fs.file(takenPhoto.file.path).delete();
88+
} on Exception catch (e, stackTrace) {
89+
log().e(
90+
'Unable to delete cached image',
91+
error: e,
92+
stackTrace: stackTrace,
93+
);
94+
}
95+
}
3396
}
3497
}

lib/ui/comparison/model/blink_comparison_state.dart

+15-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
// You should have received a copy of the GNU General Public License
1616
// along with Blink Comparison. If not, see <http://www.gnu.org/licenses/>.
1717

18+
import 'package:blink_comparison/ui/model/xfile_image.dart';
19+
import 'package:flutter/widgets.dart';
1820
import 'package:freezed_annotation/freezed_annotation.dart';
1921

2022
part 'blink_comparison_state.freezed.dart';
@@ -23,9 +25,18 @@ part 'blink_comparison_state.freezed.dart';
2325
sealed class BlinkComparisonState with _$BlinkComparisonState {
2426
const factory BlinkComparisonState.initial() = BlinkComparisonStateInitial;
2527

26-
const factory BlinkComparisonState.showRefImage() =
27-
BlinkComparisonStateShowRefImage;
28+
const factory BlinkComparisonState.loaded({
29+
required ImageProvider refImage,
30+
required XFileImage takenPhoto,
31+
}) = BlinkComparisonStateLoaded;
2832

29-
const factory BlinkComparisonState.showTakenPhoto() =
30-
BlinkComparisonStateShowTakenPhoto;
33+
const factory BlinkComparisonState.showRefImage({
34+
required ImageProvider refImage,
35+
required XFileImage takenPhoto,
36+
}) = BlinkComparisonStateShowRefImage;
37+
38+
const factory BlinkComparisonState.showTakenPhoto({
39+
required ImageProvider refImage,
40+
required XFileImage takenPhoto,
41+
}) = BlinkComparisonStateShowTakenPhoto;
3142
}

0 commit comments

Comments
 (0)