pikapika/lib/basic/config/Version.dart

161 lines
4.0 KiB
Dart

import 'dart:async' show Future;
import 'dart:convert';
import 'package:event/event.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:pikapika/basic/Common.dart';
import '../Method.dart';
const _versionUrl =
"https://api.github.com/repos/niuhuan/pikapika/releases/latest";
const _versionAssets = 'lib/assets/version.txt';
late String _version;
String? _latestVersion;
String? _latestVersionInfo;
const _propertyName = "checkVersionPeriod";
late int _period = -1;
Future initVersion() async {
// 当前版本
try {
_version = (await rootBundle.loadString(_versionAssets)).trim();
} catch (e) {
_version = "dirty";
}
// 检查周期
_period = int.parse(await method.loadProperty(_propertyName, "0"));
if (_period > 0) {
if (DateTime.now().millisecondsSinceEpoch > _period) {
await method.saveProperty(_propertyName, "0");
_period = 0;
}
}
}
var versionEvent = Event<EventArgs>();
String currentVersion() {
return _version;
}
String? latestVersion() {
return _latestVersion;
}
String? latestVersionInfo() {
return _latestVersionInfo;
}
Future autoCheckNewVersion() {
if (_period != 0) {
// -1 不检查, >0 未到检查时间
return Future.value();
}
return _versionCheck();
}
Future manualCheckNewVersion(BuildContext context) async {
try {
defaultToast(context, "检查更新中");
await _versionCheck();
defaultToast(context, "检查更新成功");
} catch (e) {
defaultToast(context, "检查更新失败 : $e");
}
}
bool dirtyVersion() {
return "dirty" == _version;
}
// maybe exception
Future _versionCheck() async {
if (!dirtyVersion()) {
// 检查更新只能使用defaultHttpClient, 而不能使用pika的client, 否则会 "tls handshake failure"
var json = jsonDecode(await method.defaultHttpClientGet(_versionUrl));
if (json["name"] != null) {
String latestVersion = (json["name"]);
if (latestVersion != _version) {
_latestVersion = latestVersion;
_latestVersionInfo = json["body"] ?? "";
}
}
} // else dirtyVersion
versionEvent.broadcast();
}
String _periodText() {
if (_period < 0) {
return "自动检查更新已关闭";
}
if (_period == 0) {
return "自动检查更新已开启";
}
return "下次检查时间 : " +
formatDateTimeToDateTime(
DateTime.fromMillisecondsSinceEpoch(_period),
);
}
Future _choosePeriod(BuildContext context) async {
var result = await chooseListDialog(
context,
"自动检查更新",
["开启", "一周后", "一个月后", "一年后", "关闭"],
tips: "重启后红点会消失",
);
switch (result) {
case "开启":
await method.saveProperty(_propertyName, "0");
_period = 0;
break;
case "一周后":
var time = DateTime.now().millisecondsSinceEpoch + (1000 * 3600 * 24 * 7);
await method.saveProperty(_propertyName, "$time");
_period = time;
break;
case "一个月后":
var time =
DateTime.now().millisecondsSinceEpoch + (1000 * 3600 * 24 * 30);
await method.saveProperty(_propertyName, "$time");
_period = time;
break;
case "一年后":
var time =
DateTime.now().millisecondsSinceEpoch + (1000 * 3600 * 24 * 365);
await method.saveProperty(_propertyName, "$time");
_period = time;
break;
case "关闭":
await method.saveProperty(_propertyName, "-1");
_period = -1;
break;
}
}
Widget autoUpdateCheckSetting() {
return StatefulBuilder(
builder: (BuildContext context, void Function(void Function()) setState) {
return ListTile(
title: const Text("自动检查更新"),
subtitle: Text(_periodText()),
onTap: () async {
await _choosePeriod(context);
setState(() {});
},
);
},
);
}
String formatDateTimeToDateTime(DateTime c) {
try {
return "${add0(c.year, 4)}-${add0(c.month, 2)}-${add0(c.day, 2)} ${add0(c.hour, 2)}:${add0(c.minute, 2)}";
} catch (e) {
return "-";
}
}