obsolete files: give error hint on viewer, allow deleting from media store

This commit is contained in:
Thibault Deckers 2021-01-30 19:12:11 +09:00
parent 34b6ef0428
commit f6434f0b5f
3 changed files with 48 additions and 14 deletions

View file

@ -186,7 +186,7 @@ class MediaStoreImageProvider : ImageProvider() {
override suspend fun delete(context: Context, uri: Uri, path: String?) {
path ?: throw Exception("failed to delete file because path is null")
if (requireAccessPermission(context, path)) {
if (File(path).exists() && requireAccessPermission(context, path)) {
// if the file is on SD card, calling the content resolver `delete()` removes the entry from the Media Store
// but it doesn't delete the file, even if the app has the permission
val df = getDocumentFile(context, path, uri)

View file

@ -129,7 +129,10 @@ class _EntryPageViewState extends State<EntryPageView> {
} else if (entry.canDecode) {
child = _buildRasterView();
}
child ??= ErrorView(onTap: () => onTap?.call(null));
child ??= ErrorView(
entry: entry,
onTap: () => onTap?.call(null),
);
return widget.heroTag != null
? Hero(
@ -146,7 +149,10 @@ class _EntryPageViewState extends State<EntryPageView> {
child: RasterImageView(
entry: entry,
viewStateNotifier: _viewStateNotifier,
errorBuilder: (context, error, stackTrace) => ErrorView(onTap: () => onTap?.call(null)),
errorBuilder: (context, error, stackTrace) => ErrorView(
entry: entry,
onTap: () => onTap?.call(null),
),
),
);
}

View file

@ -1,26 +1,54 @@
import 'dart:io';
import 'package:aves/model/entry.dart';
import 'package:aves/theme/icons.dart';
import 'package:aves/widgets/collection/empty.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
class ErrorView extends StatelessWidget {
class ErrorView extends StatefulWidget {
final AvesEntry entry;
final VoidCallback onTap;
const ErrorView({@required this.onTap});
const ErrorView({
@required this.entry,
@required this.onTap,
});
@override
_ErrorViewState createState() => _ErrorViewState();
}
class _ErrorViewState extends State<ErrorView> {
Future<bool> _exists;
AvesEntry get entry => widget.entry;
@override
void initState() {
super.initState();
_exists = entry.path != null ? File(entry.path).exists() : SynchronousFuture(true);
}
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => onTap?.call(),
// use a `Container` with a dummy color to make it expand
// so that we can also detect taps around the title `Text`
onTap: () => widget.onTap?.call(),
// use container to expand constraints, so that the user can tap anywhere
child: Container(
color: Colors.transparent,
child: EmptyContent(
icon: AIcons.error,
text: 'Oops!',
alignment: Alignment.center,
),
// opaque to cover potential lower quality layer below
color: Colors.black,
child: FutureBuilder<bool>(
future: _exists,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) return SizedBox();
final exists = snapshot.data;
return EmptyContent(
icon: AIcons.error,
text: exists ? 'Oops!' : 'The file no longer exists.',
alignment: Alignment.center,
);
}),
),
);
}