From 4d7f73ffc46ad71cf013dcad63b76960e2f7b2fd Mon Sep 17 00:00:00 2001 From: xkeyC <3334969096@qq.com> Date: Tue, 28 Nov 2023 23:08:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E4=BF=A1=E6=81=AF=E6=B5=81?= =?UTF-8?q?=20=EF=BC=88=E6=8E=A5=E5=85=A5=20Anicat=20G=E4=BD=AC=20?= =?UTF-8?q?=E6=96=B0=E9=97=BB=E7=BB=84+=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/api/rss.dart | 31 +++++ lib/common/conf.dart | 12 +- lib/ui/home/home_ui.dart | 238 +++++++++++++++++++-------------- lib/ui/home/home_ui_model.dart | 31 +++++ pubspec.yaml | 7 +- 5 files changed, 214 insertions(+), 105 deletions(-) create mode 100644 lib/api/rss.dart diff --git a/lib/api/rss.dart b/lib/api/rss.dart new file mode 100644 index 0000000..a84f3ed --- /dev/null +++ b/lib/api/rss.dart @@ -0,0 +1,31 @@ +import 'dart:io'; + +import 'package:dart_rss/dart_rss.dart'; +import 'package:dio/dio.dart'; +import 'package:starcitizen_doctor/common/conf.dart'; + +class RSSApi { + static final _dio = Dio(BaseOptions( + connectTimeout: const Duration(seconds: 10), + responseType: ResponseType.plain)); + + static Future> getRssVideo() async { + final r = await _dio.get(AppConf.rssVideoUrl); + final f = RssFeed.parse(r.data); + return f.items.sublist(0, 8); + } + + static Future> getRssText() async { + final r1 = await _dio.get(AppConf.rssTextUrl1); + final r1f = RssFeed.parse(r1.data); + final r2 = await _dio.get(AppConf.rssTextUrl2); + final r2f = RssFeed.parse(r2.data); + final items = r1f.items..addAll(r2f.items); + items.sort((a, b) { + final aDate = HttpDate.parse(a.pubDate ?? "").millisecondsSinceEpoch; + final bDate = HttpDate.parse(b.pubDate ?? "").millisecondsSinceEpoch; + return bDate - aDate; + }); + return items; + } +} diff --git a/lib/common/conf.dart b/lib/common/conf.dart index 94f6322..bd3d290 100644 --- a/lib/common/conf.dart +++ b/lib/common/conf.dart @@ -34,6 +34,14 @@ class AppConf { static const String xkeycApiUrl = "https://sctoolbox.xkeyc.com"; + static const rssVideoUrl = + "https://rss.42kit.com/bilibili/user/channel/27976358/290653"; + + static const rssTextUrl1 = + "https://rss.42kit.com/bilibili/user/article/40102960"; + static const rssTextUrl2 = + "https://rss.42kit.com/baidu/tieba/user/%E7%81%AC%E7%81%ACG%E7%81%AC%E7%81%AC&"; + static late final String applicationSupportDir; static AppVersionData? networkVersionData; @@ -90,8 +98,8 @@ class AppConf { /// init windows await windowManager.ensureInitialized(); windowManager.waitUntilReadyToShow().then((_) async { - await windowManager.setSize(const Size(1280, 820)); - await windowManager.setMinimumSize(const Size(1280, 820)); + await windowManager.setSize(const Size(1300, 830)); + await windowManager.setMinimumSize(const Size(1300, 830)); await windowManager.center(animate: true); await windowManager.setSkipTaskbar(false); await windowManager.setTitleBarStyle( diff --git a/lib/ui/home/home_ui.dart b/lib/ui/home/home_ui.dart index 6842c4f..f61e495 100644 --- a/lib/ui/home/home_ui.dart +++ b/lib/ui/home/home_ui.dart @@ -1,11 +1,11 @@ import 'package:card_swiper/card_swiper.dart'; -import 'package:extended_image/extended_image.dart'; import 'package:flutter_staggered_grid_view/flutter_staggered_grid_view.dart'; import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_tilt/flutter_tilt.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:starcitizen_doctor/api/analytics.dart'; import 'package:starcitizen_doctor/base/ui.dart'; +import 'package:starcitizen_doctor/widgets/cache_image.dart'; import 'package:starcitizen_doctor/widgets/countdown_time_text.dart'; import 'package:url_launcher/url_launcher_string.dart'; @@ -18,6 +18,7 @@ class HomeUI extends BaseUI { children: [ Center( child: SingleChildScrollView( + padding: EdgeInsets.zero, child: Column( mainAxisSize: MainAxisSize.min, children: [ @@ -36,7 +37,7 @@ class HomeUI extends BaseUI { ? null : () => model.closePlacard(), ), - const SizedBox(height: 12), + const SizedBox(height: 6), ], if (!model.isChecking && model.checkResult != null && @@ -71,7 +72,7 @@ class HomeUI extends BaseUI { } List makeIndex(BuildContext context, HomeUIModel model) { - final width = MediaQuery.of(context).size.width * .21; + const double width = 280; return [ Stack( children: [ @@ -80,10 +81,17 @@ class HomeUI extends BaseUI { child: SizedBox( width: MediaQuery.of(context).size.width, child: Center( - child: Image.asset( - "assets/sc_logo.png", - height: 256, - fit: BoxFit.fitHeight, + child: Column( + children: [ + Padding( + padding: const EdgeInsets.only(bottom: 30), + child: Image.asset( + "assets/sc_logo.png", + fit: BoxFit.fitHeight, + height: 260, + ), + ), + ], ), ), ), @@ -222,27 +230,128 @@ class HomeUI extends BaseUI { ), ), Positioned( - left: 24, + left: 24, + bottom: 0, + child: SizedBox( + height: 420, + child: ScrollConfiguration( + behavior: + ScrollConfiguration.of(context).copyWith(scrollbars: false), + child: SingleChildScrollView( + child: Column( + children: [ + SizedBox( + height: 200, + width: 316, + child: Tilt( + shadowConfig: const ShadowConfig(maxIntensity: .3), + borderRadius: const BorderRadius.only( + topLeft: Radius.circular(12), + topRight: Radius.circular(12), + ), + child: model.rssVideoItems == null + ? Container( + decoration: BoxDecoration( + color: Colors.white.withOpacity(.1)), + child: makeLoading(context), + ) + : Swiper( + itemCount: model.rssVideoItems?.length ?? 0, + itemBuilder: (context, index) { + final item = model.rssVideoItems![index]; + return GestureDetector( + onTap: () { + if (item.link != null) { + launchUrlString(item.link!); + } + }, + child: CacheNetImage( + url: model.getRssImage(item), + fit: BoxFit.cover, + ), + ); + }, + autoplay: true, + ), + )), + SizedBox( + width: 316, + child: Container( + decoration: BoxDecoration( + color: Colors.white.withOpacity(.1), + borderRadius: const BorderRadius.only( + bottomLeft: Radius.circular(12), + bottomRight: Radius.circular(12))), + child: model.rssTextItems == null + ? Padding( + padding: const EdgeInsets.only( + top: 24, bottom: 24), + child: makeLoading(context), + ) + : Column( + children: [ + const SizedBox(height: 12), + ListView.builder( + physics: + const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemBuilder: + (BuildContext context, int index) { + final item = model.rssTextItems![index]; + return Tilt( + shadowConfig: const ShadowConfig( + maxIntensity: .3), + borderRadius: + BorderRadius.circular(12), + child: GestureDetector( + onTap: () { + if (item.link != null) { + launchUrlString(item.link!); + } + }, + child: Padding( + padding: const EdgeInsets.only( + left: 12, + right: 12, + top: 4, + bottom: 4), + child: Row( + children: [ + const Text("· "), + Expanded( + child: Text( + "${item.title}", + textAlign: + TextAlign.start, + maxLines: 1, + overflow: TextOverflow + .ellipsis, + style: const TextStyle( + fontSize: 12.2), + ), + ) + ], + ), + ), + )); + }, + itemCount: model.rssTextItems?.length, + ), + const SizedBox(height: 12), + ], + )), + ), + ], + )), + ), + ), + ), + Positioned( + left: 0, + right: 0, bottom: 0, - child: Column( - children: [ - const SizedBox(height: 12), - makeADCard(context, model, - bgURl: - "https://i2.hdslb.com/bfs/face/7582c8d46fc03004f4f8032c667c0ea4dbbb1088.jpg", - title: "Anicat", - subtitle: "高质量星际公民资讯UP主", - jumpUrl: "https://space.bilibili.com/27976358/video"), - const SizedBox(height: 12), - makeADCard(context, model, - bgURl: - "https://citizenwiki.cn/images/f/f2/890Jump_beach.jpg.webp", - title: "星际公民中文百科", - subtitle: "探索宇宙的好伙伴", - jumpUrl: "https://citizenwiki.cn"), - const SizedBox(height: 12), - makeGameStatusCard(context, model, width), - ], + child: Center( + child: makeGameStatusCard(context, model, 320), )) ], ), @@ -315,9 +424,7 @@ class HomeUI extends BaseUI { ), const SizedBox(height: 8), Text(model.lastScreenInfo, maxLines: 1), - const SizedBox(height: 32), makeIndexActionLists(context, model), - const SizedBox(height: 32), ]; } @@ -480,79 +587,6 @@ class HomeUI extends BaseUI { ); } - Widget makeADCard( - BuildContext context, - HomeUIModel model, { - required String bgURl, - required String title, - required String subtitle, - required String jumpUrl, - }) { - final width = MediaQuery.of(context).size.width * .21; - return Tilt( - shadowConfig: const ShadowConfig(maxIntensity: .3), - borderRadius: BorderRadius.circular(12), - child: GestureDetector( - onTap: () { - launchUrlString(jumpUrl); - }, - child: ClipRRect( - child: Container( - width: width, - height: 128, - decoration: BoxDecoration( - color: FluentTheme.of(context).cardColor, - ), - child: Stack( - children: [ - Padding( - padding: const EdgeInsets.all(.3), - child: ExtendedImage.network( - bgURl, - fit: BoxFit.cover, - width: width, - ), - ), - Container( - width: width, - decoration: BoxDecoration( - color: Colors.black.withOpacity(.7), - ), - ), - Positioned( - top: 0, - bottom: 0, - left: 0, - right: 0, - child: Center( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Text( - title, - style: const TextStyle( - fontSize: 24, - ), - ), - const SizedBox(height: 6), - Text( - subtitle, - style: TextStyle( - color: Colors.white.withOpacity(.8), - fontSize: 14), - ), - ], - ), - ), - ) - ], - ), - ), - ), - ), - ); - } - Widget makeWebViewButton(HomeUIModel model, {required Widget icon, required String name, diff --git a/lib/ui/home/home_ui_model.dart b/lib/ui/home/home_ui_model.dart index 60e2ebd..44b99f4 100644 --- a/lib/ui/home/home_ui_model.dart +++ b/lib/ui/home/home_ui_model.dart @@ -2,11 +2,13 @@ import 'dart:async'; import 'dart:convert'; import 'dart:io'; +import 'package:dart_rss/dart_rss.dart'; import 'package:desktop_webview_window/desktop_webview_window.dart'; import 'package:dio/dio.dart'; import 'package:hive/hive.dart'; import 'package:starcitizen_doctor/api/analytics.dart'; import 'package:starcitizen_doctor/api/api.dart'; +import 'package:starcitizen_doctor/api/rss.dart'; import 'package:starcitizen_doctor/base/ui_model.dart'; import 'package:starcitizen_doctor/common/conf.dart'; import 'package:starcitizen_doctor/common/helper/log_helper.dart'; @@ -25,6 +27,9 @@ import 'package:starcitizen_doctor/ui/home/webview/webview.dart'; import 'package:starcitizen_doctor/ui/home/webview/webview_localization_capture_ui_model.dart'; import 'package:url_launcher/url_launcher_string.dart'; +import 'package:html/parser.dart' as html; +import 'package:html/dom.dart' as htmlDom; + import 'countdown/countdown_dialog_ui.dart'; import 'localization/localization_ui.dart'; import 'performance/performance_ui.dart'; @@ -48,6 +53,9 @@ class HomeUIModel extends BaseUIModel { bool get isCurGameRunning => _isGameRunning[scInstalledPath] ?? false; + List? rssVideoItems; + List? rssTextItems; + set lastScreenInfo(String info) { _lastScreenInfo = info; notifyListeners(); @@ -98,6 +106,7 @@ class HomeUIModel extends BaseUIModel { .data)); countdownFestivalListData = await Api.getFestivalCountdownList(); notifyListeners(); + handleError(() => _loadRRS()); } catch (e) { dPrint(e); } @@ -158,6 +167,15 @@ class HomeUIModel extends BaseUIModel { } } + Future _loadRRS() async { + final v = await RSSApi.getRssVideo(); + rssVideoItems = v; + notifyListeners(); + final t = await RSSApi.getRssText(); + rssTextItems = t; + notifyListeners(); + } + VoidCallback? doCheck() { if (isChecking) return null; return () async { @@ -573,4 +591,17 @@ class HomeUIModel extends BaseUIModel { CountdownDialogUIModel(countdownFestivalListData!)); }); } + + getRssImage(RssItem item) { + final h = html.parse(item.description ?? ""); + if (h.body == null) return ""; + for (var node in h.body!.nodes) { + if (node is htmlDom.Element) { + if (node.localName == "img") { + return node.attributes["src"]?.trim() ?? ""; + } + } + } + return ""; + } } diff --git a/pubspec.yaml b/pubspec.yaml index f6baedd..2354c98 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -42,7 +42,7 @@ dependencies: path_provider: ^2.1.1 dio: ^5.3.3 markdown_widget: ^2.2.0 - extended_image: ^8.1.1 + extended_image: ^8.2.0 device_info_plus: ^9.0.3 file_picker: ^6.0.0 file_sizes: ^1.0.6 @@ -62,6 +62,11 @@ dependencies: cryptography: ^2.7.0 cryptography_flutter: ^2.3.2 hexcolor: ^3.0.1 + dart_rss: ^3.0.1 + html: ^0.15.4 + +dependency_overrides: + http: ^1.1.2 dev_dependencies: flutter_test: