277 lines
8.2 KiB
Dart
277 lines
8.2 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:extended_image/extended_image.dart';
|
|
import 'package:file_selector/file_selector.dart';
|
|
import 'package:flutter/foundation.dart' show kIsWeb;
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/services.dart';
|
|
import 'package:flutter_dmzj/app/app_style.dart';
|
|
import 'package:flutter_dmzj/app/log.dart';
|
|
import 'package:flutter_dmzj/requests/common_request.dart';
|
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:image_gallery_saver_plus/image_gallery_saver_plus.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:package_info_plus/package_info_plus.dart';
|
|
import 'package:path_provider/path_provider.dart';
|
|
import 'package:permission_handler/permission_handler.dart';
|
|
// ignore: depend_on_referenced_packages
|
|
import 'package:path/path.dart' as p;
|
|
import 'package:share_plus/share_plus.dart';
|
|
import 'package:url_launcher/url_launcher_string.dart';
|
|
|
|
class Utils {
|
|
static late PackageInfo packageInfo;
|
|
static DateFormat dateFormat = DateFormat("yyyy-MM-dd");
|
|
static DateFormat dateTimeFormat = DateFormat("MM-dd HH:mm");
|
|
static DateFormat dateTimeFormatWithYear = DateFormat("yyyy-MM-dd HH:mm");
|
|
|
|
/// 版本号解析
|
|
static int parseVersion(String version) {
|
|
var sp = version.split('.');
|
|
var num = "";
|
|
for (var item in sp) {
|
|
num = num + item.padLeft(2, '0');
|
|
}
|
|
return int.parse(num);
|
|
}
|
|
|
|
/// 时间戳格式化-秒
|
|
static String formatTimestamp(int ts) {
|
|
if (ts == 0) {
|
|
return "----";
|
|
}
|
|
return formatTimestampMS(ts * 1000);
|
|
}
|
|
|
|
static String formatTimestampToDate(int ts) {
|
|
if (ts == 0) {
|
|
return "----";
|
|
}
|
|
var dt = DateTime.fromMillisecondsSinceEpoch(ts * 1000);
|
|
return dateFormat.format(dt);
|
|
}
|
|
|
|
/// 时间戳格式化-毫秒
|
|
static String formatTimestampMS(int ts) {
|
|
var dt = DateTime.fromMillisecondsSinceEpoch(ts);
|
|
|
|
var dtNow = DateTime.now();
|
|
if (dt.year == dtNow.year &&
|
|
dt.month == dtNow.month &&
|
|
dt.day == dtNow.day) {
|
|
return "今天${dt.hour.toString().padLeft(2, '0')}:${dt.minute.toString().padLeft(2, '0')}";
|
|
}
|
|
if (dt.year == dtNow.year &&
|
|
dt.month == dtNow.month &&
|
|
dt.day == dtNow.day - 1) {
|
|
return "昨天${dt.hour.toString().padLeft(2, '0')}:${dt.minute.toString().padLeft(2, '0')}";
|
|
}
|
|
|
|
if (dt.year == dtNow.year) {
|
|
return dateTimeFormat.format(dt);
|
|
}
|
|
|
|
return dateTimeFormatWithYear.format(dt);
|
|
}
|
|
|
|
/// 检查相册权限
|
|
static Future<bool> checkPhotoPermission() async {
|
|
try {
|
|
var status = await Permission.photos.status;
|
|
if (status == PermissionStatus.granted) {
|
|
return true;
|
|
}
|
|
status = await Permission.photos.request();
|
|
if (status.isGranted) {
|
|
return true;
|
|
} else {
|
|
SmartDialog.showToast("请授予相册权限");
|
|
return false;
|
|
}
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// 保存图片
|
|
static void saveImage(String url) async {
|
|
if (Platform.isIOS && !await Utils.checkPhotoPermission()) {
|
|
return;
|
|
}
|
|
try {
|
|
Uint8List? data;
|
|
if (url.startsWith("http")) {
|
|
var provider = ExtendedNetworkImageProvider(url, cache: true);
|
|
data = await provider.getNetworkImageData();
|
|
} else {
|
|
data = await File(url).readAsBytes();
|
|
}
|
|
|
|
if (data == null) {
|
|
SmartDialog.showToast("图片保存失败");
|
|
return;
|
|
}
|
|
if (!kIsWeb && (Platform.isMacOS || Platform.isWindows || Platform.isLinux)) {
|
|
saveImageDetktop(p.basename(url), data);
|
|
} else {
|
|
var cacheDir = await getTemporaryDirectory();
|
|
var file = File(p.join(cacheDir.path, p.basename(url)));
|
|
await file.writeAsBytes(data);
|
|
final result = await ImageGallerySaverPlus.saveFile(
|
|
file.path,
|
|
name: p.basename(url),
|
|
isReturnPathOfIOS: true,
|
|
);
|
|
Log.d(result.toString());
|
|
SmartDialog.showToast("保存成功");
|
|
}
|
|
} catch (e) {
|
|
SmartDialog.showToast("保存失败");
|
|
}
|
|
}
|
|
|
|
/// 保存图片-桌面平台
|
|
static void saveImageDetktop(String fileName, Uint8List list) async {
|
|
final FileSaveLocation? location =
|
|
await getSaveLocation(suggestedName: fileName);
|
|
if (location == null) {
|
|
return;
|
|
}
|
|
final XFile file = XFile.fromData(list, name: fileName);
|
|
await file.saveTo(location.path);
|
|
}
|
|
|
|
/// 分享
|
|
static void share(String url, {String content = ""}) {
|
|
showModalBottomSheet(
|
|
context: Get.context!,
|
|
shape: const RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(12),
|
|
topRight: Radius.circular(12),
|
|
),
|
|
),
|
|
constraints: const BoxConstraints(
|
|
maxWidth: 500,
|
|
),
|
|
useSafeArea: true,
|
|
backgroundColor: Get.theme.cardColor,
|
|
builder: (context) => Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
ListTile(
|
|
leading: const Icon(Icons.copy),
|
|
title: const Text("复制链接"),
|
|
onTap: () {
|
|
Get.back();
|
|
Utils.copyText(url);
|
|
},
|
|
),
|
|
Visibility(
|
|
visible: content.isNotEmpty,
|
|
child: ListTile(
|
|
leading: const Icon(Icons.copy),
|
|
title: const Text("复制标题与链接"),
|
|
onTap: () {
|
|
Get.back();
|
|
Utils.copyText("$content\n$url");
|
|
},
|
|
),
|
|
),
|
|
ListTile(
|
|
leading: const Icon(Icons.public),
|
|
title: const Text("浏览器打开"),
|
|
onTap: () {
|
|
Get.back();
|
|
launchUrlString(url, mode: LaunchMode.externalApplication);
|
|
},
|
|
),
|
|
ListTile(
|
|
leading: const Icon(Icons.share),
|
|
title: const Text("系统分享"),
|
|
onTap: () {
|
|
Get.back();
|
|
Share.share(content.isEmpty ? url : "$content\n$url");
|
|
},
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
/// 检查更新
|
|
static void checkUpdate({bool showMsg = false}) async {
|
|
try {
|
|
int currentVer = Utils.parseVersion(packageInfo.version);
|
|
CommonRequest request = CommonRequest();
|
|
var versionInfo = await request.checkUpdate();
|
|
if (versionInfo.versionNum > currentVer) {
|
|
Get.dialog(
|
|
AlertDialog(
|
|
title: Text(
|
|
"发现新版本 ${versionInfo.version}",
|
|
textAlign: TextAlign.center,
|
|
style: const TextStyle(fontSize: 18),
|
|
),
|
|
content: Text(
|
|
versionInfo.versionDesc,
|
|
style: const TextStyle(fontSize: 14, height: 1.4),
|
|
),
|
|
actionsPadding: AppStyle.edgeInsetsH12,
|
|
actions: [
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Expanded(
|
|
child: TextButton(
|
|
onPressed: () {
|
|
Get.back();
|
|
},
|
|
child: const Text("取消"),
|
|
),
|
|
),
|
|
AppStyle.hGap12,
|
|
Expanded(
|
|
child: ElevatedButton(
|
|
style: ElevatedButton.styleFrom(
|
|
elevation: 0,
|
|
),
|
|
onPressed: () {
|
|
launchUrlString(
|
|
versionInfo.downloadUrl,
|
|
mode: LaunchMode.externalApplication,
|
|
);
|
|
},
|
|
child: const Text("更新"),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
);
|
|
} else {
|
|
if (showMsg) {
|
|
SmartDialog.showToast("当前已经是最新版本了");
|
|
}
|
|
}
|
|
} catch (e) {
|
|
Log.logPrint(e);
|
|
if (showMsg) {
|
|
SmartDialog.showToast("检查更新失败");
|
|
}
|
|
}
|
|
}
|
|
|
|
/// 复制文本
|
|
static void copyText(String text) async {
|
|
try {
|
|
await Clipboard.setData(ClipboardData(text: text));
|
|
SmartDialog.showToast("已复制到剪切板");
|
|
} catch (e) {
|
|
SmartDialog.showToast(e.toString());
|
|
}
|
|
}
|
|
}
|