diff --git a/lib/common/widgets/flutter/tabs.dart b/lib/common/widgets/flutter/tabs.dart index 1a9dc0152..cf3807362 100644 --- a/lib/common/widgets/flutter/tabs.dart +++ b/lib/common/widgets/flutter/tabs.dart @@ -4,11 +4,9 @@ import 'dart:ui' show SemanticsRole; -import 'package:PiliPlus/common/widgets/flutter/page/page_view.dart'; -import 'package:PiliPlus/common/widgets/gesture/horizontal_drag_gesture_recognizer.dart'; import 'package:flutter/foundation.dart' show clampDouble; import 'package:flutter/gestures.dart' show DragStartBehavior; -import 'package:flutter/material.dart' hide TabBarView, PageView; +import 'package:flutter/material.dart' hide TabBarView; /// A page view that displays the widget which corresponds to the currently /// selected tab. @@ -357,7 +355,7 @@ class _CustomTabBarViewState extends State { return NotificationListener( onNotification: _handleScrollNotification, - child: PageView( + child: PageView( scrollDirection: widget.scrollDirection, dragStartBehavior: widget.dragStartBehavior, clipBehavior: widget.clipBehavior, @@ -365,8 +363,6 @@ class _CustomTabBarViewState extends State { physics: widget.physics == null ? const PageScrollPhysics().applyTo(const ClampingScrollPhysics()) : const PageScrollPhysics().applyTo(widget.physics), - horizontalDragGestureRecognizer: - CustomHorizontalDragGestureRecognizer(), children: _childrenWithKey, ), ); diff --git a/lib/common/widgets/gesture/horizontal_drag_gesture_recognizer.dart b/lib/common/widgets/gesture/horizontal_drag_gesture_recognizer.dart index 49a2b7680..589c08cc3 100644 --- a/lib/common/widgets/gesture/horizontal_drag_gesture_recognizer.dart +++ b/lib/common/widgets/gesture/horizontal_drag_gesture_recognizer.dart @@ -26,7 +26,7 @@ class CustomHorizontalDragGestureRecognizer globalDistanceMoved.abs(), gestureSettings, pointerDeviceKind, - _initialPosition!, + _initialPosition, lastPosition.global, ); } @@ -38,7 +38,7 @@ bool _computeHitSlop( double globalDistanceMoved, DeviceGestureSettings? settings, PointerDeviceKind kind, - Offset initialPosition, + Offset? initialPosition, Offset lastPosition, ) { switch (kind) { @@ -49,13 +49,13 @@ bool _computeHitSlop( case PointerDeviceKind.unknown: case PointerDeviceKind.touch: return globalDistanceMoved > touchSlopH && - _cacl(initialPosition, lastPosition); + _calc(initialPosition!, lastPosition); case PointerDeviceKind.trackpad: return globalDistanceMoved > (settings?.touchSlop ?? kTouchSlop); } } -bool _cacl(Offset initialPosition, Offset lastPosition) { +bool _calc(Offset initialPosition, Offset lastPosition) { final offset = lastPosition - initialPosition; return offset.dx.abs() > offset.dy.abs() * 3; } diff --git a/lib/common/widgets/image/custom_grid_view.dart b/lib/common/widgets/image/custom_grid_view.dart index 736a1a669..548f03516 100644 --- a/lib/common/widgets/image/custom_grid_view.dart +++ b/lib/common/widgets/image/custom_grid_view.dart @@ -121,7 +121,7 @@ class CustomGridView extends StatelessWidget { ); } - static BorderRadius borderRadius( + static BorderRadius _borderRadius( int col, int length, int index, { @@ -255,7 +255,7 @@ class CustomGridView extends StatelessWidget { height: imageHeight, children: List.generate(length, (index) { final item = picArr[index]; - final radius = borderRadius(column, length, index); + final borderRadius = _borderRadius(column, length, index); return LayoutId( id: index, child: GestureDetector( @@ -274,17 +274,14 @@ class CustomGridView extends StatelessWidget { clipBehavior: Clip.none, alignment: Alignment.center, children: [ - ClipRRect( - borderRadius: radius, - child: NetworkImgLayer( - type: .emote, - src: item.url, - width: imageWidth, - height: imageHeight, - alignment: item.isLongPic ? .topCenter : .center, - cacheWidth: item.width <= item.height, - getPlaceHolder: () => placeHolder, - ), + NetworkImgLayer( + src: item.url, + width: imageWidth, + height: imageHeight, + borderRadius: borderRadius, + alignment: item.isLongPic ? .topCenter : .center, + cacheWidth: item.width <= item.height, + getPlaceHolder: () => placeHolder, ), if (item.isLivePhoto) const PBadge( diff --git a/lib/models_new/download/bili_download_entry_info.dart b/lib/models_new/download/bili_download_entry_info.dart index 8de884abe..9d56e1a23 100644 --- a/lib/models_new/download/bili_download_entry_info.dart +++ b/lib/models_new/download/bili_download_entry_info.dart @@ -239,6 +239,8 @@ class PageInfo { final String? downloadTitle; final String? downloadSubtitle; + bool get cacheWidth => width <= height; + PageInfo({ required this.cid, required this.page, diff --git a/lib/models_new/later/list.dart b/lib/models_new/later/list.dart index a2739f6f3..088a299cf 100644 --- a/lib/models_new/later/list.dart +++ b/lib/models_new/later/list.dart @@ -3,6 +3,7 @@ import 'package:PiliPlus/models_new/later/bangumi.dart'; import 'package:PiliPlus/models_new/later/page.dart'; import 'package:PiliPlus/models_new/later/rights.dart'; import 'package:PiliPlus/models_new/later/stat.dart'; +import 'package:PiliPlus/models_new/video/video_detail/dimension.dart'; import 'package:PiliPlus/pages/common/multi_select/base.dart'; class LaterItemModel with MultiSelectData { @@ -27,6 +28,7 @@ class LaterItemModel with MultiSelectData { bool? isPugv; int? seasonId; bool? isCharging; + Dimension? dimension; LaterItemModel({ this.aid, @@ -50,6 +52,7 @@ class LaterItemModel with MultiSelectData { this.isPugv, this.seasonId, this.isCharging, + this.dimension, }); factory LaterItemModel.fromJson(Map json) => LaterItemModel( @@ -89,5 +92,8 @@ class LaterItemModel with MultiSelectData { isPugv: json['is_pugv'] as bool?, seasonId: json['season_id'] as int?, isCharging: json['charging_pay']?['level'] != null, + dimension: json['dimension'] == null + ? null + : Dimension.fromJson(json['dimension'] as Map), ); } diff --git a/lib/models_new/video/video_detail/dimension.dart b/lib/models_new/video/video_detail/dimension.dart index a60d8c800..5f83c037e 100644 --- a/lib/models_new/video/video_detail/dimension.dart +++ b/lib/models_new/video/video_detail/dimension.dart @@ -2,6 +2,13 @@ class Dimension { int? width; int? height; + bool? get cacheWidth { + if (width != null && height != null) { + return width! <= height!; + } + return null; + } + Dimension({this.width, this.height}); factory Dimension.fromJson(Map json) => Dimension( diff --git a/lib/pages/download/detail/widgets/item.dart b/lib/pages/download/detail/widgets/item.dart index 4cbdf36fb..1b8006830 100644 --- a/lib/pages/download/detail/widgets/item.dart +++ b/lib/pages/download/detail/widgets/item.dart @@ -175,17 +175,24 @@ class DetailItem extends StatelessWidget { final cover = File( path.join(entry.entryDirPath, PathUtils.coverName), ); + final maxWidth = constraints.maxWidth; + final maxHeight = constraints.maxHeight; + int? cacheWidth, cacheHeight; + if (entry.pageData?.cacheWidth ?? false) { + cacheWidth = maxWidth.cacheSize(context); + } else { + cacheHeight = maxHeight.cacheSize(context); + } return cover.existsSync() ? ClipRRect( borderRadius: StyleString.mdRadius, child: Image.file( cover, - width: constraints.maxWidth, - height: constraints.maxHeight, + width: maxWidth, + height: maxHeight, fit: BoxFit.cover, - cacheHeight: constraints.maxWidth.cacheSize( - context, - ), + cacheWidth: cacheWidth, + cacheHeight: cacheHeight, colorBlendMode: NetworkImgLayer.reduce ? BlendMode.modulate : null, @@ -196,8 +203,9 @@ class DetailItem extends StatelessWidget { ) : NetworkImgLayer( src: entry.cover, - width: constraints.maxWidth, - height: constraints.maxHeight, + width: maxWidth, + height: maxHeight, + cacheWidth: entry.pageData?.cacheWidth, ); }, ), diff --git a/lib/pages/episode_panel/view.dart b/lib/pages/episode_panel/view.dart index 8bb88e3c8..37c850ca4 100644 --- a/lib/pages/episode_panel/view.dart +++ b/lib/pages/episode_panel/view.dart @@ -377,6 +377,7 @@ class _EpisodePanelState extends State int? view; int? danmaku; bool? isCharging; + bool? cacheWidth; switch (episode) { case Part part: @@ -384,15 +385,21 @@ class _EpisodePanelState extends State title = part.part!; duration = part.duration; pubdate = part.ctime; + cacheWidth = part.dimension?.cacheWidth; break; case ugc.EpisodeItem item: title = item.title!; - cover = item.arc?.pic; bvid = item.bvid; - duration = item.arc?.duration; - pubdate = item.arc?.pubdate; - view = item.arc?.stat?.view; - danmaku = item.arc?.stat?.danmaku; + if (item.arc case final arc?) { + cover = arc.pic; + duration = arc.duration; + pubdate = arc.pubdate; + if (arc.stat case final stat?) { + view = stat.view; + danmaku = stat.danmaku; + } + cacheWidth = arc.dimension?.cacheWidth; + } if (item.attribute == 8) { isCharging = true; } @@ -408,6 +415,7 @@ class _EpisodePanelState extends State duration = item.duration == null ? null : item.duration! ~/ 1000; } pubdate = item.pubTime; + cacheWidth = item.dimension?.cacheWidth; break; } late final Color primary = theme.colorScheme.primary; @@ -468,6 +476,7 @@ class _EpisodePanelState extends State src: cover, width: 140.8, height: 88, + cacheWidth: cacheWidth, ), if (duration != null && duration > 0) PBadge( diff --git a/lib/pages/later/view.dart b/lib/pages/later/view.dart index 6df9b1f48..05c4add0b 100644 --- a/lib/pages/later/view.dart +++ b/lib/pages/later/view.dart @@ -37,9 +37,9 @@ class _LaterPageState extends State ); } - final sortKey = GlobalKey(); + final _sortKey = GlobalKey(); void listener() { - (sortKey.currentContext as Element?)?.markNeedsBuild(); + (_sortKey.currentContext as Element?)?.markNeedsBuild(); } @override @@ -77,9 +77,7 @@ class _LaterPageState extends State appBar: _buildAppbar(enableMultiSelect), floatingActionButtonLocation: const CustomFabLocation(), floatingActionButton: Padding( - padding: const EdgeInsets.only( - right: kFloatingActionButtonMargin, - ), + padding: const .only(right: kFloatingActionButtonMargin), child: Obx( () => currCtr().loadingState.value.isSuccess ? AnimatedSlide( @@ -126,10 +124,8 @@ class _LaterPageState extends State onTap: (_) { if (!_tabController.indexIsChanging) { currCtr().scrollController.animToTop(); - } else { - if (enableMultiSelect) { - currCtr(_tabController.previousIndex).handleSelect(); - } + } else if (enableMultiSelect) { + currCtr(_tabController.previousIndex).handleSelect(); } }, ), @@ -164,9 +160,7 @@ class _LaterPageState extends State ctr: currCtr(), actions: [ TextButton( - style: TextButton.styleFrom( - visualDensity: VisualDensity.compact, - ), + style: TextButton.styleFrom(visualDensity: .compact), onPressed: () { final ctr = currCtr(); RequestUtils.onCopyOrMove( @@ -179,15 +173,11 @@ class _LaterPageState extends State }, child: Text( '复制', - style: TextStyle( - color: theme.colorScheme.onSurfaceVariant, - ), + style: TextStyle(color: theme.colorScheme.onSurfaceVariant), ), ), TextButton( - style: TextButton.styleFrom( - visualDensity: VisualDensity.compact, - ), + style: TextButton.styleFrom(visualDensity: .compact), onPressed: () { final ctr = currCtr(); RequestUtils.onCopyOrMove( @@ -200,9 +190,7 @@ class _LaterPageState extends State }, child: Text( '移动', - style: TextStyle( - color: theme.colorScheme.onSurfaceVariant, - ), + style: TextStyle(color: theme.colorScheme.onSurfaceVariant), ), ), ], @@ -226,113 +214,97 @@ class _LaterPageState extends State }, icon: const Icon(Icons.search), ), - Material( - clipBehavior: Clip.hardEdge, - type: MaterialType.transparency, - borderRadius: const BorderRadius.all(Radius.circular(20)), - child: Builder( - key: sortKey, - builder: (context) { - final value = currCtr().asc.value; - return PopupMenuButton( - initialValue: value, - tooltip: '排序', - onSelected: (value) { - currCtr() - ..asc.value = value - ..onReload(); - }, - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 12, - vertical: 6, + Builder( + key: _sortKey, + builder: (context) { + final value = currCtr().asc.value; + return PopupMenuButton( + initialValue: value, + tooltip: '排序', + onSelected: (value) => currCtr() + ..asc.value = value + ..onReload(), + borderRadius: const .all(.circular(20)), + child: Padding( + padding: const .symmetric(horizontal: 12, vertical: 6), + child: Text.rich( + style: TextStyle(fontSize: 14, height: 1, color: color), + strutStyle: const StrutStyle( + leading: 0, + height: 1, + fontSize: 14, ), - child: Text.rich( - style: TextStyle(fontSize: 14, height: 1, color: color), - strutStyle: const StrutStyle( - leading: 0, - height: 1, - fontSize: 14, - ), - TextSpan( - children: [ - TextSpan(text: value ? '最早添加' : '最近添加'), - WidgetSpan( - alignment: .middle, - child: Icon( - size: 14, - MdiIcons.unfoldMoreHorizontal, - color: color, - ), + TextSpan( + children: [ + TextSpan(text: value ? '最早添加' : '最近添加'), + WidgetSpan( + alignment: .middle, + child: Icon( + size: 14, + MdiIcons.unfoldMoreHorizontal, + color: color, ), - ], - style: TextStyle(color: color), - ), + ), + ], + style: TextStyle(color: color), ), ), - itemBuilder: (BuildContext context) => [ - const PopupMenuItem( - value: false, - child: Text('最近添加'), - ), - const PopupMenuItem( - value: true, - child: Text('最早添加'), + ), + itemBuilder: (_) => [ + const PopupMenuItem( + value: false, + child: Text('最近添加'), + ), + const PopupMenuItem( + value: true, + child: Text('最早添加'), + ), + ], + ); + }, + ), + PopupMenuButton( + tooltip: '清空', + borderRadius: const .all(.circular(20)), + child: Padding( + padding: const .symmetric(horizontal: 12, vertical: 6), + child: Text.rich( + style: TextStyle(fontSize: 14, height: 1, color: color), + strutStyle: const StrutStyle( + leading: 0, + height: 1, + fontSize: 14, + ), + TextSpan( + children: [ + const TextSpan(text: '清空'), + WidgetSpan( + alignment: .middle, + child: Icon( + size: 14, + MdiIcons.unfoldMoreHorizontal, + color: color, + ), ), ], - ); - }, - ), - ), - Material( - clipBehavior: Clip.hardEdge, - type: MaterialType.transparency, - borderRadius: const BorderRadius.all(Radius.circular(20)), - child: PopupMenuButton( - tooltip: '清空', - child: Padding( - padding: const EdgeInsets.symmetric( - horizontal: 12, - vertical: 6, - ), - child: Text.rich( - style: TextStyle(fontSize: 14, height: 1, color: color), - strutStyle: const StrutStyle( - leading: 0, - height: 1, - fontSize: 14, - ), - TextSpan( - children: [ - const TextSpan(text: '清空'), - WidgetSpan( - alignment: .middle, - child: Icon( - size: 14, - MdiIcons.unfoldMoreHorizontal, - color: color, - ), - ), - ], - style: TextStyle(color: color), - ), + style: TextStyle(color: color), ), ), - itemBuilder: (BuildContext context) => [ - PopupMenuItem( - onTap: () => currCtr().toViewClear(context, 1), - child: const Text('清空失效'), - ), - PopupMenuItem( - onTap: () => currCtr().toViewClear(context, 2), - child: const Text('清空看完'), - ), - PopupMenuItem( - onTap: () => currCtr().toViewClear(context), - child: const Text('清空全部'), - ), - ], ), + itemBuilder: (_) => [ + PopupMenuItem( + onTap: () => currCtr().toViewClear(context, 1), + child: const Text('清空失效'), + ), + PopupMenuItem( + onTap: () => currCtr().toViewClear(context, 2), + child: const Text('清空看完'), + ), + PopupMenuItem( + onTap: () => currCtr().toViewClear(context), + child: const Text('清空全部'), + ), + ], ), const SizedBox(width: 8), ], diff --git a/lib/pages/later/widgets/video_card_h_later.dart b/lib/pages/later/widgets/video_card_h_later.dart index 91e256092..1beedce04 100644 --- a/lib/pages/later/widgets/video_card_h_later.dart +++ b/lib/pages/later/widgets/video_card_h_later.dart @@ -97,6 +97,7 @@ class VideoCardHLater extends StatelessWidget { src: videoItem.pic, width: maxWidth, height: maxHeight, + cacheWidth: videoItem.dimension?.cacheWidth, ), if (videoItem.isCharging == true) const PBadge( diff --git a/lib/pages/live/controller.dart b/lib/pages/live/controller.dart index 287d7831b..0e470cbfd 100644 --- a/lib/pages/live/controller.dart +++ b/lib/pages/live/controller.dart @@ -48,17 +48,17 @@ class LiveController extends CommonListController with AccountMixin { bool customHandleResponse(bool isRefresh, Success response) { if (isRefresh) { final res = response.response; - if (res case final LiveIndexData data) { - if (data.hasMore == 0) { + if (res is LiveIndexData) { + if (res.hasMore == 0) { isEnd = true; } topState.value = Pair( - first: data.followItem, - second: data.areaItem, + first: res.followItem, + second: res.areaItem, ); - } else if (res case final LiveSecondData data) { - count = data.count; - newTags = data.newTags; + } else if (res is LiveSecondData) { + count = res.count; + newTags = res.newTags; if (sortType != null) { tagIndex.value = newTags?.indexWhere((e) => e.sortType == sortType) ?? -1; diff --git a/lib/pages/live/view.dart b/lib/pages/live/view.dart index 3e73116ed..558fb47cc 100644 --- a/lib/pages/live/view.dart +++ b/lib/pages/live/view.dart @@ -95,43 +95,41 @@ class _LivePageState extends CommonPageState child: SizedBox( // 10+14*textScaler height: 10.0 + textScaler.scale(14), - child: ListView.separated( - scrollDirection: .horizontal, - padding: const .only(right: 8), - physics: const AlwaysScrollableScrollPhysics(), - separatorBuilder: (_, _) => const SizedBox(width: 12), - itemBuilder: (context, index) { - late final item = list[index - 1]; - return Obx( - () { - final isCurr = - index == controller.areaIndex.value; - return SearchText( - fontSize: 14, - height: 1, - padding: const EdgeInsets.symmetric( - horizontal: 8, - vertical: 5, - ), - text: index == 0 ? '推荐' : '${item.title}', - bgColor: isCurr - ? theme.colorScheme.secondaryContainer - : Colors.transparent, - textColor: isCurr - ? theme.colorScheme.onSecondaryContainer - : null, - onTap: (value) { - controller.onSelectArea( - index, - index == 0 ? null : item, - ); - }, - ); - }, - ); - }, - itemCount: list.length + 1, - ), + child: Obx(() { + final areaIndex = controller.areaIndex.value; + return ListView.separated( + scrollDirection: .horizontal, + padding: const .only(right: 8), + physics: const AlwaysScrollableScrollPhysics(), + separatorBuilder: (_, _) => + const SizedBox(width: 12), + itemBuilder: (context, index) { + final isFirst = index == 0; + late final item = list[index - 1]; + final isCurr = index == areaIndex; + return SearchText( + fontSize: 14, + height: 1, + padding: const .symmetric( + horizontal: 8, + vertical: 5, + ), + text: isFirst ? '推荐' : item.title!, + bgColor: isCurr + ? theme.colorScheme.secondaryContainer + : Colors.transparent, + textColor: isCurr + ? theme.colorScheme.onSecondaryContainer + : null, + onTap: (_) => controller.onSelectArea( + index, + isFirst ? null : item, + ), + ); + }, + itemCount: list.length + 1, + ); + }), ), ), iconButton( @@ -189,42 +187,34 @@ class _LivePageState extends CommonPageState child: SizedBox( // 8+10+13*textScaler height: 18.0 + textScaler.scale(13), - child: ListView.separated( - scrollDirection: .horizontal, - padding: const .only(bottom: 8), - separatorBuilder: (_, _) => const SizedBox(width: 12), - physics: const AlwaysScrollableScrollPhysics(), - itemBuilder: (context, index) { - late final item = newTags[index]; - return Obx( - () { - final isCurr = index == controller.tagIndex.value; - return SearchText( - height: 1, - fontSize: 13, - padding: const EdgeInsets.symmetric( - horizontal: 8, - vertical: 5, - ), - text: '${item.name}', - bgColor: isCurr - ? theme.colorScheme.secondaryContainer - : Colors.transparent, - textColor: isCurr - ? theme.colorScheme.onSecondaryContainer - : null, - onTap: (value) { - controller.onSelectTag( - index, - item.sortType, - ); - }, - ); - }, - ); - }, - itemCount: newTags.length, - ), + child: Obx(() { + final tagIndex = controller.tagIndex.value; + return ListView.separated( + scrollDirection: .horizontal, + padding: const .only(bottom: 8), + separatorBuilder: (_, _) => const SizedBox(width: 12), + physics: const AlwaysScrollableScrollPhysics(), + itemBuilder: (context, index) { + final item = newTags[index]; + final isCurr = index == tagIndex; + return SearchText( + height: 1, + fontSize: 13, + padding: const .symmetric(horizontal: 8, vertical: 5), + text: item.name!, + bgColor: isCurr + ? theme.colorScheme.secondaryContainer + : Colors.transparent, + textColor: isCurr + ? theme.colorScheme.onSecondaryContainer + : null, + onTap: (value) => + controller.onSelectTag(index, item.sortType), + ); + }, + itemCount: newTags.length, + ); + }), ), ), response != null && response.isNotEmpty diff --git a/lib/pages/live_area_detail/child/view.dart b/lib/pages/live_area_detail/child/view.dart index e1c989c23..c1b4da111 100644 --- a/lib/pages/live_area_detail/child/view.dart +++ b/lib/pages/live_area_detail/child/view.dart @@ -81,39 +81,31 @@ class _LiveAreaChildPageState extends State slivers: [ if (_controller.newTags?.isNotEmpty == true) SliverToBoxAdapter( - child: SelfSizedHorizontalList( - padding: const .only(bottom: 12), - separatorBuilder: (_, _) => const SizedBox(width: 12), - itemBuilder: (context, index) { - late final item = _controller.newTags![index]; - return Obx( - () { - final isCurr = index == _controller.tagIndex.value; - return SearchText( - fontSize: 14, - padding: const EdgeInsets.symmetric( - horizontal: 8, - vertical: 3, - ), - text: '${item.name}', - bgColor: isCurr - ? theme.colorScheme.secondaryContainer - : Colors.transparent, - textColor: isCurr - ? theme.colorScheme.onSecondaryContainer - : null, - onTap: (value) { - _controller.onSelectTag( - index, - item.sortType, - ); - }, - ); - }, - ); - }, - itemCount: _controller.newTags!.length, - ), + child: Obx(() { + final tagIndex = _controller.tagIndex.value; + return SelfSizedHorizontalList( + padding: const .only(bottom: 12), + separatorBuilder: (_, _) => const SizedBox(width: 12), + itemBuilder: (context, index) { + final item = _controller.newTags![index]; + final isCurr = index == tagIndex; + return SearchText( + fontSize: 14, + padding: const .symmetric(horizontal: 8, vertical: 3), + text: item.name!, + bgColor: isCurr + ? theme.colorScheme.secondaryContainer + : Colors.transparent, + textColor: isCurr + ? theme.colorScheme.onSecondaryContainer + : null, + onTap: (value) => + _controller.onSelectTag(index, item.sortType), + ); + }, + itemCount: _controller.newTags!.length, + ); + }), ), response != null && response.isNotEmpty ? SliverGrid.builder( diff --git a/lib/pages/main/view.dart b/lib/pages/main/view.dart index 87a636d91..c6f66d8dd 100644 --- a/lib/pages/main/view.dart +++ b/lib/pages/main/view.dart @@ -1,10 +1,8 @@ import 'dart:io'; import 'package:PiliPlus/common/constants.dart'; -import 'package:PiliPlus/common/widgets/flutter/page/page_view.dart'; import 'package:PiliPlus/common/widgets/flutter/pop_scope.dart'; import 'package:PiliPlus/common/widgets/flutter/tabs.dart'; -import 'package:PiliPlus/common/widgets/gesture/horizontal_drag_gesture_recognizer.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/models/common/nav_bar_config.dart'; import 'package:PiliPlus/pages/home/view.dart'; @@ -20,7 +18,7 @@ import 'package:PiliPlus/utils/platform_utils.dart'; import 'package:PiliPlus/utils/storage.dart'; import 'package:PiliPlus/utils/storage_key.dart'; import 'package:PiliPlus/utils/utils.dart'; -import 'package:flutter/material.dart' hide PageView; +import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:tray_manager/tray_manager.dart'; @@ -395,11 +393,9 @@ class _MainAppState extends PopScopeState children: _mainController.navigationBars.map((i) => i.page).toList(), ); } else { - child = PageView( + child = PageView( physics: const NeverScrollableScrollPhysics(), controller: _mainController.controller, - horizontalDragGestureRecognizer: - CustomHorizontalDragGestureRecognizer(), children: _mainController.navigationBars.map((i) => i.page).toList(), ); } diff --git a/lib/pages/pgc_index/view.dart b/lib/pages/pgc_index/view.dart index 1348aa6f1..e63d8923a 100644 --- a/lib/pages/pgc_index/view.dart +++ b/lib/pages/pgc_index/view.dart @@ -103,58 +103,45 @@ class _PgcIndexPageState extends State ThemeData theme, int index, PgcIndexConditionData data, - item, + Object item, + Map indexParams, ) { - if (item case final PgcConditionOrder e) { - return Obx( - () { - final isCurr = _ctr.indexParams['order'] == e.field; - return SearchText( - bgColor: isCurr - ? theme.colorScheme.secondaryContainer - : Colors.transparent, - textColor: isCurr - ? theme.colorScheme.onSecondaryContainer - : theme.colorScheme.onSurfaceVariant, - text: e.name!, - padding: const EdgeInsets.symmetric( - horizontal: 6, - vertical: 3, - ), - onTap: (_) => _ctr - ..indexParams['order'] = e.field - ..onReload(), - ); - }, + if (item is PgcConditionOrder) { + final isCurr = indexParams['order'] == item.field; + return SearchText( + bgColor: isCurr + ? theme.colorScheme.secondaryContainer + : Colors.transparent, + textColor: isCurr + ? theme.colorScheme.onSecondaryContainer + : theme.colorScheme.onSurfaceVariant, + text: item.name!, + padding: const .symmetric(horizontal: 6, vertical: 3), + onTap: (_) => _ctr + ..indexParams['order'] = item.field + ..onReload(), ); } - if (item case final PgcConditionValue e) { + if (item is PgcConditionValue) { final hasOrder = data.order?.isNotEmpty == true; if (hasOrder) index -= 1; final key = data.filter![index].field!; - return Obx( - () { - final isCurr = _ctr.indexParams[key] == e.keyword; - return SearchText( - bgColor: isCurr - ? theme.colorScheme.secondaryContainer - : Colors.transparent, - textColor: isCurr - ? theme.colorScheme.onSecondaryContainer - : theme.colorScheme.onSurfaceVariant, - text: e.name!, - padding: const EdgeInsets.symmetric( - horizontal: 6, - vertical: 3, - ), - onTap: (_) => _ctr - ..indexParams[key] = e.keyword - ..onReload(), - ); - }, + final isCurr = indexParams[key] == item.keyword; + return SearchText( + bgColor: isCurr + ? theme.colorScheme.secondaryContainer + : Colors.transparent, + textColor: isCurr + ? theme.colorScheme.onSecondaryContainer + : theme.colorScheme.onSurfaceVariant, + text: item.name!, + padding: const .symmetric(horizontal: 6, vertical: 3), + onTap: (_) => _ctr + ..indexParams[key] = item.keyword + ..onReload(), ); } - throw UnsupportedError('${item.runtimeType}'); + throw UnsupportedError(item.runtimeType.toString()); } Widget _buildSortsWidget( @@ -179,16 +166,24 @@ class _PgcIndexPageState extends State : data.filter![index - 1].values : data.filter![index].values; if (item != null && item.isNotEmpty) { - return SelfSizedHorizontalList( - padding: isFirst - ? const .symmetric(horizontal: 12) - : const .fromLTRB(12, 10, 12, 0), - separatorBuilder: (_, _) => const SizedBox(width: 12), - itemBuilder: (context, childIndex) { - return _buildSortWidget(theme, index, data, item[childIndex]); - }, - itemCount: item.length, - ); + return Obx(() { + // ignore: invalid_use_of_protected_member + final indexParams = _ctr.indexParams.value; + return SelfSizedHorizontalList( + padding: isFirst + ? const .symmetric(horizontal: 12) + : const .fromLTRB(12, 10, 12, 0), + separatorBuilder: (_, _) => const SizedBox(width: 12), + itemBuilder: (context, childIndex) => _buildSortWidget( + theme, + index, + data, + item[childIndex], + indexParams, + ), + itemCount: item.length, + ); + }); } return const SizedBox.shrink(); }, diff --git a/lib/pages/rank/view.dart b/lib/pages/rank/view.dart index 3443ce304..ad83a63a1 100644 --- a/lib/pages/rank/view.dart +++ b/lib/pages/rank/view.dart @@ -48,10 +48,11 @@ class _RankPageState extends State width: 64, child: Obx(() { final tabIndex = _rankController.tabIndex.value; - return ListView( + return ListView.builder( padding: .only(bottom: MediaQuery.paddingOf(context).bottom + 105), - children: RankType.values.map((e) { - final index = e.index; + itemCount: RankType.values.length, + itemBuilder: (context, index) { + final item = RankType.values[index]; final isCurr = index == tabIndex; return IntrinsicHeight( child: Material( @@ -59,15 +60,11 @@ class _RankPageState extends State ? theme.colorScheme.onInverseSurface : theme.colorScheme.surface, child: InkWell( - onTap: () { - if (isCurr) { - _rankController.animateToTop(); - } else { - _rankController - ..tabIndex.value = index - ..tabController.animateTo(index); - } - }, + onTap: isCurr + ? _rankController.animateToTop + : () => _rankController + ..tabIndex.value = index + ..tabController.animateTo(index), child: Row( mainAxisSize: MainAxisSize.min, children: [ @@ -85,13 +82,13 @@ class _RankPageState extends State alignment: Alignment.center, padding: const .symmetric(vertical: 7), child: Text( - RankType.values[index].label, - style: TextStyle( - color: isCurr - ? theme.colorScheme.primary - : theme.colorScheme.onSurface, - fontSize: 15, - ), + item.label, + style: isCurr + ? TextStyle( + fontSize: 15, + color: theme.colorScheme.primary, + ) + : const TextStyle(fontSize: 15), maxLines: 1, overflow: TextOverflow.ellipsis, ), @@ -102,7 +99,7 @@ class _RankPageState extends State ), ), ); - }).toList(), + }, ); }), ); diff --git a/lib/pages/video/download_panel/view.dart b/lib/pages/video/download_panel/view.dart index 9d7f67ee0..d412e3732 100644 --- a/lib/pages/video/download_panel/view.dart +++ b/lib/pages/video/download_panel/view.dart @@ -332,9 +332,7 @@ class _DownloadPanelState extends State { int? cid; String? cover; - int? width; - int? height; - bool cacheWidth = false; + bool? cacheWidth; switch (episode) { case Part part: @@ -343,10 +341,7 @@ class _DownloadPanelState extends State { title = part.part ?? widget.videoDetail!.title!; duration = part.duration; pubdate = part.ctime; - if (part.dimension case final dimension?) { - width = dimension.width; - height = dimension.height; - } + cacheWidth = part.dimension?.cacheWidth; break; case ugc.EpisodeItem item: cid = item.cid; @@ -359,10 +354,7 @@ class _DownloadPanelState extends State { view = stat.view; danmaku = stat.danmaku; } - if (arc.dimension case final dimension?) { - width = dimension.width; - height = dimension.height; - } + cacheWidth = arc.dimension?.cacheWidth; } if (item.attribute == 8) { isCharging = true; @@ -379,15 +371,9 @@ class _DownloadPanelState extends State { duration = item.duration == null ? null : item.duration! ~/ 1000; } pubdate = item.pubTime; - if (item.dimension case final dimension?) { - width = dimension.width; - height = dimension.height; - } + cacheWidth = item.dimension?.cacheWidth; break; } - if (width != null && height != null) { - cacheWidth = width <= height; - } late final primary = theme.colorScheme.primary; return Padding( diff --git a/lib/pages/video/introduction/local/view.dart b/lib/pages/video/introduction/local/view.dart index c12a2fc43..83f219d95 100644 --- a/lib/pages/video/introduction/local/view.dart +++ b/lib/pages/video/introduction/local/view.dart @@ -55,6 +55,7 @@ class _LocalIntroPanelState extends State ) { final outline = theme.colorScheme.outline; final cover = File(path.join(entry.entryDirPath, PathUtils.coverName)); + final cacheWidth = entry.pageData?.cacheWidth ?? false; return Padding( padding: const EdgeInsets.only(bottom: 2), child: SizedBox( @@ -87,7 +88,12 @@ class _LocalIntroPanelState extends State width: 140.8, height: 88, fit: BoxFit.cover, - cacheHeight: 140.8.cacheSize(context), + cacheWidth: cacheWidth + ? 140.8.cacheSize(context) + : null, + cacheHeight: cacheWidth + ? null + : 88.cacheSize(context), colorBlendMode: NetworkImgLayer.reduce ? BlendMode.modulate : null,