From eababaad74075c27a82fa3c7e1b4f3ca089d31fb Mon Sep 17 00:00:00 2001 From: guozhigq Date: Thu, 17 Aug 2023 09:43:01 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=85=B3=E4=BA=8E=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/Podfile.lock | 6 + lib/http/api.dart | 4 + lib/models/github/latest.dart | 45 ++++ lib/pages/about/index.dart | 246 ++++++++++++++++++ lib/pages/setting/view.dart | 5 + lib/router/app_pages.dart | 3 + lib/utils/utils.dart | 16 ++ macos/Flutter/GeneratedPluginRegistrant.swift | 2 + pubspec.lock | 38 ++- pubspec.yaml | 4 + 10 files changed, 366 insertions(+), 3 deletions(-) create mode 100644 lib/models/github/latest.dart create mode 100644 lib/pages/about/index.dart diff --git a/ios/Podfile.lock b/ios/Podfile.lock index aad4a9b0..68128de1 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -31,6 +31,8 @@ PODS: - sqflite (0.0.3): - Flutter - FMDB (>= 2.7.5) + - url_launcher_ios (0.0.1): + - Flutter - volume_controller (0.0.1): - Flutter - wakelock_plus (0.0.1): @@ -54,6 +56,7 @@ DEPENDENCIES: - screen_brightness_ios (from `.symlinks/plugins/screen_brightness_ios/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`) - sqflite (from `.symlinks/plugins/sqflite/ios`) + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - volume_controller (from `.symlinks/plugins/volume_controller/ios`) - wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`) - webview_cookie_manager (from `.symlinks/plugins/webview_cookie_manager/ios`) @@ -91,6 +94,8 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/share_plus/ios" sqflite: :path: ".symlinks/plugins/sqflite/ios" + url_launcher_ios: + :path: ".symlinks/plugins/url_launcher_ios/ios" volume_controller: :path: ".symlinks/plugins/volume_controller/ios" wakelock_plus: @@ -116,6 +121,7 @@ SPEC CHECKSUMS: screen_brightness_ios: 715ca807df953bf676d339f11464e438143ee625 share_plus: 599aa54e4ea31d4b4c0e9c911bcc26c55e791028 sqflite: 31f7eba61e3074736dff8807a9b41581e4f7f15a + url_launcher_ios: 08a3dfac5fb39e8759aeb0abbd5d9480f30fc8b4 volume_controller: 531ddf792994285c9b17f9d8a7e4dcdd29b3eae9 wakelock_plus: 8b09852c8876491e4b6d179e17dfe2a0b5f60d47 webview_cookie_manager: eaf920722b493bd0f7611b5484771ca53fed03f7 diff --git a/lib/http/api.dart b/lib/http/api.dart index 885680c3..5f171349 100644 --- a/lib/http/api.dart +++ b/lib/http/api.dart @@ -281,4 +281,8 @@ class Api { // 黑名单 static const String blackLst = '/x/relation/blacks'; + + // github 获取最新版 + static const String latestApp = + 'https://api.github.com/repos/guozhigq/pilipala/releases/latest'; } diff --git a/lib/models/github/latest.dart b/lib/models/github/latest.dart new file mode 100644 index 00000000..1b2d0706 --- /dev/null +++ b/lib/models/github/latest.dart @@ -0,0 +1,45 @@ +class LatestDataModel { + LatestDataModel({ + this.url, + this.tagName, + this.createdAt, + this.assets, + }); + + String? url; + String? tagName; + String? createdAt; + List? assets; + + LatestDataModel.fromJson(Map json) { + url = json['url']; + tagName = json['tag_name']; + createdAt = json['created_at']; + assets = + json['assets'].map((e) => AssetItem.fromJson(e)).toList(); + } +} + +class AssetItem { + AssetItem({ + this.url, + this.name, + this.size, + this.downloadCount, + this.downloadUrl, + }); + + String? url; + String? name; + int? size; + int? downloadCount; + String? downloadUrl; + + AssetItem.fromJson(Map json) { + url = json['url']; + name = json['name']; + size = json['size']; + downloadCount = json['download_count']; + downloadUrl = json['browser_download_url']; + } +} diff --git a/lib/pages/about/index.dart b/lib/pages/about/index.dart new file mode 100644 index 00000000..66c66abb --- /dev/null +++ b/lib/pages/about/index.dart @@ -0,0 +1,246 @@ +import 'dart:io'; + +import 'package:device_info_plus/device_info_plus.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; +import 'package:get/get.dart'; +import 'package:package_info_plus/package_info_plus.dart'; +import 'package:path_provider/path_provider.dart'; +import 'package:pilipala/http/index.dart'; +import 'package:pilipala/models/github/latest.dart'; +import 'package:pilipala/utils/utils.dart'; +import 'package:url_launcher/url_launcher.dart'; + +class AboutPage extends StatefulWidget { + const AboutPage({super.key}); + + @override + State createState() => _AboutPageState(); +} + +class _AboutPageState extends State { + final AboutController _aboutController = Get.put(AboutController()); + + @override + Widget build(BuildContext context) { + Color outline = Theme.of(context).colorScheme.outline; + TextStyle subTitleStyle = + TextStyle(fontSize: 13, color: Theme.of(context).colorScheme.outline); + return Scaffold( + appBar: AppBar( + title: Text('关于', style: Theme.of(context).textTheme.titleMedium), + ), + body: SingleChildScrollView( + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + Divider( + thickness: 8, + height: 10, + color: Theme.of(context).colorScheme.onInverseSurface, + ), + Image.asset( + 'assets/images/logo/logo_android_2.png', + width: 150, + ), + Text( + 'PiliPala', + style: Theme.of(context).textTheme.titleMedium, + ), + const SizedBox(height: 20), + Obx( + () => ListTile( + title: const Text("当前版本"), + trailing: Text(_aboutController.currentVersion.value, + style: subTitleStyle), + ), + ), + Obx( + () => ListTile( + onTap: () => _aboutController.onUpdate(), + title: const Text('最新版本'), + trailing: Text( + _aboutController.isLoading.value + ? '正在获取' + : _aboutController.isUpdate.value + ? '有新版本 ❤️${_aboutController.remoteVersion.value}' + : '当前已是最新版', + style: subTitleStyle, + ), + ), + ), + // ListTile( + // onTap: () {}, + // title: const Text('更新日志'), + // trailing: const Icon( + // Icons.arrow_forward_ios, + // size: 16, + // ), + // ), + Divider( + thickness: 8, + height: 30, + color: Theme.of(context).colorScheme.onInverseSurface, + ), + ListTile( + onTap: () {}, + title: const Text('作者'), + trailing: Text('guozhigq', style: subTitleStyle), + ), + ListTile( + onTap: () {}, + title: const Text('酷安'), + trailing: Text('影若风', style: subTitleStyle), + ), + ListTile( + onTap: () => _aboutController.githubUrl(), + title: const Text('Github'), + trailing: Text( + 'github.com/guozhigq/pilipala', + style: subTitleStyle, + ), + ), + ListTile( + onTap: () => _aboutController.feedback(), + title: const Text('问题反馈'), + trailing: Icon( + Icons.arrow_forward_ios, + size: 16, + color: outline, + ), + ), + ListTile( + onTap: () => _aboutController.qqChanel(), + title: const Text('QQ频道'), + trailing: Icon( + Icons.arrow_forward_ios, + size: 16, + color: outline, + ), + ), + ListTile( + onTap: () => _aboutController.tgChanel(), + title: const Text('TG频道'), + trailing: Icon(Icons.arrow_forward_ios, size: 16, color: outline), + ), + Divider( + thickness: 8, + height: 30, + color: Theme.of(context).colorScheme.onInverseSurface, + ), + ], + ), + ), + ); + } +} + +class AboutController extends GetxController { + RxString currentVersion = ''.obs; + RxString remoteVersion = ''.obs; + late LatestDataModel remoteAppInfo; + RxBool isUpdate = true.obs; + RxBool isLoading = true.obs; + + @override + void onInit() { + super.onInit(); + init(); + // 获取当前版本 + getCurrentApp(); + // 获取最新的版本 + getRemoteApp(); + } + + // 获取设备信息 + Future init() async { + DeviceInfoPlugin deviceInfo = DeviceInfoPlugin(); + if (Platform.isAndroid) { + AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo; + print(androidInfo.supportedAbis); + } else if (Platform.isIOS) { + IosDeviceInfo iosInfo = await deviceInfo.iosInfo; + print(iosInfo); + } + } + + // 获取啊当前版本 + Future getCurrentApp() async { + var result = await PackageInfo.fromPlatform(); + currentVersion.value = result.version; + } + + // 获取远程版本 + Future getRemoteApp() async { + var result = await Request().get(Api.latestApp); + LatestDataModel data = LatestDataModel.fromJson(result.data); + remoteAppInfo = data; + remoteVersion.value = data.tagName!; + isUpdate.value = + Utils.needUpdate(currentVersion.value, remoteVersion.value); + isLoading.value = false; + } + + // 跳转下载/本地更新 + Future onUpdate() async { + // final dir = await getApplicationSupportDirectory(); + // final path = '${dir.path}/pilipala.apk'; + // var result = await Request() + // .downloadFile(remoteAppInfo.assets!.first.downloadUrl, path); + // print(result); + launchUrl( + Uri.parse('https://github.com/guozhigq/pilipala/releases'), + mode: LaunchMode.externalApplication, + ); + } + + // 跳转github + githubUrl() { + launchUrl( + Uri.parse('https://github.com/guozhigq/pilipala'), + mode: LaunchMode.externalApplication, + ); + } + + // 问题反馈 + feedback() { + launchUrl( + Uri.parse('https://github.com/guozhigq/pilipala/issues'), + // 系统自带浏览器打开 + mode: LaunchMode.externalApplication, + ); + } + + // qq频道 + qqChanel() { + Clipboard.setData( + const ClipboardData(text: 'https://pd.qq.com/s/css9rdwga'), + ); + SmartDialog.showToast( + '已复制,即将在浏览器打开', + displayTime: const Duration(milliseconds: 500), + ).then( + (value) => launchUrl( + Uri.parse('https://pd.qq.com/s/css9rdwga'), + mode: LaunchMode.externalApplication, + ), + ); + } + + // tg频道 + tgChanel() { + Clipboard.setData( + const ClipboardData(text: 'https://t.me/+lm_oOVmF0RJiODk1'), + ); + SmartDialog.showToast( + '已复制,即将在浏览器打开', + displayTime: const Duration(milliseconds: 500), + ).then( + (value) => launchUrl( + Uri.parse('https://t.me/+lm_oOVmF0RJiODk1'), + mode: LaunchMode.externalApplication, + ), + ); + } +} diff --git a/lib/pages/setting/view.dart b/lib/pages/setting/view.dart index 8b443529..0bddb809 100644 --- a/lib/pages/setting/view.dart +++ b/lib/pages/setting/view.dart @@ -49,6 +49,11 @@ class SettingPage extends StatelessWidget { ), ), ), + ListTile( + onTap: () => Get.toNamed('/about'), + dense: false, + title: const Text('关于'), + ), ], ), ); diff --git a/lib/router/app_pages.dart b/lib/router/app_pages.dart index 62e79b35..c1482f1a 100644 --- a/lib/router/app_pages.dart +++ b/lib/router/app_pages.dart @@ -1,4 +1,5 @@ import 'package:get/get.dart'; +import 'package:pilipala/pages/about/index.dart'; import 'package:pilipala/pages/blacklist/index.dart'; import 'package:pilipala/pages/dynamics/deatil/index.dart'; import 'package:pilipala/pages/dynamics/index.dart'; @@ -82,5 +83,7 @@ class Routes { // GetPage(name: '/blackListPage', page: () => const BlackListPage()), + // 关于 + GetPage(name: '/about', page: () => const AboutPage()), ]; } diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 7dfe972e..4a539888 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -178,4 +178,20 @@ class Utils { } catch (_) {} return closestNumber; } + + // 版本对比 + static bool needUpdate(localVersion, remoteVersion) { + List localVersionList = localVersion.split('.'); + List remoteVersionList = remoteVersion.split('v')[1].split('.'); + for (int i = 0; i < localVersionList.length; i++) { + int localVersion = int.parse(localVersionList[i]); + int remoteVersion = int.parse(remoteVersionList[i]); + if (remoteVersion > localVersion) { + return true; + } else if (remoteVersion < localVersion) { + return false; + } + } + return false; + } } diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index bc042145..22b40faf 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -15,6 +15,7 @@ import path_provider_foundation import screen_brightness_macos import share_plus import sqflite +import url_launcher_macos import wakelock_plus func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { @@ -28,5 +29,6 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { ScreenBrightnessMacosPlugin.register(with: registry.registrar(forPlugin: "ScreenBrightnessMacosPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) + UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index b1f149bd..68188d05 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -774,13 +774,13 @@ packages: source: hosted version: "2.1.0" package_info_plus: - dependency: transitive + dependency: "direct main" description: name: package_info_plus - sha256: ceb027f6bc6a60674a233b4a90a7658af1aebdea833da0b5b53c1e9821a78c7b + sha256: "6ff267fcd9d48cb61c8df74a82680e8b82e940231bb5f68356672fde0397334a" url: "https://pub.dev" source: hosted - version: "4.0.2" + version: "4.1.0" package_info_plus_platform_interface: dependency: transitive description: @@ -1186,6 +1186,30 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.2" + url_launcher: + dependency: "direct main" + description: + name: url_launcher + sha256: "781bd58a1eb16069412365c98597726cd8810ae27435f04b3b4d3a470bacd61e" + url: "https://pub.dev" + source: hosted + version: "6.1.12" + url_launcher_android: + dependency: transitive + description: + name: url_launcher_android + sha256: "3dd2388cc0c42912eee04434531a26a82512b9cb1827e0214430c9bcbddfe025" + url: "https://pub.dev" + source: hosted + version: "6.0.38" + url_launcher_ios: + dependency: transitive + description: + name: url_launcher_ios + sha256: "9af7ea73259886b92199f9e42c116072f05ff9bea2dcb339ab935dfc957392c2" + url: "https://pub.dev" + source: hosted + version: "6.1.4" url_launcher_linux: dependency: transitive description: @@ -1194,6 +1218,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.5" + url_launcher_macos: + dependency: transitive + description: + name: url_launcher_macos + sha256: "1c4fdc0bfea61a70792ce97157e5cc17260f61abbe4f39354513f39ec6fd73b1" + url: "https://pub.dev" + source: hosted + version: "3.0.6" url_launcher_platform_interface: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index b15728cf..8ff79d42 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -110,6 +110,10 @@ dependencies: animations: ^2.0.7 # auto_orientation: ^2.3.1 + # 获取appx信息 + package_info_plus: ^4.1.0 + url_launcher: ^6.1.12 + dev_dependencies: flutter_test: sdk: flutter