feat: 关于页面
This commit is contained in:
@ -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';
|
||||
}
|
||||
|
45
lib/models/github/latest.dart
Normal file
45
lib/models/github/latest.dart
Normal file
@ -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<String, dynamic> json) {
|
||||
url = json['url'];
|
||||
tagName = json['tag_name'];
|
||||
createdAt = json['created_at'];
|
||||
assets =
|
||||
json['assets'].map<AssetItem>((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<String, dynamic> json) {
|
||||
url = json['url'];
|
||||
name = json['name'];
|
||||
size = json['size'];
|
||||
downloadCount = json['download_count'];
|
||||
downloadUrl = json['browser_download_url'];
|
||||
}
|
||||
}
|
246
lib/pages/about/index.dart
Normal file
246
lib/pages/about/index.dart
Normal file
@ -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<AboutPage> createState() => _AboutPageState();
|
||||
}
|
||||
|
||||
class _AboutPageState extends State<AboutPage> {
|
||||
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,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
@ -49,6 +49,11 @@ class SettingPage extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
ListTile(
|
||||
onTap: () => Get.toNamed('/about'),
|
||||
dense: false,
|
||||
title: const Text('关于'),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
@ -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()),
|
||||
];
|
||||
}
|
||||
|
@ -178,4 +178,20 @@ class Utils {
|
||||
} catch (_) {}
|
||||
return closestNumber;
|
||||
}
|
||||
|
||||
// 版本对比
|
||||
static bool needUpdate(localVersion, remoteVersion) {
|
||||
List<String> localVersionList = localVersion.split('.');
|
||||
List<String> 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;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user