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; Future initVersion() async { // 当前版本 try { _version = (await rootBundle.loadString(_versionAssets)).trim(); } catch (e) { _version = "dirty"; } } var versionEvent = Event(); String currentVersion() { return _version; } String? latestVersion() { return _latestVersion; } String? latestVersionInfo() { return _latestVersionInfo; } Future autoCheckNewVersion() { 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(); } var _display = true; void versionPop(BuildContext context) { if (latestVersion() != null && _display) { _display = false; TopConfirm.topConfirm( context, "发现新版本", "发现新版本 ${latestVersion()} , 请到关于页面更新", ); } } class TopConfirm { static topConfirm(BuildContext context, String title, String message, {Function()? afterIKnown}) { late OverlayEntry overlayEntry; overlayEntry = OverlayEntry(builder: (BuildContext context) { return LayoutBuilder( builder: ( BuildContext context, BoxConstraints constraints, ) { var mq = MediaQuery.of(context).size.width - 30; return Material( color: Colors.transparent, child: Container( width: constraints.maxWidth, height: constraints.maxHeight, decoration: BoxDecoration( color: Colors.black.withOpacity(.35), ), child: Column( children: [ Expanded(child: Container()), Container( width: mq, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10), ), child: Column( children: [ Container(height: 30), Text( title, style: const TextStyle( color: Colors.black, fontSize: 28, ), ), Container(height: 15), Text( message, style: const TextStyle( color: Colors.black, fontSize: 16, ), ), Container(height: 25), MaterialButton( elevation: 0, color: Colors.black.withOpacity(.1), onPressed: () { overlayEntry.remove(); }, child: const Text("朕知道了"), ), Container(height: 30), ], ), ), Expanded(child: Container()), ], ), ), ); }, ); }); OverlayState? overlay = Overlay.of(context); if (overlay != null) { overlay.insert(overlayEntry); } } }