obsolete files: give error hint on viewer, allow deleting from media store
This commit is contained in:
parent
34b6ef0428
commit
f6434f0b5f
3 changed files with 48 additions and 14 deletions
|
@ -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)
|
||||
|
|
|
@ -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),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
}),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue