From 04668b3591fb0a4416248ed7a5fd9bac2db0e951 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Tue, 9 May 2023 14:39:52 +0800 Subject: [PATCH] =?UTF-8?q?mod:=20=E6=A0=B7=E5=BC=8F=E3=80=81dio=E5=BC=82?= =?UTF-8?q?=E5=B8=B8=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ios/Podfile.lock | 14 - lib/common/skeleton/video_card_v.dart | 1 - lib/common/skeleton/video_reply.dart | 6 - lib/common/widgets/http_error.dart | 1 + lib/common/widgets/stat/danmu.dart | 17 +- lib/common/widgets/stat/up.dart | 24 ++ lib/common/widgets/stat/view.dart | 21 +- lib/common/widgets/video_card_h.dart | 12 +- lib/http/init.dart | 4 +- lib/http/interceptor.dart | 13 +- lib/http/user.dart | 4 +- lib/http/video.dart | 60 ++-- lib/models/user/info.dart | 73 ++++ lib/models/video/reply/item.dart | 2 +- lib/pages/home/controller.dart | 3 +- lib/pages/home/view.dart | 67 ++-- lib/pages/home/widgets/app_bar.dart | 23 +- lib/pages/hot/view.dart | 2 +- lib/pages/main/controller.dart | 37 +- lib/pages/mine/controller.dart | 3 + lib/pages/mine/view.dart | 334 ++++++++++-------- lib/pages/preview/controller.dart | 5 - lib/pages/preview/view.dart | 5 - lib/pages/video/detail/introduction/view.dart | 7 +- .../detail/reply/widgets/reply_item.dart | 36 +- lib/pages/webview/controller.dart | 7 +- lib/utils/utils.dart | 21 -- pubspec.lock | 8 - pubspec.yaml | 1 - 29 files changed, 469 insertions(+), 342 deletions(-) create mode 100644 lib/common/widgets/stat/up.dart diff --git a/ios/Podfile.lock b/ios/Podfile.lock index c6b5ee31..c7f1a66e 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -5,19 +5,11 @@ PODS: - device_info_plus (0.0.1): - Flutter - Flutter (1.0.0) - - flutter_inappwebview (0.0.1): - - Flutter - - flutter_inappwebview/Core (= 0.0.1) - - OrderedSet (~> 5.0) - - flutter_inappwebview/Core (0.0.1): - - Flutter - - OrderedSet (~> 5.0) - FMDB (2.7.5): - FMDB/standard (= 2.7.5) - FMDB/standard (2.7.5) - image_gallery_saver (1.5.0): - Flutter - - OrderedSet (5.0.0) - path_provider_foundation (0.0.1): - Flutter - FlutterMacOS @@ -40,7 +32,6 @@ DEPENDENCIES: - connectivity_plus (from `.symlinks/plugins/connectivity_plus/ios`) - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`) - Flutter (from `Flutter`) - - flutter_inappwebview (from `.symlinks/plugins/flutter_inappwebview/ios`) - image_gallery_saver (from `.symlinks/plugins/image_gallery_saver/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/ios`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) @@ -53,7 +44,6 @@ DEPENDENCIES: SPEC REPOS: trunk: - FMDB - - OrderedSet - ReachabilitySwift EXTERNAL SOURCES: @@ -63,8 +53,6 @@ EXTERNAL SOURCES: :path: ".symlinks/plugins/device_info_plus/ios" Flutter: :path: Flutter - flutter_inappwebview: - :path: ".symlinks/plugins/flutter_inappwebview/ios" image_gallery_saver: :path: ".symlinks/plugins/image_gallery_saver/ios" path_provider_foundation: @@ -86,10 +74,8 @@ SPEC CHECKSUMS: connectivity_plus: 413a8857dd5d9f1c399a39130850d02fe0feaf7e device_info_plus: e5c5da33f982a436e103237c0c85f9031142abed Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 - flutter_inappwebview: bfd58618f49dc62f2676de690fc6dcda1d6c3721 FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a image_gallery_saver: 259eab68fb271cfd57d599904f7acdc7832e7ef2 - OrderedSet: aaeb196f7fef5a9edf55d89760da9176ad40b93c path_provider_foundation: c68054786f1b4f3343858c1e1d0caaded73f0be9 permission_handler_apple: 44366e37eaf29454a1e7b1b7d736c2cceaeb17ce ReachabilitySwift: 985039c6f7b23a1da463388634119492ff86c825 diff --git a/lib/common/skeleton/video_card_v.dart b/lib/common/skeleton/video_card_v.dart index aeff595f..859f95aa 100644 --- a/lib/common/skeleton/video_card_v.dart +++ b/lib/common/skeleton/video_card_v.dart @@ -23,7 +23,6 @@ class VideoCardVSkeleton extends StatelessWidget { return Container( clipBehavior: Clip.hardEdge, decoration: BoxDecoration( - color: Theme.of(context).colorScheme.background, borderRadius: BorderRadius.circular(6), ), ); diff --git a/lib/common/skeleton/video_reply.dart b/lib/common/skeleton/video_reply.dart index 219540eb..adfba431 100644 --- a/lib/common/skeleton/video_reply.dart +++ b/lib/common/skeleton/video_reply.dart @@ -71,12 +71,6 @@ class VideoReplySkeleton extends StatelessWidget { ], ), ), - Divider( - height: 1, - indent: 52, - endIndent: 10, - color: Theme.of(context).dividerColor.withOpacity(0.08), - ) ], ), ); diff --git a/lib/common/widgets/http_error.dart b/lib/common/widgets/http_error.dart index b3aa348d..607fffe0 100644 --- a/lib/common/widgets/http_error.dart +++ b/lib/common/widgets/http_error.dart @@ -17,6 +17,7 @@ class HttpError extends StatelessWidget { children: [ Text( errMsg, + textAlign: TextAlign.center, style: Theme.of(context).textTheme.titleMedium, ), const SizedBox(height: 10), diff --git a/lib/common/widgets/stat/danmu.dart b/lib/common/widgets/stat/danmu.dart index 44f63b21..d8deb3e2 100644 --- a/lib/common/widgets/stat/danmu.dart +++ b/lib/common/widgets/stat/danmu.dart @@ -1,3 +1,4 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:pilipala/utils/utils.dart'; @@ -11,21 +12,21 @@ class StatDanMu extends StatelessWidget { @override Widget build(BuildContext context) { + Color color = + theme == 'white' ? Colors.white : Theme.of(context).colorScheme.outline; return Row( children: [ - Image.asset( - 'assets/images/dm_$theme.png', - width: size == 'medium' ? 16 : 14, - height: size == 'medium' ? 16 : 14, + Icon( + CupertinoIcons.ellipses_bubble, + size: 14, + color: color, ), - const SizedBox(width: 2), + const SizedBox(width: 3), Text( Utils.numFormat(danmu!), style: TextStyle( fontSize: size == 'medium' ? 12 : 11, - color: theme == 'white' - ? Colors.white - : Theme.of(context).colorScheme.outline, + color: color, ), ) ], diff --git a/lib/common/widgets/stat/up.dart b/lib/common/widgets/stat/up.dart new file mode 100644 index 00000000..d217e2c4 --- /dev/null +++ b/lib/common/widgets/stat/up.dart @@ -0,0 +1,24 @@ +import 'package:flutter/material.dart'; + +class UpTag extends StatelessWidget { + const UpTag({super.key}); + + @override + Widget build(BuildContext context) { + return Container( + width: 14, + height: 10, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(2), + border: Border.all(color: Theme.of(context).colorScheme.outline)), + margin: const EdgeInsets.only(right: 4), + child: Center( + child: Text( + 'UP', + style: TextStyle( + fontSize: 6, color: Theme.of(context).colorScheme.outline), + ), + ), + ); + } +} diff --git a/lib/common/widgets/stat/view.dart b/lib/common/widgets/stat/view.dart index 6f6d1960..302ceee6 100644 --- a/lib/common/widgets/stat/view.dart +++ b/lib/common/widgets/stat/view.dart @@ -1,3 +1,4 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:pilipala/utils/utils.dart'; @@ -6,26 +7,26 @@ class StatView extends StatelessWidget { final int? view; final String? size; - const StatView({Key? key, this.theme, this.view, this.size}) : super(key: key); + const StatView({Key? key, this.theme, this.view, this.size}) + : super(key: key); @override Widget build(BuildContext context) { + Color color = + theme == 'white' ? Colors.white : Theme.of(context).colorScheme.outline; return Row( children: [ - Image.asset( - 'assets/images/view_$theme.png', - width: size == 'medium' ? 16 : 14, - height: size == 'medium' ? 16 : 14, + Icon( + CupertinoIcons.play_rectangle, + size: 13, + color: color, ), - const SizedBox(width: 2), + const SizedBox(width: 3), Text( Utils.numFormat(view!), - // videoItem['stat']['view'].toString(), style: TextStyle( fontSize: size == 'medium' ? 12 : 11, - color: theme == 'white' - ? Colors.white - : Theme.of(context).colorScheme.outline, + color: color, ), ), ], diff --git a/lib/common/widgets/video_card_h.dart b/lib/common/widgets/video_card_h.dart index 6e881831..fd3c289c 100644 --- a/lib/common/widgets/video_card_h.dart +++ b/lib/common/widgets/video_card_h.dart @@ -1,6 +1,7 @@ import 'package:get/get.dart'; import 'package:flutter/material.dart'; import 'package:pilipala/common/constants.dart'; +import 'package:pilipala/common/widgets/stat/up.dart'; import 'package:pilipala/common/widgets/stat/view.dart'; import 'package:pilipala/utils/utils.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart'; @@ -137,11 +138,12 @@ class VideoContent extends StatelessWidget { const SizedBox(height: 4), Row( children: [ - Image.asset( - 'assets/images/up_gray.png', - width: 14, - height: 12, - ), + // Image.asset( + // 'assets/images/up_gray.png', + // width: 14, + // height: 12, + // ), + const UpTag(), const SizedBox(width: 2), Text( videoItem.owner.name, diff --git a/lib/http/init.dart b/lib/http/init.dart index 0ac94f85..b5008a60 100644 --- a/lib/http/init.dart +++ b/lib/http/init.dart @@ -111,7 +111,7 @@ class Request { return response; } on DioError catch (e) { print('get error: $e'); - return Future.error(ApiInterceptor.dioError(e)); + return Future.error(await ApiInterceptor.dioError(e)); } } @@ -132,7 +132,7 @@ class Request { return response; } on DioError catch (e) { print('post error: $e'); - return Future.error(ApiInterceptor.dioError(e)); + return Future.error(await ApiInterceptor.dioError(e)); } } diff --git a/lib/http/interceptor.dart b/lib/http/interceptor.dart index d7140b00..8ee8c8a0 100644 --- a/lib/http/interceptor.dart +++ b/lib/http/interceptor.dart @@ -1,10 +1,12 @@ import 'package:dio/dio.dart'; import 'package:connectivity_plus/connectivity_plus.dart'; +import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; +import 'package:get/get.dart' hide Response; class ApiInterceptor extends Interceptor { @override void onRequest(RequestOptions options, RequestInterceptorHandler handler) { - // print("请求之前"); + print("请求之前"); // 在请求之前添加头部或认证信息 // options.headers['Authorization'] = 'Bearer token'; // options.headers['Content-Type'] = 'application/json'; @@ -13,15 +15,14 @@ class ApiInterceptor extends Interceptor { @override void onResponse(Response response, ResponseInterceptorHandler handler) { - // print("响应之前"); handler.next(response); } @override - void onError(DioError err, ErrorInterceptorHandler handler) { + void onError(DioError err, ErrorInterceptorHandler handler) async { // 处理网络请求错误 - - handler.next(err); + // handler.next(err); + SmartDialog.showToast(await dioError(err)); super.onError(err, handler); } @@ -43,7 +44,7 @@ class ApiInterceptor extends Interceptor { return "发送请求超时,请检查网络设置"; case DioErrorType.unknown: var res = await checkConect(); - return "$res 网络异常,请稍后重试!"; + return res + " \n 网络异常,请稍后重试!"; default: return "Dio异常"; } diff --git a/lib/http/user.dart b/lib/http/user.dart index f7f19a55..77964f08 100644 --- a/lib/http/user.dart +++ b/lib/http/user.dart @@ -1,5 +1,6 @@ import 'package:pilipala/http/api.dart'; import 'package:pilipala/http/init.dart'; +import 'package:pilipala/models/user/info.dart'; class UserHttp { static Future userStat({required int mid}) async { @@ -14,7 +15,8 @@ class UserHttp { static Future userInfo() async { var res = await Request().get(Api.userInfo); if (res.data['code'] == 0) { - return {'status': true, 'data': res.data['data']}; + UserInfoData data = UserInfoData.fromJson(res.data['data']); + return {'status': true, 'data': data}; } else { return {'status': false}; } diff --git a/lib/http/video.dart b/lib/http/video.dart index 61f2770e..686bbc2d 100644 --- a/lib/http/video.dart +++ b/lib/http/video.dart @@ -11,39 +11,47 @@ import 'package:pilipala/models/video_detail_res.dart'; class VideoHttp { // 首页推荐视频 static Future rcmdVideoList({required int ps, required int freshIdx}) async { - var res = await Request().get( - Api.recommendList, - data: { - 'feed_version': 'V3', - 'ps': ps, - 'fresh_idx': freshIdx, - }, - ); - if (res.data['code'] == 0) { - List list = []; - for (var i in res.data['data']['item']) { - list.add(RecVideoItemModel.fromJson(i)); + try { + var res = await Request().get( + Api.recommendList, + data: { + 'feed_version': 'V3', + 'ps': ps, + 'fresh_idx': freshIdx, + }, + ); + if (res.data['code'] == 0) { + List list = []; + for (var i in res.data['data']['item']) { + list.add(RecVideoItemModel.fromJson(i)); + } + return {'status': true, 'data': list}; + } else { + return {'status': false, 'data': []}; } - return {'status': true, 'data': list}; - } else { - return {'status': false, 'data': []}; + } catch (err) { + return {'status': false, 'data': [], 'msg': err}; } } // 最热视频 static Future hotVideoList({required int pn, required int ps}) async { - var res = await Request().get( - Api.hotList, - data: {'pn': pn, 'ps': ps}, - ); - if (res.data['code'] == 0) { - List list = []; - for (var i in res.data['data']['list']) { - list.add(HotVideoItemModel.fromJson(i)); + try { + var res = await Request().get( + Api.hotList, + data: {'pn': pn, 'ps': ps}, + ); + if (res.data['code'] == 0) { + List list = []; + for (var i in res.data['data']['list']) { + list.add(HotVideoItemModel.fromJson(i)); + } + return {'status': true, 'data': list}; + } else { + return {'status': false, 'data': []}; } - return {'status': true, 'data': list}; - } else { - return {'status': false, 'data': []}; + } catch (err) { + return {'status': false, 'data': [], 'msg': err}; } } diff --git a/lib/models/user/info.dart b/lib/models/user/info.dart index 9fa34bb7..ce8b641c 100644 --- a/lib/models/user/info.dart +++ b/lib/models/user/info.dart @@ -1,7 +1,80 @@ class UserInfoData { UserInfoData({ this.isLogin, + this.emailVerified, + this.face, + this.levelInfo, + this.mid, + this.mobileVerified, + this.money, + this.moral, + this.official, + this.officialVerify, + this.pendant, + this.scores, + this.uname, + this.vipDueDate, + this.vipStatus, + this.vipType, + this.vipPayType, + this.vipThemeType, + this.vipLabel, + this.vipAvatarSub, + this.vipNicknameColor, + this.wallet, + this.hasShop, + this.shopUrl, }); bool? isLogin; + int? emailVerified; + String? face; + Map? levelInfo; + int? mid; + int? mobileVerified; + int? money; + int? moral; + Map? official; + Map? officialVerify; + Map? pendant; + int? scores; + String? uname; + int? vipDueDate; + int? vipStatus; + int? vipType; + int? vipPayType; + int? vipThemeType; + Map? vipLabel; + int? vipAvatarSub; + String? vipNicknameColor; + Map? wallet; + bool? hasShop; + String? shopUrl; + + UserInfoData.fromJson(Map json) { + isLogin = json['isLogin'] ?? false; + emailVerified = json['email_verified']; + face = json['face']; + levelInfo = json['level_info']; + mid = json['mid']; + mobileVerified = json['mobile_verified']; + money = json['money']; + moral = json['moral']; + official = json['official']; + officialVerify = json['officialVerify']; + pendant = json['pendant']; + scores = json['scores']; + uname = json['uname']; + vipDueDate = json['vipDueDate']; + vipStatus = json['vipStatus']; + vipType = json['vipType']; + vipPayType = json['vip_pay_type']; + vipThemeType = json['vip_theme_type']; + vipLabel = json['vip_label']; + vipAvatarSub = json['vip_avatar_subscript']; + vipNicknameColor = json['vip_nickname_color']; + wallet = json['wallet']; + hasShop = json['has_shop']; + shopUrl = json['shop_url']; + } } diff --git a/lib/models/video/reply/item.dart b/lib/models/video/reply/item.dart index c6838a13..a1e96561 100644 --- a/lib/models/video/reply/item.dart +++ b/lib/models/video/reply/item.dart @@ -149,6 +149,6 @@ class ReplyControl { entryText = json['sub_reply_entry_text']; titleText = json['sub_reply_title_text']; time = json['time_desc']; - location = json['location'] ?? ''; + location = json['location'] != null ? json['location'].split(':')[1] : ''; } } diff --git a/lib/pages/home/controller.dart b/lib/pages/home/controller.dart index e96d8b60..7182b134 100644 --- a/lib/pages/home/controller.dart +++ b/lib/pages/home/controller.dart @@ -15,7 +15,7 @@ class HomeController extends GetxController { @override void onInit() { super.onInit(); - queryRcmdFeed('init'); + // queryRcmdFeed('init'); } // 获取推荐 @@ -35,6 +35,7 @@ class HomeController extends GetxController { _currentPage += 1; } isLoadingMore = false; + return res; } // 下拉刷新 diff --git a/lib/pages/home/view.dart b/lib/pages/home/view.dart index 1adb482b..0d08ed3e 100644 --- a/lib/pages/home/view.dart +++ b/lib/pages/home/view.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:pilipala/common/skeleton/video_card_v.dart'; +import 'package:pilipala/common/widgets/http_error.dart'; import 'package:pilipala/common/widgets/video_card_v.dart'; import './controller.dart'; import 'package:pilipala/common/constants.dart'; @@ -16,6 +17,7 @@ class HomePage extends StatefulWidget { class _HomePageState extends State with AutomaticKeepAliveClientMixin { final HomeController _homeController = Get.put(HomeController()); + Future? _futureBuilderFuture; List videoList = []; @override @@ -24,6 +26,7 @@ class _HomePageState extends State @override void initState() { super.initState(); + _futureBuilderFuture = _homeController.queryRcmdFeed('init'); _homeController.videoList.listen((value) { videoList = value; setState(() {}); @@ -69,26 +72,25 @@ class _HomePageState extends State ? EdgeInsets.zero : const EdgeInsets.fromLTRB( StyleString.cardSpace, 0, StyleString.cardSpace, 8), - sliver: SliverGrid( - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - // 行间距 - mainAxisSpacing: StyleString.cardSpace, - // 列间距 - crossAxisSpacing: StyleString.cardSpace, - // 列数 - crossAxisCount: _homeController.crossAxisCount, - mainAxisExtent: MediaQuery.of(context).size.width / - _homeController.crossAxisCount / - StyleString.aspectRatio + - 70), - delegate: SliverChildBuilderDelegate( - (BuildContext context, int index) { - return videoList.isNotEmpty - ? VideoCardV(videoItem: videoList[index]) - : const VideoCardVSkeleton(); - }, - childCount: videoList.isNotEmpty ? videoList.length : 10, - ), + sliver: FutureBuilder( + future: _futureBuilderFuture, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + Map data = snapshot.data as Map; + if (data['status']) { + return Obx(() => contentGrid( + _homeController, _homeController.videoList)); + } else { + return HttpError( + errMsg: data['msg'], + fn: () => setState(() {}), + ); + } + } else { + // 骨架屏 + return contentGrid(_homeController, []); + } + }, ), ), const LoadingMore() @@ -98,6 +100,31 @@ class _HomePageState extends State // ), ); } + + Widget contentGrid(ctr, videoList) { + return SliverGrid( + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + // 行间距 + mainAxisSpacing: StyleString.cardSpace, + // 列间距 + crossAxisSpacing: StyleString.cardSpace, + // 列数 + crossAxisCount: ctr.crossAxisCount, + mainAxisExtent: MediaQuery.of(context).size.width / + ctr.crossAxisCount / + StyleString.aspectRatio + + 70, + ), + delegate: SliverChildBuilderDelegate( + (BuildContext context, int index) { + return videoList!.isNotEmpty + ? VideoCardV(videoItem: videoList![index]) + : const VideoCardVSkeleton(); + }, + childCount: videoList!.isNotEmpty ? videoList!.length : 10, + ), + ); + } } class MySliverPersistentHeaderDelegate extends SliverPersistentHeaderDelegate { diff --git a/lib/pages/home/widgets/app_bar.dart b/lib/pages/home/widgets/app_bar.dart index cd070d1d..f0b142e0 100644 --- a/lib/pages/home/widgets/app_bar.dart +++ b/lib/pages/home/widgets/app_bar.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; @@ -10,11 +11,7 @@ class HomeAppBar extends StatelessWidget { return SliverAppBar( // forceElevated: true, scrolledUnderElevation: 0, - toolbarHeight: Platform.isAndroid - ? (MediaQuery.of(context).padding.top + 6) - : Platform.isIOS - ? MediaQuery.of(context).padding.top - 2 - : kToolbarHeight, + toolbarHeight: MediaQuery.of(context).padding.top, expandedHeight: kToolbarHeight + MediaQuery.of(context).padding.top, automaticallyImplyLeading: false, pinned: true, @@ -39,18 +36,12 @@ class HomeAppBar extends StatelessWidget { actions: [ IconButton( onPressed: () {}, - icon: const FaIcon( - FontAwesomeIcons.magnifyingGlass, - size: 18, - ), - ), - IconButton( - onPressed: () {}, - icon: const FaIcon( - FontAwesomeIcons.envelope, - size: 20, - ), + icon: const Icon(CupertinoIcons.search, size: 22), ), + // IconButton( + // onPressed: () {}, + // icon: const Icon(CupertinoIcons.bell, size: 22), + // ), const SizedBox(width: 10) ], elevation: 0, diff --git a/lib/pages/hot/view.dart b/lib/pages/hot/view.dart index 3bddd37c..51abee1e 100644 --- a/lib/pages/hot/view.dart +++ b/lib/pages/hot/view.dart @@ -24,7 +24,7 @@ class _HotPageState extends State with AutomaticKeepAliveClientMixin { @override void initState() { super.initState(); - _futureBuilderFuture = _hotController!.queryHotFeed('init'); + _futureBuilderFuture = _hotController.queryHotFeed('init'); _hotController.scrollController.addListener( () { if (_hotController.scrollController.position.pixels >= diff --git a/lib/pages/main/controller.dart b/lib/pages/main/controller.dart index f7ef9e49..2206af59 100644 --- a/lib/pages/main/controller.dart +++ b/lib/pages/main/controller.dart @@ -1,3 +1,4 @@ +import 'package:flutter/cupertino.dart'; import 'package:get/get.dart'; import 'package:flutter/material.dart'; import 'package:pilipala/pages/home/view.dart'; @@ -12,18 +13,42 @@ class MainController extends GetxController { ]; List navigationBars = [ { - 'icon': const Icon(Icons.home_outlined), - 'selectedIcon': const Icon(Icons.home), + // 'icon': const Icon(Icons.home_outlined), + // 'selectedIcon': const Icon(Icons.home), + 'icon': const Icon( + CupertinoIcons.house, + size: 18, + ), + 'selectedIcon': const Icon( + CupertinoIcons.house_fill, + size: 18, + ), 'label': "推荐", }, { - 'icon': const Icon(Icons.whatshot_outlined), - 'selectedIcon': const Icon(Icons.whatshot_rounded), + // 'icon': const Icon(Icons.whatshot_outlined), + // 'selectedIcon': const Icon(Icons.whatshot_rounded), + 'icon': const Icon( + CupertinoIcons.flame, + size: 20, + ), + 'selectedIcon': const Icon( + CupertinoIcons.flame_fill, + size: 20, + ), 'label': "热门", }, { - 'icon': const Icon(Icons.person_outline), - 'selectedIcon': const Icon(Icons.person), + // 'icon': const Icon(Icons.person_outline), + // 'selectedIcon': const Icon(Icons.person), + 'icon': const Icon( + CupertinoIcons.person, + size: 21, + ), + 'selectedIcon': const Icon( + CupertinoIcons.person_fill, + size: 21, + ), 'label': "我的", } ]; diff --git a/lib/pages/mine/controller.dart b/lib/pages/mine/controller.dart index 9e867c78..5c560ebc 100644 --- a/lib/pages/mine/controller.dart +++ b/lib/pages/mine/controller.dart @@ -1,7 +1,10 @@ import 'package:get/get.dart'; import 'package:pilipala/http/user.dart'; +import 'package:pilipala/models/user/info.dart'; class MineController extends GetxController { + UserInfoData? userInfo; + @override void onInit() { super.onInit(); diff --git a/lib/pages/mine/view.dart b/lib/pages/mine/view.dart index 10c7ab36..54796281 100644 --- a/lib/pages/mine/view.dart +++ b/lib/pages/mine/view.dart @@ -1,3 +1,4 @@ +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:get/get.dart'; @@ -22,13 +23,19 @@ class _MinePageState extends State { actions: [ IconButton( onPressed: () {}, - icon: const Icon(Icons.light_mode_rounded), + icon: const Icon( + CupertinoIcons.moon, + size: 22, + ), + // icon: const Icon( + // CupertinoIcons.sun_max, + // size: 22, + // ), ), IconButton( onPressed: () {}, - icon: const FaIcon( - FontAwesomeIcons.sliders, - size: 18, + icon: const Icon( + CupertinoIcons.slider_horizontal_3, ), ), const SizedBox(width: 10), @@ -36,161 +43,183 @@ class _MinePageState extends State { ), body: RefreshIndicator( onRefresh: () async { - await Future.delayed(Duration(seconds: 2)); + await Future.delayed(const Duration(seconds: 2)); }, - child: Column( - children: [ - InkWell( - onTap: () { - Get.toNamed( - '/webview', - parameters: { - 'url': - 'https://passport.bilibili.com/h5-app/passport/login', - 'type': 'login', - 'pageTitle': '登录bilibili', - }, - ); - }, - child: Padding( - padding: const EdgeInsets.only(top: 10, bottom: 10), - child: Row( + child: LayoutBuilder( + builder: (context, constraint) { + return SingleChildScrollView( + physics: const AlwaysScrollableScrollPhysics(), + child: SizedBox( + height: constraint.maxHeight, + child: Column( children: [ - const SizedBox(width: 20), - ClipOval( - child: Container( - width: 75, - height: 75, - color: Theme.of(context).colorScheme.onInverseSurface, - child: Center( - child: Image.asset('assets/images/loading.png'), + InkWell( + onTap: () { + Get.toNamed( + '/webview', + parameters: { + 'url': + 'https://passport.bilibili.com/h5-app/passport/login', + 'type': 'login', + 'pageTitle': '登录bilibili', + }, + ); + }, + child: Padding( + padding: const EdgeInsets.only(top: 10, bottom: 10), + child: Row( + children: [ + const SizedBox(width: 20), + ClipOval( + child: Container( + width: 75, + height: 75, + color: Theme.of(context) + .colorScheme + .onInverseSurface, + child: Center( + child: + Image.asset('assets/images/loading.png'), + ), + ), + ), + const SizedBox(width: 14), + Text( + '点击登录', + style: Theme.of(context).textTheme.titleMedium, + ), + ], ), ), ), - const SizedBox(width: 14), - Text( - '点击登录', - style: Theme.of(context).textTheme.titleMedium, + const SizedBox(height: 10), + Padding( + padding: const EdgeInsets.only(left: 12, right: 12), + child: LayoutBuilder( + builder: (context, constraints) { + TextStyle style = TextStyle( + fontSize: Theme.of(context) + .textTheme + .titleMedium! + .fontSize, + color: Theme.of(context).colorScheme.primary, + fontWeight: FontWeight.bold); + return SizedBox( + height: constraints.maxWidth / 3 * 0.6, + child: GridView.count( + primary: false, + padding: const EdgeInsets.all(0), + crossAxisCount: 3, + childAspectRatio: 1.67, + children: [ + InkWell( + onTap: () {}, + borderRadius: StyleString.mdRadius, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('-', style: style), + const SizedBox(height: 8), + Text( + '动态', + style: Theme.of(context) + .textTheme + .labelMedium, + ), + ], + ), + ), + InkWell( + onTap: () {}, + borderRadius: StyleString.mdRadius, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '50', + style: style, + ), + const SizedBox(height: 8), + Text( + '关注', + style: Theme.of(context) + .textTheme + .labelMedium, + ), + ], + ), + ), + InkWell( + onTap: () {}, + borderRadius: StyleString.mdRadius, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '-', + style: style, + ), + const SizedBox(height: 8), + Text( + '粉丝', + style: Theme.of(context) + .textTheme + .labelMedium, + ), + ], + ), + ), + ], + ), + ); + }, + ), + ), + const SizedBox(height: 20), + Padding( + padding: const EdgeInsets.only(left: 12, right: 12), + child: LayoutBuilder( + builder: (context, constraints) { + return SizedBox( + height: constraints.maxWidth / 4 * 0.8, + child: GridView.count( + primary: false, + padding: const EdgeInsets.all(0), + crossAxisCount: 4, + childAspectRatio: 1.25, + children: [ + ActionItem( + icon: + const Icon(CupertinoIcons.cloud_download), + onTap: () => {}, + text: '离线缓存', + ), + ActionItem( + icon: const Icon(CupertinoIcons.time), + onTap: () => {}, + text: '历史记录', + ), + ActionItem( + icon: const Icon(CupertinoIcons.star), + onTap: () => {}, + text: '我的收藏', + ), + ActionItem( + icon: const Icon(CupertinoIcons.film), + onTap: () => {}, + text: '稍后再看', + ), + ], + ), + ); + }, + ), ), ], ), ), - ), - const SizedBox(height: 10), - Padding( - padding: const EdgeInsets.only(left: 12, right: 12), - child: LayoutBuilder( - builder: (context, constraints) { - TextStyle style = TextStyle( - fontSize: - Theme.of(context).textTheme.titleMedium!.fontSize, - color: Theme.of(context).colorScheme.primary, - fontWeight: FontWeight.bold); - return SizedBox( - height: constraints.maxWidth / 3 * 0.6, - child: GridView.count( - primary: false, - padding: const EdgeInsets.all(0), - crossAxisCount: 3, - childAspectRatio: 1.67, - children: [ - InkWell( - onTap: () {}, - borderRadius: StyleString.mdRadius, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text('-', style: style), - const SizedBox(height: 8), - Text( - '动态', - style: Theme.of(context).textTheme.labelMedium, - ), - ], - ), - ), - InkWell( - onTap: () {}, - borderRadius: StyleString.mdRadius, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - '50', - style: style, - ), - const SizedBox(height: 8), - Text( - '关注', - style: Theme.of(context).textTheme.labelMedium, - ), - ], - ), - ), - InkWell( - onTap: () {}, - borderRadius: StyleString.mdRadius, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Text( - '-', - style: style, - ), - const SizedBox(height: 8), - Text( - '粉丝', - style: Theme.of(context).textTheme.labelMedium, - ), - ], - ), - ), - ], - ), - ); - }, - ), - ), - const SizedBox(height: 20), - Padding( - padding: const EdgeInsets.only(left: 12, right: 12), - child: LayoutBuilder( - builder: (context, constraints) { - return SizedBox( - height: constraints.maxWidth / 4 * 0.8, - child: GridView.count( - primary: false, - padding: const EdgeInsets.all(0), - crossAxisCount: 4, - childAspectRatio: 1.25, - children: [ - ActionItem( - icon: const Icon(FontAwesomeIcons.download), - onTap: () => {}, - text: '离线缓存', - ), - ActionItem( - icon: const Icon(FontAwesomeIcons.clockRotateLeft), - onTap: () => {}, - text: '历史记录', - ), - ActionItem( - icon: const Icon(FontAwesomeIcons.star), - onTap: () => {}, - text: '我的收藏', - ), - ActionItem( - icon: const Icon(FontAwesomeIcons.film), - onTap: () => {}, - text: '稍后再看', - ), - ], - ), - ); - }, - ), - ), - ], + ); + }, ), ), ); @@ -217,10 +246,7 @@ class ActionItem extends StatelessWidget { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon( - icon!.icon!, - color: Theme.of(context).colorScheme.outline, - ), + Icon(icon!.icon!), const SizedBox(height: 8), Text( text!, diff --git a/lib/pages/preview/controller.dart b/lib/pages/preview/controller.dart index f2af8b9c..fd0d4472 100644 --- a/lib/pages/preview/controller.dart +++ b/lib/pages/preview/controller.dart @@ -69,9 +69,4 @@ class PreviewController extends GetxController { File(path).writeAsBytesSync(response.data); Share.shareXFiles([XFile(path)], subject: imgList[initialPage.value]); } - - // 浏览器中查看 - void onBrowserImg() async { - Utils.openURL(imgList[initialPage.value]); - } } diff --git a/lib/pages/preview/view.dart b/lib/pages/preview/view.dart index d82cd45e..2ff9bd73 100644 --- a/lib/pages/preview/view.dart +++ b/lib/pages/preview/view.dart @@ -74,11 +74,6 @@ class _ImagePreviewState extends State onTap: _previewController.onSaveImg, child: const Text('保存'), ), - PopupMenuItem( - value: 'browser', - onTap: _previewController.onBrowserImg, - child: const Text('浏览器中查看'), - ), ], ), ], diff --git a/lib/pages/video/detail/introduction/view.dart b/lib/pages/video/detail/introduction/view.dart index 623a2684..4bef011b 100644 --- a/lib/pages/video/detail/introduction/view.dart +++ b/lib/pages/video/detail/introduction/view.dart @@ -1,3 +1,4 @@ +import 'package:flutter/cupertino.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:get/get.dart'; import 'package:flutter/material.dart'; @@ -246,8 +247,8 @@ class _VideoInfoState extends State with TickerProviderStateMixin { child: Row( children: const [ Icon( - FontAwesomeIcons.lemon, - size: 15, + CupertinoIcons.plus, + size: 16, ), SizedBox(width: 4), Text('关注'), @@ -383,7 +384,7 @@ class ActionItem extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(icon!.icon!, - size: 20, + size: 21, color: selectStatus ? Theme.of(context).primaryColor : Theme.of(context).colorScheme.outline), diff --git a/lib/pages/video/detail/reply/widgets/reply_item.dart b/lib/pages/video/detail/reply/widgets/reply_item.dart index 8f0e3cb6..f920da95 100644 --- a/lib/pages/video/detail/reply/widgets/reply_item.dart +++ b/lib/pages/video/detail/reply/widgets/reply_item.dart @@ -18,15 +18,15 @@ class ReplyItem extends StatelessWidget { child: Column( children: [ Padding( - padding: const EdgeInsets.fromLTRB(12, 8, 8, 2), + padding: const EdgeInsets.fromLTRB(12, 6, 8, 0), child: content(context), ), - Divider( - height: 1, - indent: 52, - endIndent: 10, - color: Theme.of(context).dividerColor.withOpacity(0.08), - ) + // Divider( + // height: 1, + // indent: 52, + // endIndent: 10, + // color: Theme.of(context).dividerColor.withOpacity(0.08), + // ) ], ), ); @@ -154,7 +154,7 @@ class ReplyItem extends StatelessWidget { ), // title Container( - margin: const EdgeInsets.only(top: 0, left: 45, right: 6), + margin: const EdgeInsets.only(top: 0, left: 45, right: 6, bottom: 6), child: SelectableRegion( magnifierConfiguration: const TextMagnifierConfiguration(), focusNode: FocusNode(), @@ -201,7 +201,7 @@ class ReplyItem extends StatelessWidget { .copyWith(color: Theme.of(context).colorScheme.outline), ), if (replyItem!.replyControl != null && - replyItem!.replyControl!.location != null) + replyItem!.replyControl!.location != '') Text( ' • ${replyItem!.replyControl!.location!}', style: Theme.of(context) @@ -315,10 +315,6 @@ class ReplyItemRow extends StatelessWidget { maxLines: extraRow == 1 ? 2 : null, TextSpan( children: [ - if (replies![index].isUp) - WidgetSpan( - child: UpTag(), - ), TextSpan( text: replies![index].member.uname + ' ', style: TextStyle( @@ -333,6 +329,10 @@ class ReplyItemRow extends StatelessWidget { print('跳转至用户主页'), }, ), + if (replies![index].isUp) + WidgetSpan( + child: UpTag(), + ), buildContent(context, replies![index].content), ], ), @@ -352,13 +352,14 @@ class ReplyItemRow extends StatelessWidget { useRootNavigator: true, isScrollControlled: true, Container( - height: Get.size.height - Get.size.width * 9 / 16 - 50, + height: Get.size.height - Get.size.width * 9 / 16 - 45, color: Theme.of(context).colorScheme.background, child: Column( children: [ AppBar( automaticallyImplyLeading: false, centerTitle: false, + elevation: 1, title: Text( '评论详情', style: Theme.of(context).textTheme.titleMedium, @@ -367,7 +368,6 @@ class ReplyItemRow extends StatelessWidget { IconButton( icon: const Icon(Icons.close), onPressed: () async { - await Future.delayed(const Duration(milliseconds: 200)); Get.back(); }, ) @@ -546,7 +546,7 @@ InlineSpan buildContent(BuildContext context, content) { arguments: {'initialPage': 0, 'imgList': picList}); }, child: Padding( - padding: EdgeInsets.only(top: 4), + padding: const EdgeInsets.only(top: 4), child: NetworkImgLayer( src: pictureItem['img_src'], width: box.maxWidth / 2, @@ -634,8 +634,8 @@ class UpTag extends StatelessWidget { Widget build(BuildContext context) { Color primary = Theme.of(context).colorScheme.primary; return Container( - width: tagText == 'UP' ? 25 : 32, - height: tagText == 'UP' ? 16 : 18, + width: 24, + height: 15, decoration: BoxDecoration( borderRadius: BorderRadius.circular(3), color: tagText == 'UP' ? primary : null, diff --git a/lib/pages/webview/controller.dart b/lib/pages/webview/controller.dart index 593dd53f..b8d591cc 100644 --- a/lib/pages/webview/controller.dart +++ b/lib/pages/webview/controller.dart @@ -2,6 +2,7 @@ import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; import 'package:pilipala/http/constants.dart'; import 'package:pilipala/http/user.dart'; +import 'package:pilipala/pages/mine/index.dart'; import 'package:pilipala/utils/cookie.dart'; import 'package:webview_cookie_manager/webview_cookie_manager.dart'; import 'package:webview_flutter/webview_flutter.dart'; @@ -45,10 +46,10 @@ class WebviewController extends GetxController { await SetCookie.onSet(cookies, HttpString.baseUrl); await SetCookie.onSet(apiCookies, HttpString.baseApiUrl); var result = await UserHttp.userInfo(); - bool isLogin = result['data']['isLogin']; - if (isLogin) { + if (result['status'] && result['data'].isLogin) { SmartDialog.showToast('登录成功'); - Get.back(); + Get.find().userInfo = result['data']; + // Get.back(); } } catch (e) { print(e); diff --git a/lib/utils/utils.dart b/lib/utils/utils.dart index 03d30181..084a6e6f 100644 --- a/lib/utils/utils.dart +++ b/lib/utils/utils.dart @@ -1,13 +1,10 @@ // 工具函数 import 'dart:io'; import 'dart:math'; -import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:get/get_utils/get_utils.dart'; import 'package:path_provider/path_provider.dart'; class Utils { - final ChromeSafariBrowser browser = ChromeSafariBrowser(); - static Future getCookiePath() async { Directory tempDir = await getApplicationSupportDirectory(); String tempPath = "${tempDir.path}/.plpl/"; @@ -138,22 +135,4 @@ class Utils { static String makeHeroTag(v) { return v.toString() + Random().nextInt(9999).toString(); } - - static openURL(aUrl) async { - try { - await Utils().browser.open( - url: Uri.parse(aUrl), - options: ChromeSafariBrowserClassOptions( - android: AndroidChromeCustomTabsOptions( - shareState: CustomTabsShareState.SHARE_STATE_OFF, - isSingleInstance: false, - isTrustedWebActivity: false, - keepAliveEnabled: true, - ), - ), - ); - } catch (err) { - await InAppBrowser.openWithSystemBrowser(url: Uri.parse(aUrl)); - } - } } diff --git a/pubspec.lock b/pubspec.lock index 78a4654c..45514cc2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -246,14 +246,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.3.0" - flutter_inappwebview: - dependency: "direct main" - description: - name: flutter_inappwebview - sha256: "1c370ac07de80a579a0047c94c5bb586128d4ef50c0f3f501d6e77010374a319" - url: "https://pub.dev" - source: hosted - version: "5.4.4" flutter_lints: dependency: "direct dev" description: diff --git a/pubspec.yaml b/pubspec.yaml index 7374bbf5..63778e94 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -62,7 +62,6 @@ dependencies: share_plus: ^6.3.1 # webView url_launcher: ^6.1.9 - flutter_inappwebview: 5.4.4 webview_cookie_manager: ^2.0.6 webview_flutter: ^4.2.0