feat: 长按保存封面

This commit is contained in:
guozhigq
2024-05-01 19:46:27 +08:00
parent e5c71bef64
commit 1b25d821f3
21 changed files with 430 additions and 515 deletions

View File

@ -15,24 +15,7 @@ class DownloadUtils {
PermissionStatus status = await Permission.storage.status;
if (status == PermissionStatus.denied ||
status == PermissionStatus.permanentlyDenied) {
SmartDialog.show(
useSystem: true,
animationType: SmartAnimationType.centerFade_otherSlide,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('提示'),
content: const Text('存储权限未授权'),
actions: [
TextButton(
onPressed: () async {
openAppSettings();
},
child: const Text('去授权'),
)
],
);
},
);
await permissionDialog('提示', '存储权限未授权');
return false;
} else {
return true;
@ -45,24 +28,7 @@ class DownloadUtils {
PermissionStatus status = await Permission.photos.status;
if (status == PermissionStatus.denied ||
status == PermissionStatus.permanentlyDenied) {
SmartDialog.show(
useSystem: true,
animationType: SmartAnimationType.centerFade_otherSlide,
builder: (BuildContext context) {
return AlertDialog(
title: const Text('提示'),
content: const Text('相册权限未授权'),
actions: [
TextButton(
onPressed: () async {
openAppSettings();
},
child: const Text('去授权'),
)
],
);
},
);
await permissionDialog('提示', '相册权限未授权');
return false;
} else {
return true;
@ -72,17 +38,16 @@ class DownloadUtils {
static Future<bool> downloadImg(String imgUrl,
{String imgType = 'cover'}) async {
try {
if (!Platform.isAndroid || !await requestPhotoPer()) {
return false;
}
final androidInfo = await DeviceInfoPlugin().androidInfo;
if (androidInfo.version.sdkInt <= 32) {
if (!await requestStoragePer()) {
return false;
}
} else {
if (!await requestPhotoPer()) {
return false;
if (Platform.isAndroid) {
final androidInfo = await DeviceInfoPlugin().androidInfo;
if (androidInfo.version.sdkInt <= 32) {
if (!await requestStoragePer()) {
return false;
}
} else {
if (!await requestPhotoPer()) {
return false;
}
}
}
@ -101,13 +66,38 @@ class DownloadUtils {
);
SmartDialog.dismiss();
if (result.isSuccess) {
await SmartDialog.showToast('${'$picName.$imgSuffix'}」已保存 ');
SmartDialog.showToast('${'$picName.$imgSuffix'}」已保存 ');
return true;
} else {
await permissionDialog('保存失败', '相册权限未授权');
return false;
}
return true;
} catch (err) {
SmartDialog.dismiss();
SmartDialog.showToast(err.toString());
return true;
return false;
}
}
static Future permissionDialog(String title, String content,
{Function? onGranted}) async {
await SmartDialog.show(
useSystem: true,
animationType: SmartAnimationType.centerFade_otherSlide,
builder: (BuildContext context) {
return AlertDialog(
title: Text(title),
content: Text(content),
actions: [
TextButton(
onPressed: () async {
openAppSettings();
},
child: const Text('去授权'),
)
],
);
},
);
}
}

88
lib/utils/image_save.dart Normal file
View File

@ -0,0 +1,88 @@
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:pilipala/common/constants.dart';
import 'package:pilipala/common/widgets/network_img_layer.dart';
import 'package:pilipala/utils/download.dart';
Future imageSaveDialog(context, videoItem, closeFn) {
final double imgWidth =
MediaQuery.sizeOf(context).width - StyleString.safeSpace * 2;
return SmartDialog.show(
animationType: SmartAnimationType.centerScale_otherSlide,
builder: (context) => Container(
margin: const EdgeInsets.symmetric(horizontal: StyleString.safeSpace),
decoration: BoxDecoration(
color: Theme.of(context).colorScheme.background,
borderRadius: BorderRadius.circular(10.0),
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Stack(
children: [
NetworkImgLayer(
width: imgWidth,
height: imgWidth / StyleString.aspectRatio,
src: videoItem.pic! as String,
quality: 100,
),
Positioned(
right: 8,
top: 8,
child: Container(
width: 30,
height: 30,
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.3),
borderRadius:
const BorderRadius.all(Radius.circular(20))),
child: IconButton(
style: ButtonStyle(
padding: MaterialStateProperty.all(EdgeInsets.zero),
),
onPressed: () => closeFn!(),
icon: const Icon(
Icons.close,
size: 18,
color: Colors.white,
),
),
),
),
],
),
Padding(
padding: const EdgeInsets.fromLTRB(12, 10, 8, 10),
child: Row(
children: [
Expanded(
child: Text(
videoItem.title! as String,
style: Theme.of(context).textTheme.titleSmall,
),
),
const SizedBox(width: 4),
IconButton(
tooltip: '保存封面图',
onPressed: () async {
bool saveStatus = await DownloadUtils.downloadImg(
videoItem.pic != null
? videoItem.pic as String
: videoItem.cover as String,
);
// 保存成功,自动关闭弹窗
if (saveStatus) {
closeFn?.call();
}
},
icon: const Icon(Icons.download, size: 20),
)
],
),
),
],
),
),
);
}