optimize checkUpdate

This commit is contained in:
chen08209
2024-05-31 09:59:18 +08:00
parent 96738090cf
commit ecce17ad75
12 changed files with 182 additions and 49 deletions

View File

@@ -162,11 +162,22 @@ class Other {
}
}
double getViewWidth(){
double getViewWidth() {
final view = WidgetsBinding.instance.platformDispatcher.views.first;
final size = view.physicalSize / view.devicePixelRatio;
return size.width;
}
List<String> parseReleaseBody(String? body) {
if(body == null) return [];
const pattern = r'- (.+?)\. \[.+?\]';
final regex = RegExp(pattern);
return regex
.allMatches(body)
.map((match) => match.group(1) ?? '')
.where((item) => item.isNotEmpty)
.toList();
}
}
final other = Other();

View File

@@ -17,20 +17,20 @@ class Request {
}
}
static Future<Result<String>> checkForUpdate() async {
static Future<Result<Map<String,dynamic>>> checkForUpdate() async {
final response = await get(
Uri.parse(
"https://api.github.com/repos/$repository/releases/latest",
),
);
if (response.statusCode != 200) return Result.error();
final body = json.decode(response.body);
final body = json.decode(response.body) as Map<String,dynamic>;
final remoteVersion = body['tag_name'];
final packageInfo = await appPackage.packageInfoCompleter.future;
final version = packageInfo.version;
final hasUpdate =
other.compareVersions(remoteVersion.replaceAll('v', ''), version) > 0;
if (!hasUpdate) return Result.error();
return Result.success(body['body']);
return Result.success(body);
}
}

View File

@@ -3,6 +3,7 @@ import 'dart:async';
import 'package:fl_clash/state.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:url_launcher/url_launcher.dart';
import 'clash/core.dart';
import 'enum/enum.dart';
@@ -209,14 +210,52 @@ class AppController {
}
autoCheckUpdate() async {
if (!config.autoCheckUpdate) return;
final res = await Request.checkForUpdate();
if(res.type != ResultType.success) return;
globalState.showMessage(
title: appLocalizations.checkUpdate,
message: TextSpan(
text: res.data,
),
);
checkUpdateResultHandle(result: res);
}
checkUpdateResultHandle({
Result<Map<String, dynamic>>? result,
bool handleError = false
}) async {
if (result == null) return;
if (result.type == ResultType.success) {
final tagName = result.data?['tag_name'];
final body = result.data?['body'];
final submits = other.parseReleaseBody(body);
globalState.showMessage(
title: appLocalizations.discoverNewVersion,
message: TextSpan(
text: "$tagName \n",
style: context.textTheme.headlineSmall,
children: [
TextSpan(
text: "\n",
style: context.textTheme.bodyMedium,
),
for (final submit in submits)
TextSpan(
text: "- $submit \n",
style: context.textTheme.bodyMedium,
),
],
),
onTab: () {
launchUrl(
Uri.parse("https://github.com/$repository/releases/latest"),
);
},
confirmText: appLocalizations.goDownload,
);
} else if(handleError){
globalState.showMessage(
title: appLocalizations.checkUpdate,
message: TextSpan(
text: appLocalizations.checkUpdateError,
),
);
}
}
afterInit() async {
@@ -235,7 +274,7 @@ class AppController {
}
healthcheck() {
if(globalState.healthcheckLock) return;
if (globalState.healthcheckLock) return;
for (final delay in appState.delayMap.entries) {
setDelay(
Delay(
@@ -268,7 +307,6 @@ class AppController {
}
}
toProfiles() {
final index = appState.currentNavigationItems.indexWhere(
(element) => element.label == "profiles",
@@ -365,7 +403,7 @@ class AppController {
addProfileFormQrCode() async {
final result = await picker.pickerConfigQRCode();
if (result.type == ResultType.error) {
if(result.message != null){
if (result.message != null) {
globalState.showMessage(
title: appLocalizations.tip,
message: TextSpan(
@@ -394,10 +432,10 @@ class AppController {
}
}
updateViewWidth(){
updateViewWidth() {
appState.viewWidth = context.width;
if(appState.viewWidth == 0){
Future.delayed(moreDuration,(){
if (appState.viewWidth == 0) {
Future.delayed(moreDuration, () {
updateViewWidth();
});
}

View File

@@ -12,26 +12,15 @@ class AboutFragment extends StatelessWidget {
_checkUpdate(BuildContext context) async {
final commonScaffoldState = context.commonScaffoldState;
if (commonScaffoldState?.mounted != true) return;
final res = await commonScaffoldState?.loadingRun<Result<String>>(
final res =
await commonScaffoldState?.loadingRun<Result<Map<String, dynamic>>>(
Request.checkForUpdate,
title: appLocalizations.checkUpdate,
);
if (res == null) return;
if (res.type == ResultType.success) {
globalState.showMessage(
title: appLocalizations.checkUpdate,
message: TextSpan(
text: res.data,
),
);
} else {
globalState.showMessage(
title: appLocalizations.checkUpdate,
message: TextSpan(
text: appLocalizations.checkUpdateError,
),
);
}
globalState.appController.checkUpdateResultHandle(
result: res,
handleError: true,
);
}
@override
@@ -92,7 +81,7 @@ class AboutFragment extends StatelessWidget {
),
ListTile(
title: Text(appLocalizations.checkUpdate),
onTap: (){
onTap: () {
_checkUpdate(context);
},
),

View File

@@ -149,5 +149,7 @@
"passwordTip": "Password cannot be empty",
"accountTip": "Account cannot be empty",
"checkUpdate": "Check for updates",
"checkUpdateError": "The current application is already the latest version"
"discoverNewVersion": "Discover the new version",
"checkUpdateError": "The current application is already the latest version",
"goDownload": "Go to download"
}

View File

@@ -149,5 +149,7 @@
"passwordTip": "密码不能为空",
"accountTip": "账号不能为空",
"checkUpdate": "检查更新",
"checkUpdateError": "当前应用已经是最新版了"
"discoverNewVersion": "发现新版本",
"checkUpdateError": "当前应用已经是最新版了",
"goDownload": "前往下载"
}

View File

@@ -99,6 +99,8 @@ class MessageLookup extends MessageLookupByLibrary {
"desc": MessageLookupByLibrary.simpleMessage(
"A multi-platform proxy client based on ClashMeta, simple and easy to use, open-source and ad-free."),
"direct": MessageLookupByLibrary.simpleMessage("Direct"),
"discoverNewVersion":
MessageLookupByLibrary.simpleMessage("Discover the new version"),
"discovery":
MessageLookupByLibrary.simpleMessage("Discovery a new version"),
"doYouWantToPass":
@@ -113,6 +115,7 @@ class MessageLookup extends MessageLookupByLibrary {
"filterSystemApp":
MessageLookupByLibrary.simpleMessage("Filter system app"),
"global": MessageLookupByLibrary.simpleMessage("Global"),
"goDownload": MessageLookupByLibrary.simpleMessage("Go to download"),
"hours": MessageLookupByLibrary.simpleMessage("Hours"),
"importFromURL":
MessageLookupByLibrary.simpleMessage("Import from URL"),

View File

@@ -83,6 +83,7 @@ class MessageLookup extends MessageLookupByLibrary {
"desc": MessageLookupByLibrary.simpleMessage(
"基于ClashMeta的多平台代理客户端简单易用开源无广告。"),
"direct": MessageLookupByLibrary.simpleMessage("直连"),
"discoverNewVersion": MessageLookupByLibrary.simpleMessage("发现新版本"),
"discovery": MessageLookupByLibrary.simpleMessage("发现新版本"),
"doYouWantToPass": MessageLookupByLibrary.simpleMessage("是否要通过"),
"download": MessageLookupByLibrary.simpleMessage("下载"),
@@ -93,6 +94,7 @@ class MessageLookup extends MessageLookupByLibrary {
"fileDesc": MessageLookupByLibrary.simpleMessage("直接上传配置文件"),
"filterSystemApp": MessageLookupByLibrary.simpleMessage("过滤系统应用"),
"global": MessageLookupByLibrary.simpleMessage("全局"),
"goDownload": MessageLookupByLibrary.simpleMessage("前往下载"),
"hours": MessageLookupByLibrary.simpleMessage("小时"),
"importFromURL": MessageLookupByLibrary.simpleMessage("从URL导入"),
"just": MessageLookupByLibrary.simpleMessage("刚刚"),

View File

@@ -1550,6 +1550,16 @@ class AppLocalizations {
);
}
/// `Discover the new version`
String get discoverNewVersion {
return Intl.message(
'Discover the new version',
name: 'discoverNewVersion',
desc: '',
args: [],
);
}
/// `The current application is already the latest version`
String get checkUpdateError {
return Intl.message(
@@ -1559,6 +1569,16 @@ class AppLocalizations {
args: [],
);
}
/// `Go to download`
String get goDownload {
return Intl.message(
'Go to download',
name: 'goDownload',
desc: '',
args: [],
);
}
}
class AppLocalizationDelegate extends LocalizationsDelegate<AppLocalizations> {

View File

@@ -158,18 +158,25 @@ class GlobalState {
required String title,
required InlineSpan message,
Function()? onTab,
String? confirmText,
}) {
showCommonDialog(
child: Builder(
builder: (context) {
return AlertDialog(
title: Text(title),
content: SizedBox(
content: Container(
width: 300,
child: RichText(
text: TextSpan(
style: Theme.of(context).textTheme.labelLarge,
children: [message],
constraints: const BoxConstraints(
maxHeight: 200
),
child: SingleChildScrollView(
child: RichText(
overflow: TextOverflow.visible,
text: TextSpan(
style: Theme.of(context).textTheme.labelLarge,
children: [message],
),
),
),
),
@@ -179,7 +186,7 @@ class GlobalState {
() {
Navigator.of(context).pop();
},
child: Text(appLocalizations.confirm),
child: Text(confirmText ?? appLocalizations.confirm),
)
],
);
@@ -200,6 +207,7 @@ class GlobalState {
filter: filter,
);
}
updateTraffic({
AppState? appState,
required Config config,

View File

@@ -1,7 +1,7 @@
name: fl_clash
description: A multi-platform proxy client based on ClashMeta, simple and easy to use, open-source and ad-free.
publish_to: 'none'
version: 0.8.5
version: 0.8.6
environment:
sdk: '>=3.1.0 <4.0.0'

View File

@@ -4,10 +4,68 @@ import 'package:http/io_client.dart';
import 'dart:io';
void main() async {
HttpClient httpClient = HttpClient();
httpClient.findProxy = HttpClient.findProxyFromEnvironment;
String input = """
<details markdown=1><summary>All changes from v0.8.5 to the latest commit:</summary>
IOClient ioClient = IOClient(httpClient);
var response = await ioClient.get(Uri.parse('https://mirror.ghproxy.com/https://raw.githubusercontent.com/Ruk1ng001/freeSub/main/clash_top30.yaml'));
print(response.body);
(unreleased)
------------
- Fix submit error. [chen08209]
- Add WebDAV. [chen08209]
add Auto check updates
Optimize more details
- Optimize delayTest. [chen08209]
- Upgrade flutter version. [chen08209]
- Update kernel Add import profile via QR code image. [chen08209]
- Add compatibility mode and adapt clash scheme. [chen08209]
- Update Version. [chen08209]
- Reconstruction application proxy logic. [chen08209]
- Fix Tab destroy error. [chen08209]
- Optimize repeat healthcheck. [chen08209]
- Optimize Direct mode ui. [chen08209]
- Optimize Healthcheck. [chen08209]
- Remove proxies position animation, improve performance Add Telegram
Link. [chen08209]
- Update healthcheck policy. [chen08209]
- New Check URLTest. [chen08209]
- Fix the problem of invalid auto-selection. [chen08209]
- New Async UpdateConfig. [chen08209]
- Add changeProfileDebounce. [chen08209]
- Update Workflow. [chen08209]
- Fix ChangeProfile block. [chen08209]
- Fix Release Message Error. [chen08209]
- Update Selector 2. [chen08209]
- Update Version. [chen08209]
- Fix Proxies Select Error. [chen08209]
- Fix the problem that the proxy group is empty in global mode.
[chen08209]
- Fix the problem that the proxy group is empty in global mode.
[chen08209]
- Add ProxyProvider2. [chen08209]
- Add ProxyProvider. [chen08209]
- Update Version. [chen08209]
- Update ProxyGroup Sort. [chen08209]
- Fix Android quickStart VpnService some problems. [chen08209]
- Update version. [chen08209]
- Set Android notification low importance. [chen08209]
- Fix the issue that VpnService can't be closed correctly in special
cases. [chen08209]
- Fix the problem that TileService is not destroyed correctly in some
cases. [chen08209]
Adjust tab animation defaults
- Add Telegram in README_zh_CN.md. [chen08209]
- Add Telegram. [chen08209]
""";
const pattern = r'- (.+?)\. \[.+?\]';
final regex = RegExp(pattern);
for (final match in regex.allMatches(input)) {
final change = match.group(1);
print(change);
}
}