From 32eeef7866c15557e7c1605b443f70a9ef1ffd14 Mon Sep 17 00:00:00 2001 From: dom Date: Mon, 11 May 2026 10:06:11 +0800 Subject: [PATCH] tweaks Signed-off-by: dom --- .../widgets/image_viewer/gallery_viewer.dart | 6 +- lib/http/user.dart | 4 +- .../dynamics/widgets/additional_panel.dart | 133 +++++------- .../dynamics/widgets/live_panel_sub.dart | 2 +- .../dynamics/widgets/live_rcmd_panel.dart | 2 +- lib/pages/dynamics/widgets/video_panel.dart | 2 +- lib/pages/dynamics_create/view.dart | 10 +- lib/pages/dynamics_tab/controller.dart | 17 ++ lib/pages/dynamics_tab/view.dart | 19 -- lib/pages/live_room/controller.dart | 63 +++--- lib/pages/live_room/view.dart | 198 ++++++++---------- lib/pages/live_room/widgets/chat_panel.dart | 89 +++----- lib/pages/video/controller.dart | 14 +- lib/pages/video/view.dart | 7 +- lib/utils/global_data.dart | 7 +- 15 files changed, 253 insertions(+), 320 deletions(-) diff --git a/lib/common/widgets/image_viewer/gallery_viewer.dart b/lib/common/widgets/image_viewer/gallery_viewer.dart index 65b6ad972..c70b273ea 100644 --- a/lib/common/widgets/image_viewer/gallery_viewer.dart +++ b/lib/common/widgets/image_viewer/gallery_viewer.dart @@ -399,7 +399,11 @@ class _GalleryViewerState extends State final isLongPic = item.isLongPic; child = Image( key: _key, - image: CachedNetworkImageProvider(_getActualUrl(item.url)), + image: ResizeImage.resizeIfNeeded( + _containerSize.width.cacheSize(context), + null, + CachedNetworkImageProvider(_getActualUrl(item.url)), + ), minScale: widget.minScale, maxScale: widget.maxScale, containerSize: _containerSize, diff --git a/lib/http/user.dart b/lib/http/user.dart index 4c7fb2eaa..7f368e740 100644 --- a/lib/http/user.dart +++ b/lib/http/user.dart @@ -382,10 +382,10 @@ abstract final class UserHttp { } } - static Future> getCoin() async { + static Future> getCoin() async { final res = await Request.get(Api.getCoin); if (res.data['code'] == 0) { - return Success(res.data['data']?['money']); + return Success((res.data['data']?['money'] as num?)?.toDouble()); } else { return Error(res.data['message']); } diff --git a/lib/pages/dynamics/widgets/additional_panel.dart b/lib/pages/dynamics/widgets/additional_panel.dart index ff6d67edd..0d84e8fd6 100644 --- a/lib/pages/dynamics/widgets/additional_panel.dart +++ b/lib/pages/dynamics/widgets/additional_panel.dart @@ -34,10 +34,7 @@ Widget? addWidget( ? null : () => PiliScheme.routePushFromUrl(ugc.jumpUrl!), child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 12, - vertical: 8, - ), + padding: const .symmetric(horizontal: 12, vertical: 8), child: Row( children: [ NetworkImgLayer( @@ -48,13 +45,9 @@ Widget? addWidget( const SizedBox(width: 10), Expanded( child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: .start, children: [ - Text( - ugc.title!, - maxLines: 2, - overflow: TextOverflow.ellipsis, - ), + Text(ugc.title!), const SizedBox(height: 4), Text( ugc.descSecond!, @@ -78,18 +71,14 @@ Widget? addWidget( onTap: () {}, borderRadius: borderRadius, child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 10), + padding: const .symmetric(horizontal: 12, vertical: 10), child: Row( children: [ Expanded( child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: .start, children: [ - Text( - reserve.title!, - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), + Text(reserve.title!), const SizedBox(height: 1), Text.rich( TextSpan( @@ -109,7 +98,7 @@ Widget? addWidget( if (reserve.desc3?.text?.isNotEmpty == true) ...[ const TextSpan(text: '\n'), WidgetSpan( - alignment: PlaceholderAlignment.middle, + alignment: .middle, child: Icon( size: 17, Icons.card_giftcard, @@ -158,16 +147,12 @@ Widget? addWidget( alpha: 0.12, ) : null, - visualDensity: VisualDensity.compact, - padding: const EdgeInsets.symmetric( - horizontal: 16, - ), - tapTargetSize: MaterialTapTargetSize.shrinkWrap, + visualDensity: .compact, + tapTargetSize: .shrinkWrap, + padding: const .symmetric(horizontal: 16), ), onPressed: canJump - ? () => PiliScheme.routePushFromUrl( - btn.jumpUrl!, - ) + ? () => PiliScheme.routePushFromUrl(btn.jumpUrl!) : btn.disable == 1 ? null : () async { @@ -216,14 +201,14 @@ Widget? addWidget( ? null : () => PiliScheme.routePushFromUrl(content.jumpUrl!), child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), + padding: const .symmetric(horizontal: 12, vertical: 8), child: Row( children: [ Expanded( child: Column( spacing: 2, - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: .min, + crossAxisAlignment: .start, children: [ if (content.title?.isNotEmpty == true) Text(content.title!), @@ -240,7 +225,7 @@ Widget? addWidget( TextSpan( children: [ WidgetSpan( - alignment: PlaceholderAlignment.middle, + alignment: .middle, child: Icon( size: 17, Icons.card_giftcard, @@ -276,14 +261,14 @@ Widget? addWidget( ), style: FilledButton.styleFrom( shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(6)), + borderRadius: .all(.circular(6)), ), - padding: const EdgeInsets.symmetric(horizontal: 10), + padding: const .symmetric(horizontal: 10), visualDensity: const VisualDensity( horizontal: -2, vertical: -3, ), - tapTargetSize: MaterialTapTargetSize.shrinkWrap, + tapTargetSize: .shrinkWrap, ), child: Text( content.button!.jumpStyle?.text ?? @@ -302,16 +287,13 @@ Widget? addWidget( final content = additional.goods!; if (content.items?.isNotEmpty == true) { child = Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: .start, children: content.items!.map((e) { return InkWell( borderRadius: borderRadius, onTap: () => PiliScheme.routePushFromUrl(e.jumpUrl!), child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 12, - vertical: 8, - ), + padding: const .symmetric(horizontal: 12, vertical: 8), child: Row( children: [ if (e.cover?.isNotEmpty == true) ...[ @@ -319,20 +301,18 @@ Widget? addWidget( width: 45, height: 45, src: e.cover, - borderRadius: const BorderRadius.all( - Radius.circular(6), - ), + borderRadius: const .all(.circular(6)), ), const SizedBox(width: 10), ], Expanded( child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: .start, children: [ Text( e.name!, maxLines: 1, - overflow: TextOverflow.ellipsis, + overflow: .ellipsis, ), if (e.price?.isNotEmpty == true) Text.rich( @@ -361,18 +341,14 @@ Widget? addWidget( PiliScheme.routePushFromUrl(e.jumpUrl!), style: FilledButton.styleFrom( shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all( - Radius.circular(6), - ), - ), - padding: const EdgeInsets.symmetric( - horizontal: 10, + borderRadius: .all(.circular(6)), ), + padding: const .symmetric(horizontal: 10), visualDensity: const VisualDensity( horizontal: -2, vertical: -3, ), - tapTargetSize: MaterialTapTargetSize.shrinkWrap, + tapTargetSize: .shrinkWrap, ), child: Text(e.jumpDesc!), ), @@ -399,7 +375,7 @@ Widget? addWidget( : null, ), child: Padding( - padding: const EdgeInsets.symmetric( + padding: const .symmetric( horizontal: 12, vertical: 8, ), @@ -410,9 +386,7 @@ Widget? addWidget( color: floor == 1 ? theme.colorScheme.surface : theme.dividerColor.withValues(alpha: 0.08), - borderRadius: const BorderRadius.all( - Radius.circular(8), - ), + borderRadius: const .all(.circular(8)), ), width: 70, height: 50, @@ -424,18 +398,11 @@ Widget? addWidget( const SizedBox(width: 10), Expanded( child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: .start, children: [ - if (vote.title case final title?) - Text( - title, - maxLines: 1, - overflow: TextOverflow.ellipsis, - ), + if (vote.title case final title?) Text(title), Text( '${NumUtils.numFormat(vote.joinNum)}人参与', - maxLines: 1, - overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 13, color: theme.colorScheme.outline, @@ -457,14 +424,14 @@ Widget? addWidget( ), style: FilledButton.styleFrom( shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(6)), + borderRadius: .all(.circular(6)), ), - padding: const EdgeInsets.symmetric(horizontal: 10), + padding: const .symmetric(horizontal: 10), visualDensity: const VisualDensity( horizontal: -2, vertical: -3, ), - tapTargetSize: MaterialTapTargetSize.shrinkWrap, + tapTargetSize: .shrinkWrap, ), child: const Text('参与'), ), @@ -481,7 +448,7 @@ Widget? addWidget( ? null : () => PiliScheme.routePushFromUrl(content.jumpUrl!), child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), + padding: const .symmetric(horizontal: 12, vertical: 8), child: Row( children: [ if (content.cover?.isNotEmpty == true) ...[ @@ -489,8 +456,8 @@ Widget? addWidget( width: 45, height: 45, src: content.cover, - borderRadius: const BorderRadius.all( - Radius.circular(6), + borderRadius: const .all( + .circular(6), ), ), const SizedBox(width: 10), @@ -498,8 +465,8 @@ Widget? addWidget( Expanded( child: Column( spacing: 2, - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: .min, + crossAxisAlignment: .start, children: [ if (content.title?.isNotEmpty == true) Text(content.title!), @@ -530,14 +497,14 @@ Widget? addWidget( ), style: FilledButton.styleFrom( shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(6)), + borderRadius: .all(.circular(6)), ), - padding: const EdgeInsets.symmetric(horizontal: 10), + padding: const .symmetric(horizontal: 10), visualDensity: const VisualDensity( horizontal: -2, vertical: -3, ), - tapTargetSize: MaterialTapTargetSize.shrinkWrap, + tapTargetSize: .shrinkWrap, ), child: Text(content.button!.jumpStyle?.text ?? ''), ), @@ -586,7 +553,7 @@ Widget? addWidget( } if (content.matchInfo?.subTitle?.isNotEmpty == true) { title = Column( - mainAxisSize: MainAxisSize.min, + mainAxisSize: .min, children: [ ?title, Text( @@ -605,7 +572,7 @@ Widget? addWidget( ? null : () => PiliScheme.routePushFromUrl(content.jumpUrl!), child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), + padding: const .symmetric(horizontal: 12, vertical: 8), child: Row( children: [ ?title, @@ -620,11 +587,11 @@ Widget? addWidget( if (content.matchInfo?.centerTop?.isNotEmpty == true) Container( height: 35, - alignment: Alignment.center, + alignment: .center, child: Text( content.matchInfo!.centerTop!.join(' '), style: const TextStyle( - fontWeight: FontWeight.bold, + fontWeight: .bold, fontSize: 16, ), ), @@ -651,14 +618,14 @@ Widget? addWidget( PiliScheme.routePushFromUrl(button.jumpUrl!), style: FilledButton.styleFrom( shape: const RoundedRectangleBorder( - borderRadius: BorderRadius.all(Radius.circular(6)), + borderRadius: .all(.circular(6)), ), - padding: const EdgeInsets.symmetric(horizontal: 10), + padding: const .symmetric(horizontal: 10), visualDensity: const VisualDensity( horizontal: -2, vertical: -3, ), - tapTargetSize: MaterialTapTargetSize.shrinkWrap, + tapTargetSize: .shrinkWrap, ), child: Text(button.jumpStyle?.text ?? ''), ), @@ -669,7 +636,7 @@ Widget? addWidget( } if (child != null) { return Padding( - padding: const EdgeInsets.only(top: 6), + padding: const .only(top: 6), child: Material( borderRadius: borderRadius, color: bgColor, @@ -681,7 +648,7 @@ Widget? addWidget( } } catch (e) { return Padding( - padding: const EdgeInsets.all(12), + padding: const .all(12), child: SelectableText( ''' additional panel error diff --git a/lib/pages/dynamics/widgets/live_panel_sub.dart b/lib/pages/dynamics/widgets/live_panel_sub.dart index 26f44f0b2..aa40b2ebe 100644 --- a/lib/pages/dynamics/widgets/live_panel_sub.dart +++ b/lib/pages/dynamics/widgets/live_panel_sub.dart @@ -109,7 +109,7 @@ Widget livePanelSub( if (live.title case final title?) Text( title, - maxLines: isDetail ? null : 1, + maxLines: isDetail ? null : 2, style: const TextStyle(fontWeight: FontWeight.bold), overflow: isDetail ? null : TextOverflow.ellipsis, ), diff --git a/lib/pages/dynamics/widgets/live_rcmd_panel.dart b/lib/pages/dynamics/widgets/live_rcmd_panel.dart index 9c2fd0545..0e5b3289e 100644 --- a/lib/pages/dynamics/widgets/live_rcmd_panel.dart +++ b/lib/pages/dynamics/widgets/live_rcmd_panel.dart @@ -104,7 +104,7 @@ Widget liveRcmdPanel( if (liveRcmd.title case final title?) Text( title, - maxLines: isDetail ? null : 1, + maxLines: isDetail ? null : 2, style: const TextStyle(fontWeight: FontWeight.bold), overflow: isDetail ? null : TextOverflow.ellipsis, ), diff --git a/lib/pages/dynamics/widgets/video_panel.dart b/lib/pages/dynamics/widgets/video_panel.dart index 001e8998f..92106bdbe 100644 --- a/lib/pages/dynamics/widgets/video_panel.dart +++ b/lib/pages/dynamics/widgets/video_panel.dart @@ -138,7 +138,7 @@ Widget videoSeasonWidget( if (video.title case final title?) Text( title, - maxLines: isDetail ? null : 1, + maxLines: isDetail ? null : 2, style: const TextStyle(fontWeight: FontWeight.bold), overflow: isDetail ? null : TextOverflow.ellipsis, ), diff --git a/lib/pages/dynamics_create/view.dart b/lib/pages/dynamics_create/view.dart index bd0693583..99720a38b 100644 --- a/lib/pages/dynamics_create/view.dart +++ b/lib/pages/dynamics_create/view.dart @@ -771,15 +771,17 @@ class _CreateDynPanelState extends CommonRichTextPubPageState { } final reserveCard = _reserveCard.value; + final publishTime = _publishTime.value; + final isPrivate = _isPrivate.value; final res = await DynamicsHttp.createDynamic( mid: Accounts.main.mid, rawText: hasRichText ? null : editController.text, pics: pictures, - publishTime: _publishTime.value != null - ? _publishTime.value!.millisecondsSinceEpoch ~/ 1000 + publishTime: publishTime != null + ? publishTime.millisecondsSinceEpoch ~/ 1000 : null, replyOption: _replyOption.value, - privatePub: _isPrivate.value ? 1 : null, + privatePub: isPrivate ? 1 : null, title: _titleEditCtr.text, topic: _topic.value, extraContent: extraContent, @@ -801,7 +803,7 @@ class _CreateDynPanelState extends CommonRichTextPubPageState { SmartDialog.showToast('发布成功'); final id = response?['dyn_id']; RequestUtils.insertCreatedDyn(id); - if (!_isPrivate.value && _publishTime.value == null) { + if (!isPrivate && publishTime == null) { RequestUtils.checkCreatedDyn( id: id, dynText: editController.rawText, diff --git a/lib/pages/dynamics_tab/controller.dart b/lib/pages/dynamics_tab/controller.dart index e3f6d6b0a..724d188c0 100644 --- a/lib/pages/dynamics_tab/controller.dart +++ b/lib/pages/dynamics_tab/controller.dart @@ -1,3 +1,5 @@ +import 'dart:async' show StreamSubscription; + import 'package:PiliPlus/http/dynamics.dart'; import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/msg.dart'; @@ -20,11 +22,20 @@ class DynamicsTabController int? mid; late final MainController mainController = Get.find(); final dynamicsController = Get.find(); + StreamSubscription? _listener; @override void onInit() { super.onInit(); queryData(); + if (dynamicsType == .up) { + _listener = dynamicsController.mid.listen((mid) { + if (mid != -1) { + this.mid = mid; + onReload(); + } + }); + } } @override @@ -92,4 +103,10 @@ class DynamicsTabController @override void onChangeAccount(bool isLogin) => onReload(); + + @override + void onClose() { + _listener?.cancel(); + super.onClose(); + } } diff --git a/lib/pages/dynamics_tab/view.dart b/lib/pages/dynamics_tab/view.dart index dd78b6f3d..4dcc4f669 100644 --- a/lib/pages/dynamics_tab/view.dart +++ b/lib/pages/dynamics_tab/view.dart @@ -1,5 +1,3 @@ -import 'dart:async'; - import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/http/loading_state.dart'; @@ -27,8 +25,6 @@ class DynamicsTabPage extends StatefulWidget { class _DynamicsTabPageState extends State with AutomaticKeepAliveClientMixin, DynMixin { - StreamSubscription? _listener; - DynamicsController dynamicsController = Get.putOrFind(DynamicsController.new); late final DynamicsTabController controller; @@ -44,21 +40,6 @@ class _DynamicsTabPageState extends State ..mid = dynamicsController.mid.value, tag: widget.dynamicsType.name, ); - if (widget.dynamicsType == .up) { - _listener = dynamicsController.mid.listen((mid) { - if (mid != -1) { - controller - ..mid = mid - ..onReload(); - } - }); - } - } - - @override - void dispose() { - _listener?.cancel(); - super.dispose(); } @override diff --git a/lib/pages/live_room/controller.dart b/lib/pages/live_room/controller.dart index 0fd20432d..c1fdc1e8b 100644 --- a/lib/pages/live_room/controller.dart +++ b/lib/pages/live_room/controller.dart @@ -50,9 +50,7 @@ class LiveRoomController extends GetxController { int roomId = Get.arguments; int? ruid; DanmakuController? danmakuController; - final plPlayerController = PlPlayerController.getInstance( - isLive: true, - ); + final plPlayerController = PlPlayerController.getInstance(isLive: true); final isLoaded = false.obs; final roomInfoH5 = Rxn(); @@ -89,10 +87,7 @@ class LiveRoomController extends GetxController { } return Text( text, - style: const TextStyle( - fontSize: 12, - color: Colors.white, - ), + style: const TextStyle(fontSize: 12, color: Colors.white), ); }); @@ -107,6 +102,7 @@ class LiveRoomController extends GetxController { final disableAutoScroll = false.obs; bool autoScroll = true; LiveMessageStream? _msgStream; + LiveMessageStream? get msgStream => _msgStream; late final ScrollController scrollController; late final RxInt pageIndex = 0.obs; late final PageController pageController; @@ -150,7 +146,7 @@ class LiveRoomController extends GetxController { final account = Accounts.main; isLogin = account.isLogin; mid = account.mid; - queryLiveUrl(autoFullScreenFlag: true); + queryLiveUrl(); queryLiveInfoH5(); if (Accounts.heartbeat.isLogin && !Pref.historyPause) { VideoHttp.roomEntryAction(roomId: roomId); @@ -158,10 +154,7 @@ class LiveRoomController extends GetxController { pageController = PageController(); } - Future? playerInit({ - bool autoplay = true, - bool autoFullScreenFlag = false, - }) { + Future? playerInit({bool autoplay = true}) { if (videoUrl == null) { return null; } @@ -173,7 +166,7 @@ class LiveRoomController extends GetxController { ); } - Future queryLiveUrl({bool autoFullScreenFlag = false}) async { + Future queryLiveUrl() async { currentQn ??= await ConnectivityUtils.isWiFi ? Pref.liveQuality : Pref.liveQualityCellular; @@ -195,7 +188,12 @@ class LiveRoomController extends GetxController { if (response.roomId != null) { roomId = response.roomId!; } - liveTime.value = response.liveTime; + final liveTime = response.liveTime; + if (liveTime != null && + DateTime.now().millisecondsSinceEpoch ~/ 1000 - liveTime < + Duration.secondsPerDay * 2) { + this.liveTime.value = liveTime; + } startLiveTimer(); isPortrait.value = response.isPortrait ?? false; List codec = @@ -212,7 +210,7 @@ class LiveRoomController extends GetxController { currentQnDesc.value = LiveQuality.fromCode(currentQn)?.desc ?? currentQn.toString(); videoUrl = VideoUtils.getLiveCdnUrl(item); - await playerInit(autoFullScreenFlag: autoFullScreenFlag); + await playerInit(); isLoaded.value = true; } else { _showDialog(res.toString()); @@ -323,10 +321,6 @@ class LiveRoomController extends GetxController { } } - void clearSC() { - superChatMsg.removeWhere((e) => e.expired); - } - void startLiveMsg() { if (messages.isEmpty) { prefetch(); @@ -530,7 +524,7 @@ class LiveRoomController extends GetxController { void onLikeTapDown([_]) { cancelLikeTimer(); - likeClickTime.value++; + likeClickTime.value += 2; } void onLikeTapUp([_]) { @@ -568,19 +562,22 @@ class LiveRoomController extends GetxController { PublishRoute( barrierColor: Colors.transparent, pageBuilder: (context, animation, secondaryAnimation) { - return LiveSendDmPanel( - fromEmote: fromEmote, - liveRoomController: this, - items: savedDanmaku, - autofocus: !fromEmote, - onSave: (msg) { - if (msg.isEmpty) { - savedDanmaku?.clear(); - savedDanmaku = null; - } else { - savedDanmaku = msg.toList(); - } - }, + return Theme( + data: ThemeUtils.darkTheme, + child: LiveSendDmPanel( + fromEmote: fromEmote, + liveRoomController: this, + items: savedDanmaku, + autofocus: !fromEmote, + onSave: (msg) { + if (msg.isEmpty) { + savedDanmaku?.clear(); + savedDanmaku = null; + } else { + savedDanmaku = msg.toList(); + } + }, + ), ); }, transitionDuration: fromEmote diff --git a/lib/pages/live_room/view.dart b/lib/pages/live_room/view.dart index 238145f77..914ef0fb3 100644 --- a/lib/pages/live_room/view.dart +++ b/lib/pages/live_room/view.dart @@ -44,6 +44,7 @@ import 'package:PiliPlus/utils/platform_utils.dart'; import 'package:PiliPlus/utils/share_utils.dart'; import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/storage_key.dart'; +import 'package:PiliPlus/utils/theme_utils.dart'; import 'package:PiliPlus/utils/utils.dart'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:canvas_danmaku/canvas_danmaku.dart'; @@ -53,6 +54,8 @@ import 'package:flutter/material.dart' hide PageView; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:get/get.dart'; +const baseWhite = Color(0xFFEEEEEE); + class LiveRoomPage extends StatefulWidget { const LiveRoomPage({super.key}); @@ -66,6 +69,7 @@ class _LiveRoomPageState extends State late final LiveRoomController _liveRoomController; late final PlPlayerController plPlayerController; bool get isFullScreen => plPlayerController.isFullScreen.value; + final colorScheme = ThemeUtils.darkTheme.colorScheme; late final GlobalKey pageKey = GlobalKey(); late final GlobalKey chatKey = GlobalKey(); @@ -212,7 +216,7 @@ class _LiveRoomPageState extends State child: child, ); } - return child; + return Theme(data: ThemeUtils.darkTheme, child: child); } Widget videoPlayerPanel( @@ -518,28 +522,24 @@ class _LiveRoomPageState extends State } PreferredSizeWidget _buildAppBar(bool isFullScreen) { - final color = Theme.of(context).colorScheme.onSurfaceVariant; return AppBar( toolbarHeight: isFullScreen ? 0 : null, backgroundColor: Colors.transparent, - foregroundColor: Colors.white, - titleTextStyle: const TextStyle(color: Colors.white), title: isFullScreen || plPlayerController.isDesktopPip ? null : Obx( () { - RoomInfoH5Data? roomInfoH5 = - _liveRoomController.roomInfoH5.value; + final roomInfoH5 = _liveRoomController.roomInfoH5.value; if (roomInfoH5 == null) { return const SizedBox.shrink(); } return GestureDetector( - behavior: HitTestBehavior.opaque, + behavior: .opaque, onTap: () => Get.toNamed('/member?mid=${roomInfoH5.roomInfo?.uid}'), child: Row( spacing: 10, - mainAxisSize: MainAxisSize.min, + mainAxisSize: .min, children: [ NetworkImgLayer( width: 34, @@ -550,12 +550,12 @@ class _LiveRoomPageState extends State Flexible( child: Column( spacing: 1, - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: .start, children: [ Row( spacing: 10, mainAxisSize: .min, - crossAxisAlignment: CrossAxisAlignment.end, + crossAxisAlignment: .end, children: [ Flexible( child: Text( @@ -586,11 +586,6 @@ class _LiveRoomPageState extends State }, ), actions: [ - // IconButton( - // tooltip: '刷新', - // onPressed: _liveRoomController.queryLiveUrl, - // icon: const Icon(Icons.refresh, size: 20), - // ), PopupMenuButton( icon: const Icon(Icons.more_vert, size: 20), itemBuilder: (BuildContext context) { @@ -599,32 +594,24 @@ class _LiveRoomPageState extends State return [ PopupMenuItem( onTap: () => Utils.copyText(liveUrl), - child: Row( + child: const Row( spacing: 10, - mainAxisSize: MainAxisSize.min, + mainAxisSize: .min, children: [ - Icon( - Icons.copy, - size: 19, - color: color, - ), - const Text('复制链接'), + Icon(Icons.copy, size: 19), + Text('复制链接'), ], ), ), if (PlatformUtils.isMobile) PopupMenuItem( onTap: () => ShareUtils.shareText(liveUrl), - child: Row( + child: const Row( spacing: 10, - mainAxisSize: MainAxisSize.min, + mainAxisSize: .min, children: [ - Icon( - Icons.share, - size: 19, - color: color, - ), - const Text('分享直播间'), + Icon(Icons.share, size: 19), + Text('分享直播间'), ], ), ), @@ -651,16 +638,12 @@ class _LiveRoomPageState extends State SmartDialog.showToast(e.toString()); } }, - child: Row( + child: const Row( spacing: 10, - mainAxisSize: MainAxisSize.min, + mainAxisSize: .min, children: [ - Icon( - Icons.forward_to_inbox, - size: 19, - color: color, - ), - const Text('分享至消息'), + Icon(Icons.forward_to_inbox, size: 19), + Text('分享至消息'), ], ), ), @@ -683,14 +666,14 @@ class _LiveRoomPageState extends State : videoHeight; return Padding( padding: isFullScreen - ? EdgeInsets.zero - : EdgeInsets.only(left: padding.left, right: padding.right), + ? .zero + : .only(left: padding.left, right: padding.right), child: Row( children: [ Container( width: width, height: height, - margin: EdgeInsets.only(bottom: padding.bottom), + margin: .only(bottom: padding.bottom), child: videoPlayerPanel( isFullScreen, fill: Colors.transparent, @@ -712,7 +695,7 @@ class _LiveRoomPageState extends State } Widget get _buildBottomWidget => Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: .start, children: [ Expanded(child: _buildChatWidget()), _buildInputWidget, @@ -737,7 +720,7 @@ class _LiveRoomPageState extends State ..onSendDanmaku(), ); return Padding( - padding: EdgeInsets.only(bottom: 12, top: isPortrait ? 12 : 0), + padding: .only(bottom: 12, top: isPortrait ? 12 : 0), child: PageView( key: pageKey, controller: _liveRoomController.pageController, @@ -758,7 +741,7 @@ class _LiveRoomPageState extends State Widget get _buildInputWidget { final child = Container( - padding: EdgeInsets.only( + padding: .only( top: 5, left: 10, right: 10, @@ -766,15 +749,15 @@ class _LiveRoomPageState extends State ), height: 70 + padding.bottom, decoration: const BoxDecoration( - borderRadius: BorderRadius.vertical(top: Radius.circular(20)), + borderRadius: .vertical(top: .circular(20)), border: Border(top: BorderSide(color: Color(0x1AFFFFFF))), color: Color(0x1AFFFFFF), ), child: GestureDetector( onTap: _liveRoomController.onSendDanmaku, - behavior: HitTestBehavior.opaque, + behavior: .opaque, child: Padding( - padding: const EdgeInsets.only(top: 5, bottom: 10), + padding: const .only(top: 5, bottom: 10), child: Align( alignment: Alignment.topCenter, child: Row( @@ -788,8 +771,8 @@ class _LiveRoomPageState extends State width: 34, height: 34, child: IconButton( - style: IconButton.styleFrom( - padding: EdgeInsets.zero, + style: const ButtonStyle( + padding: WidgetStatePropertyAll(.zero), ), onPressed: () { final newVal = !enableShowLiveDanmaku; @@ -803,80 +786,74 @@ class _LiveRoomPageState extends State ? const Icon( size: 22, CustomIcons.dm_on, - color: Color(0xFFEEEEEE), + color: baseWhite, ) : const Icon( size: 22, CustomIcons.dm_off, - color: Color(0xFFEEEEEE), + color: baseWhite, ), ), ); }, ), const Expanded( - child: Text( - '发送弹幕', - style: TextStyle(color: Color(0xFFEEEEEE)), - ), + child: Text('发送弹幕', style: TextStyle(color: baseWhite)), ), - Builder( - builder: (context) { - final colorScheme = Theme.of(context).colorScheme; - return Material( - type: MaterialType.transparency, - child: Stack( - clipBehavior: Clip.none, - children: [ - InkWell( - overlayColor: overlayColor(colorScheme), - customBorder: const CircleBorder(), - onTapDown: _liveRoomController.onLikeTapDown, - onTapUp: _liveRoomController.onLikeTapUp, - onTapCancel: _liveRoomController.onLikeTapUp, - child: const SizedBox.square( - dimension: 34, - child: Icon( - size: 22, - color: Color(0xFFEEEEEE), - Icons.thumb_up_off_alt, - ), - ), + Material( + type: .transparency, + child: Stack( + clipBehavior: .none, + children: [ + InkWell( + overlayColor: overlayColor(colorScheme), + customBorder: const CircleBorder(), + onTapDown: _liveRoomController.onLikeTapDown, + onTapUp: _liveRoomController.onLikeTapUp, + onTapCancel: _liveRoomController.onLikeTapUp, + child: const SizedBox.square( + dimension: 34, + child: Icon( + size: 22, + color: baseWhite, + Icons.thumb_up_off_alt, ), - Positioned( - left: 30, - top: -12, - child: Obx(() { - final likeClickTime = - _liveRoomController.likeClickTime.value; - if (likeClickTime == 0) { - return const SizedBox.shrink(); - } - return Text( - 'x$likeClickTime', - style: TextStyle( - fontSize: 16, - color: colorScheme.isDark - ? colorScheme.primary - : colorScheme.inversePrimary, - ), - ); - }), - ), - ], + ), ), - ); - }, + Positioned( + left: 30, + top: -12, + child: Obx(() { + final likeClickTime = + _liveRoomController.likeClickTime.value; + if (likeClickTime == 0) { + return const SizedBox.shrink(); + } + return Text( + 'x$likeClickTime', + style: TextStyle( + fontSize: 16, + color: colorScheme.isDark + ? colorScheme.primary + : colorScheme.inversePrimary, + ), + ); + }), + ), + ], + ), ), SizedBox( width: 34, height: 34, child: IconButton( - style: IconButton.styleFrom(padding: EdgeInsets.zero), + style: const ButtonStyle( + padding: WidgetStatePropertyAll(.zero), + ), onPressed: () => _liveRoomController.onSendDanmaku(true), icon: const Icon( size: 22, - color: Color(0xFFEEEEEE), + color: baseWhite, Icons.emoji_emotions_outlined, ), ), @@ -888,6 +865,7 @@ class _LiveRoomPageState extends State ), ); return Stack( + clipBehavior: .none, children: [ child, Positioned( @@ -896,11 +874,21 @@ class _LiveRoomPageState extends State right: 0, child: Obx( () => _BorderIndicator( - radius: const Radius.circular(20), + radius: const .circular(20), isLeft: _liveRoomController.pageIndex.value == 0, ), ), ), + Positioned( + top: -6, + right: 6, + child: Obx( + () => Badge.count( + isLabelVisible: _liveRoomController.superChatMsg.isNotEmpty, + count: _liveRoomController.superChatMsg.length, + ), + ), + ), ], ); } @@ -1001,7 +989,7 @@ class _RenderBorderIndicator extends RenderBox { width, size.height, ), - borderRadius: BorderRadius.only( + borderRadius: .only( topLeft: _isLeft ? _radius : .zero, topRight: _isLeft ? .zero : _radius, ), diff --git a/lib/pages/live_room/widgets/chat_panel.dart b/lib/pages/live_room/widgets/chat_panel.dart index 80d1a1ea7..9a0a41428 100644 --- a/lib/pages/live_room/widgets/chat_panel.dart +++ b/lib/pages/live_room/widgets/chat_panel.dart @@ -164,53 +164,6 @@ class LiveRoomChatPanel extends StatelessWidget { ), ), ], - Positioned( - top: 12, - right: 12, - child: Obx(() { - final isEmpty = liveRoomController.superChatMsg.isEmpty; - return AnimatedOpacity( - opacity: isEmpty ? 0 : 1, - duration: const Duration(milliseconds: 120), - child: GestureDetector( - onTap: isEmpty - ? null - : () => liveRoomController.pageController.animateToPage( - 1, - duration: const Duration(milliseconds: 200), - curve: Curves.easeInOut, - ), - child: Container( - decoration: BoxDecoration( - borderRadius: const BorderRadius.all(Radius.circular(8)), - color: const Color(0x2FFFFFFF), - border: Border.all(color: Colors.white24, width: 0.7), - ), - padding: const EdgeInsets.fromLTRB(10, 4, 4, 4), - child: Text.rich( - style: const TextStyle(color: Colors.white, height: 1), - strutStyle: const StrutStyle(height: 1, leading: 0), - TextSpan( - children: [ - TextSpan( - text: 'SC(${liveRoomController.superChatMsg.length})', - ), - const WidgetSpan( - alignment: PlaceholderAlignment.middle, - child: Icon( - size: 18, - Icons.keyboard_arrow_right, - color: Colors.white, - ), - ), - ], - ), - ), - ), - ), - ); - }), - ), Obx( () => liveRoomController.disableAutoScroll.value ? Positioned( @@ -225,6 +178,38 @@ class LiveRoomChatPanel extends StatelessWidget { ) : const SizedBox.shrink(), ), + Positioned( + top: 0, + right: 12, + width: 32, + height: 32, + child: PopupMenuButton( + iconSize: 19, + padding: .zero, + itemBuilder: (context) => [ + if (liveRoomController.msgStream != null) + PopupMenuItem( + height: 35, + onTap: liveRoomController.closeLiveMsg, + child: const Text('Pause'), + ) + else + PopupMenuItem( + height: 35, + onTap: liveRoomController.startLiveMsg, + child: const Text('Resume'), + ), + PopupMenuItem( + height: 35, + onTap: () => liveRoomController + ..danmakuController?.clear() + ..messages.clear() + ..disableAutoScroll.value = false, + child: const Text('Clear'), + ), + ], + ), + ), ], ); } @@ -274,10 +259,7 @@ class LiveRoomChatPanel extends StatelessWidget { spanChildren.add( TextSpan( text: nonMatchStr, - style: const TextStyle( - color: Colors.white, - fontSize: 14, - ), + style: const TextStyle(color: Colors.white, fontSize: 14), ), ); return ''; @@ -287,10 +269,7 @@ class LiveRoomChatPanel extends StatelessWidget { } else { return TextSpan( text: obj.text, - style: const TextStyle( - color: Colors.white, - fontSize: 14, - ), + style: const TextStyle(color: Colors.white, fontSize: 14), ); } } diff --git a/lib/pages/video/controller.dart b/lib/pages/video/controller.dart index 1bf79915a..3b248cc38 100644 --- a/lib/pages/video/controller.dart +++ b/lib/pages/video/controller.dart @@ -669,11 +669,9 @@ class VideoDetailController extends GetxController playerInit(); } - Future? _initPlayerIfNeeded(bool autoFullScreenFlag) { + Future? _initPlayerIfNeeded() { if (_autoPlay.value) { - return playerInit( - autoFullScreenFlag: autoFullScreenFlag && _autoPlay.value, - ); + return playerInit(); } return null; } @@ -685,7 +683,6 @@ class VideoDetailController extends GetxController Duration? duration, bool? autoplay, Volume? volume, - bool autoFullScreenFlag = false, }) async { Duration? seek = seekToTime ?? defaultST ?? playedTime; if (seek == null || seek == Duration.zero) { @@ -762,10 +759,9 @@ class VideoDetailController extends GetxController Future queryVideoUrl({ Duration? defaultST, bool fromReset = false, - bool autoFullScreenFlag = false, }) async { if (isFileSource) { - return _initPlayerIfNeeded(autoFullScreenFlag); + return _initPlayerIfNeeded(); } if (isQuerying) { return; @@ -839,7 +835,7 @@ class VideoDetailController extends GetxController _setVideoHeight(); currentDecodeFormats = VideoDecodeFormatType.fromString('avc1'); currentVideoQa.value = videoQuality; - await _initPlayerIfNeeded(autoFullScreenFlag); + await _initPlayerIfNeeded(); isQuerying = false; return; } @@ -938,7 +934,7 @@ class VideoDetailController extends GetxController } else { audioUrl = ''; } - await _initPlayerIfNeeded(autoFullScreenFlag); + await _initPlayerIfNeeded(); } else { _autoPlay.value = false; videoState.value = false; diff --git a/lib/pages/video/view.dart b/lib/pages/video/view.dart index 38da7e398..44b671e77 100644 --- a/lib/pages/video/view.dart +++ b/lib/pages/video/view.dart @@ -153,7 +153,7 @@ class _VideoDetailPageVState extends State // 获取视频资源,初始化播放器 void videoSourceInit() { - videoDetailController.queryVideoUrl(autoFullScreenFlag: true); + videoDetailController.queryVideoUrl(); if (videoDetailController.autoPlay) { plPlayerController = videoDetailController.plPlayerController; plPlayerController! @@ -284,10 +284,7 @@ class _VideoDetailPageVState extends State plPlayerController ..addStatusLister(playerListener) ..addPositionListener(positionListener); - return videoDetailController.playerInit( - autoplay: true, - autoFullScreenFlag: true, - ); + return videoDetailController.playerInit(autoplay: true); } @override diff --git a/lib/utils/global_data.dart b/lib/utils/global_data.dart index a0e154701..c4652d4c4 100644 --- a/lib/utils/global_data.dart +++ b/lib/utils/global_data.dart @@ -1,13 +1,18 @@ +import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/storage_pref.dart'; abstract final class GlobalData { static int imgQuality = Pref.picQuality; - static num? coins; + static double? coins; static void afterCoin(num coin) { if (coins != null) { coins = coins! - coin; + GStorage.userInfo.put( + 'userInfoCache', + Pref.userInfoCache!..money = coins, + ); } }