diff --git a/lib/main.dart b/lib/main.dart index 1f5745514..3a7d778e1 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -51,9 +51,7 @@ void main() async { else SystemChrome.setPreferredOrientations( //支持竖屏 - [ - DeviceOrientation.portraitUp, - ], + [DeviceOrientation.portraitUp], ), setupServiceLocator(), ]); diff --git a/lib/pages/common/reply_controller.dart b/lib/pages/common/reply_controller.dart index 3863c618e..b480363fb 100644 --- a/lib/pages/common/reply_controller.dart +++ b/lib/pages/common/reply_controller.dart @@ -169,17 +169,13 @@ abstract class ReplyController extends CommonListController { }, transitionDuration: const Duration(milliseconds: 500), transitionBuilder: (context, animation, secondaryAnimation, child) { - const begin = Offset(0.0, 1.0); - const end = Offset.zero; - const curve = Curves.linear; - - var tween = Tween( - begin: begin, - end: end, - ).chain(CurveTween(curve: curve)); - return SlideTransition( - position: animation.drive(tween), + position: animation.drive( + Tween( + begin: const Offset(0.0, 1.0), + end: Offset.zero, + ).chain(CurveTween(curve: Curves.linear)), + ), child: child, ); }, diff --git a/lib/pages/fan/view.dart b/lib/pages/fan/view.dart index 019e7c95a..208a891ea 100644 --- a/lib/pages/fan/view.dart +++ b/lib/pages/fan/view.dart @@ -39,14 +39,15 @@ class _FansPageState extends State { void initState() { super.initState(); AccountService accountService = Get.find(); - mid = - widget.mid ?? - (Get.parameters['mid'] != null - ? int.parse(Get.parameters['mid']!) - : accountService.mid); - isOwner = mid == accountService.mid; + late final mid = Get.parameters['mid']; + this.mid = + widget.mid ?? (mid != null ? int.parse(mid) : accountService.mid); + isOwner = this.mid == accountService.mid; name = Get.parameters['name'] ?? accountService.name.value; - _fansController = Get.put(FansController(mid), tag: Utils.makeHeroTag(mid)); + _fansController = Get.put( + FansController(this.mid), + tag: Utils.makeHeroTag(this.mid), + ); } @override diff --git a/lib/pages/follow/controller.dart b/lib/pages/follow/controller.dart index 728b7d34e..fc310db84 100644 --- a/lib/pages/follow/controller.dart +++ b/lib/pages/follow/controller.dart @@ -20,10 +20,9 @@ class FollowController extends GetxController with GetTickerProviderStateMixin { void onInit() { super.onInit(); int ownerMid = Accounts.main.mid; - mid = Get.parameters['mid'] != null - ? int.parse(Get.parameters['mid']!) - : ownerMid; - isOwner = ownerMid == mid; + final mid = Get.parameters['mid']; + this.mid = mid != null ? int.parse(mid) : ownerMid; + isOwner = ownerMid == this.mid; name = Get.parameters['name'] ?? Get.find().name.value; if (isOwner) { queryFollowUpTags(); diff --git a/lib/pages/mine/view.dart b/lib/pages/mine/view.dart index 82d291b48..8e1a96198 100644 --- a/lib/pages/mine/view.dart +++ b/lib/pages/mine/view.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:PiliPlus/common/constants.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; +import 'package:PiliPlus/common/widgets/list_tile.dart'; import 'package:PiliPlus/common/widgets/refresh_indicator.dart'; import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/models/common/image_type.dart'; @@ -16,7 +17,7 @@ import 'package:PiliPlus/pages/mine/controller.dart'; import 'package:PiliPlus/pages/mine/widgets/item.dart'; import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/utils.dart'; -import 'package:flutter/material.dart'; +import 'package:flutter/material.dart' hide ListTile; import 'package:get/get.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; @@ -61,6 +62,7 @@ class _MediaPageState extends CommonPageState child: refreshIndicator( onRefresh: controller.onRefresh, child: ListView( + padding: const EdgeInsets.only(bottom: 100), controller: controller.scrollController, physics: const AlwaysScrollableScrollPhysics(), children: [ @@ -461,12 +463,7 @@ class _MediaPageState extends CommonPageState icon: const Icon(Icons.refresh, size: 20), ), ), - SizedBox( - width: double.infinity, - height: 200, - child: _buildFavBody(theme, secondary, controller.loadingState.value), - ), - const SizedBox(height: 100), + _buildFavBody(theme, secondary, controller.loadingState.value), ], ); } @@ -481,55 +478,60 @@ class _MediaPageState extends CommonPageState Success(:var response) => Builder( builder: (context) { List? favFolderList = response.list; - if (favFolderList.isNullOrEmpty) { + if (favFolderList == null || favFolderList.isEmpty) { return const SizedBox.shrink(); } - bool flag = (controller.favFoldercount ?? 0) > favFolderList!.length; - return ListView.separated( - padding: const EdgeInsets.only(left: 20), - itemCount: response.list.length + (flag ? 1 : 0), - itemBuilder: (context, index) { - if (flag && index == favFolderList.length) { - return Padding( - padding: const EdgeInsets.only(right: 14, bottom: 35), - child: Center( - child: IconButton( - tooltip: '查看更多', - style: ButtonStyle( - padding: const WidgetStatePropertyAll(EdgeInsets.zero), - backgroundColor: WidgetStatePropertyAll( - theme.colorScheme.secondaryContainer.withValues( - alpha: 0.5, + bool flag = (controller.favFoldercount ?? 0) > favFolderList.length; + return SizedBox( + height: 200, + child: ListView.separated( + padding: const EdgeInsets.only(left: 20, top: 12), + itemCount: response.list.length + (flag ? 1 : 0), + itemBuilder: (context, index) { + if (flag && index == favFolderList.length) { + return Padding( + padding: const EdgeInsets.only(right: 14, bottom: 35), + child: Center( + child: IconButton( + tooltip: '查看更多', + style: ButtonStyle( + padding: const WidgetStatePropertyAll( + EdgeInsets.zero, + ), + backgroundColor: WidgetStatePropertyAll( + theme.colorScheme.secondaryContainer.withValues( + alpha: 0.5, + ), ), ), - ), - onPressed: () => Get.toNamed('/fav')?.whenComplete( - () => Future.delayed( - const Duration(milliseconds: 150), - controller.onRefresh, + onPressed: () => Get.toNamed('/fav')?.whenComplete( + () => Future.delayed( + const Duration(milliseconds: 150), + controller.onRefresh, + ), + ), + icon: Icon( + Icons.arrow_forward_ios, + size: 18, + color: secondary, ), ), - icon: Icon( - Icons.arrow_forward_ios, - size: 18, - color: secondary, - ), ), - ), - ); - } else { - return FavFolderItem( - heroTag: Utils.generateRandomString(8), - item: response.list[index], - callback: () => Future.delayed( - const Duration(milliseconds: 150), - controller.onRefresh, - ), - ); - } - }, - scrollDirection: Axis.horizontal, - separatorBuilder: (context, index) => const SizedBox(width: 14), + ); + } else { + return FavFolderItem( + heroTag: Utils.generateRandomString(8), + item: response.list[index], + callback: () => Future.delayed( + const Duration(milliseconds: 150), + controller.onRefresh, + ), + ); + } + }, + scrollDirection: Axis.horizontal, + separatorBuilder: (context, index) => const SizedBox(width: 14), + ), ); }, ), diff --git a/lib/pages/mine/widgets/item.dart b/lib/pages/mine/widgets/item.dart index 490769538..fce2a600c 100644 --- a/lib/pages/mine/widgets/item.dart +++ b/lib/pages/mine/widgets/item.dart @@ -36,11 +36,7 @@ class FavFolderItem extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - const SizedBox(height: 12), - Container( - width: 180, - height: 110, - margin: const EdgeInsets.only(bottom: 8), + DecoratedBox( decoration: BoxDecoration( borderRadius: const BorderRadius.all(Radius.circular(12)), boxShadow: [ @@ -58,11 +54,12 @@ class FavFolderItem extends StatelessWidget { tag: heroTag, child: NetworkImgLayer( src: item.cover, - width: 176, + width: 180, height: 110, ), ), ), + const SizedBox(height: 8), Text( ' ${item.title}', overflow: TextOverflow.fade, diff --git a/lib/pages/pgc_index/view.dart b/lib/pages/pgc_index/view.dart index 1a27c106f..5d89cfada 100644 --- a/lib/pages/pgc_index/view.dart +++ b/lib/pages/pgc_index/view.dart @@ -120,14 +120,12 @@ class _PgcIndexPageState extends State : data.filter![index].values; return item?.isNotEmpty == true ? Padding( - padding: EdgeInsets.only( - top: index == 0 ? 0 : 10, - ), + padding: index == 0 + ? EdgeInsets.zero + : const EdgeInsets.only(top: 10), child: SelfSizedHorizontalList( gapSize: 12, - padding: const EdgeInsets.symmetric( - horizontal: 12, - ), + padding: const EdgeInsets.symmetric(horizontal: 12), childBuilder: (childIndex) { final e = item[childIndex]; return Obx( diff --git a/lib/pages/save_panel/view.dart b/lib/pages/save_panel/view.dart index 6d65a923c..42a944159 100644 --- a/lib/pages/save_panel/view.dart +++ b/lib/pages/save_panel/view.dart @@ -49,12 +49,13 @@ class SavePanel extends StatefulWidget { }, transitionDuration: const Duration(milliseconds: 255), transitionBuilder: (context, animation, secondaryAnimation, child) { - var tween = Tween( - begin: 0, - end: 1, - ).chain(CurveTween(curve: Curves.easeInOut)); return FadeTransition( - opacity: animation.drive(tween), + opacity: animation.drive( + Tween( + begin: 0, + end: 1, + ).chain(CurveTween(curve: Curves.easeInOut)), + ), child: child, ); }, diff --git a/lib/pages/share/view.dart b/lib/pages/share/view.dart index db06d7161..cb83c7a22 100644 --- a/lib/pages/share/view.dart +++ b/lib/pages/share/view.dart @@ -112,6 +112,7 @@ class _SharePanelState extends State { gapSize: 10, itemCount: _userList.length, controller: _scrollController, + padding: EdgeInsets.zero, childBuilder: (index) { final item = _userList[index]; return GestureDetector( diff --git a/lib/pages/video/controller.dart b/lib/pages/video/controller.dart index e69b39c0c..66f0060a3 100644 --- a/lib/pages/video/controller.dart +++ b/lib/pages/video/controller.dart @@ -972,17 +972,13 @@ class VideoDetailController extends GetxController }, transitionDuration: const Duration(milliseconds: 500), transitionBuilder: (context, animation, secondaryAnimation, child) { - const begin = Offset(0.0, 1.0); - const end = Offset.zero; - const curve = Curves.linear; - - var tween = Tween( - begin: begin, - end: end, - ).chain(CurveTween(curve: curve)); - return SlideTransition( - position: animation.drive(tween), + position: animation.drive( + Tween( + begin: const Offset(0.0, 1.0), + end: Offset.zero, + ).chain(CurveTween(curve: Curves.linear)), + ), child: child, ); }, diff --git a/lib/pages/video/introduction/ugc/widgets/page.dart b/lib/pages/video/introduction/ugc/widgets/page.dart index f6bb1a776..eed96aac3 100644 --- a/lib/pages/video/introduction/ugc/widgets/page.dart +++ b/lib/pages/video/introduction/ugc/widgets/page.dart @@ -140,6 +140,7 @@ class _PagesPanelState extends State { scrollDirection: Axis.horizontal, itemCount: pages.length, itemExtent: 150, + padding: EdgeInsets.zero, itemBuilder: (BuildContext context, int i) { bool isCurrentIndex = pageIndex == i; final item = pages[i]; diff --git a/lib/pages/video/pay_coins/view.dart b/lib/pages/video/pay_coins/view.dart index f858c9294..b6a0ffa16 100644 --- a/lib/pages/video/pay_coins/view.dart +++ b/lib/pages/video/pay_coins/view.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:math'; import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/global_data.dart'; @@ -14,12 +13,12 @@ class PayCoinsPage extends StatefulWidget { const PayCoinsPage({ super.key, required this.onPayCoin, - this.copyright = 1, + int copyright = 1, this.hasCoin = false, - }); + }) : hasCopyright = copyright == 1; final Function(int coin, bool coinWithLike) onPayCoin; - final int copyright; + final bool hasCopyright; final bool hasCoin; @override @@ -41,17 +40,13 @@ class PayCoinsPage extends StatefulWidget { }, transitionDuration: const Duration(milliseconds: 225), transitionBuilder: (context, animation, secondaryAnimation, child) { - const begin = 0.0; - const end = 1.0; - const curve = Curves.linear; - - var tween = Tween( - begin: begin, - end: end, - ).chain(CurveTween(curve: curve)); - return FadeTransition( - opacity: animation.drive(tween), + opacity: animation.drive( + Tween( + begin: 0.0, + end: 1.0, + ).chain(CurveTween(curve: Curves.linear)), + ), child: child, ); }, @@ -62,54 +57,12 @@ class PayCoinsPage extends StatefulWidget { class _PayCoinsPageState extends State with TickerProviderStateMixin { - bool _isPaying = false; - late final _controller = PageController(viewportFraction: 0.30); + late final _key = GlobalKey(); + late final _hasCopyright = widget.hasCopyright; + late bool _isPaying = false; + PageController? _controller; late final RxBool _coinWithLike = Pref.coinWithLike.obs; - final _key = GlobalKey(); - - int get _index => _controller.hasClients ? _controller.page?.round() ?? 0 : 0; - - num? get _coins => GlobalData().coins; - bool get _canPay { - if (_index == 1 && widget.hasCoin) { - return false; - } - if (_coins == null) { - return true; - } - if (_index == 0 && _coins! >= 1) { - return true; - } - if (_index == 1 && _coins! >= 2) { - return true; - } - return false; - } - - Color _getColorFilter(int index) { - if (index == 1 && widget.hasCoin) { - return Colors.black.withValues(alpha: 0.4); - } - if (_coins == null) { - return Colors.transparent; - } - if (index == 0 && _coins == 0) { - return Colors.black.withValues(alpha: 0.4); - } - if (index == 1 && _coins! < 2) { - return Colors.black.withValues(alpha: 0.4); - } - return Colors.transparent; - } - - String get _getImage { - if (!_canPay) { - return 'assets/images/paycoins/ic_22_not_enough_pay.png'; - } - return _index == 0 - ? 'assets/images/paycoins/ic_22_mario.png' - : 'assets/images/paycoins/ic_22_gun_sister.png'; - } + late final RxInt _pageIndex = 0.obs; late final AnimationController _slide22Controller; late final Animation _slide22Anim; @@ -122,18 +75,76 @@ class _PayCoinsPageState extends State late final AnimationController _boxAnimController; late final Animation _boxAnim; - final List _images = const [ + Timer? _timer; + late final RxInt _thunderIndex = (-1).obs; + late final List _thunderImages = const [ 'assets/images/paycoins/ic_thunder_1.png', 'assets/images/paycoins/ic_thunder_2.png', 'assets/images/paycoins/ic_thunder_3.png', ]; - late int _imageIndex = -1; - Timer? _timer; - bool get _showThunder => _imageIndex != -1 && _imageIndex != _images.length; + void _cancelTimer() { + _timer?.cancel(); + _timer = null; + } + + final num? _coins = GlobalData().coins; + late final List _payState; + late final List _payImg; + late final List _payFilter; + + bool _canPay(int index) { + if (index == 1 && widget.hasCoin) { + return false; + } + if (_coins == null) { + return true; + } + if (index == 0 && _coins >= 1) { + return true; + } + if (index == 1 && _coins >= 2) { + return true; + } + return false; + } + + String _getPayImage(int index) { + if (!_payState[index]) { + return 'assets/images/paycoins/ic_22_not_enough_pay.png'; + } + return index == 0 + ? 'assets/images/paycoins/ic_22_mario.png' + : 'assets/images/paycoins/ic_22_gun_sister.png'; + } + + late final color = Colors.black.withValues(alpha: 0.4); + Color _getPayFilter(int index) { + if (index == 1 && widget.hasCoin) { + return color; + } + if (_coins == null) { + return Colors.transparent; + } + if (index == 0 && _coins == 0) { + return color; + } + if (index == 1 && _coins < 2) { + return color; + } + return Colors.transparent; + } @override void initState() { super.initState(); + if (_hasCopyright) { + _controller = PageController(viewportFraction: 0.30); + } + final count = _hasCopyright ? 2 : 1; + _payState = List.generate(count, _canPay); + _payImg = List.generate(count, _getPayImage); + _payFilter = List.generate(count, _getPayFilter); + _slide22Controller = AnimationController( vsync: this, duration: const Duration(milliseconds: 50), @@ -179,18 +190,19 @@ class _PayCoinsPageState extends State end: const Offset(0.0, -0.2), ), ); + _scale(); } @override void dispose() { - _timer?.cancel(); + _cancelTimer(); _slide22Controller.dispose(); _scale22Controller.dispose(); _coinSlideController.dispose(); _coinFadeController.dispose(); _boxAnimController.dispose(); - _controller.dispose(); + _controller?.dispose(); super.dispose(); } @@ -199,7 +211,7 @@ class _PayCoinsPageState extends State } void _onScroll(int index) { - _controller.animateToPage( + _controller?.animateToPage( index, duration: const Duration(milliseconds: 200), curve: Curves.ease, @@ -221,18 +233,89 @@ class _PayCoinsPageState extends State ); } + Widget _buildCoinWidget(int index, double factor) { + return Center( + child: SizedBox( + height: 70 + (factor * 30), + width: 70 + (factor * 30), + child: ColorFiltered( + colorFilter: ColorFilter.mode( + _payFilter[index], + BlendMode.srcATop, + ), + child: Stack( + clipBehavior: Clip.none, + alignment: Alignment.center, + children: [ + SlideTransition( + position: _boxAnim, + child: Image.asset( + 'assets/images/paycoins/ic_pay_coins_box.png', + ), + ), + SlideTransition( + position: _coinSlideAnim, + child: FadeTransition( + opacity: _coinFadeAnim, + child: Image.asset( + height: 35 + (factor * 15), + width: 35 + (factor * 15), + index == 0 + ? 'assets/images/paycoins/ic_coins_one.png' + : 'assets/images/paycoins/ic_coins_two.png', + ), + ), + ), + ], + ), + ), + ), + ); + } + + Widget _build22() { + final index = _pageIndex.value; + final canPay = _payState[index]; + final payImg = _payImg[index]; + return GestureDetector( + onTap: canPay ? _onPayCoin : null, + onVerticalDragStart: canPay + ? (e) { + _isHorizontal = false; + _onDragDown(e); + } + : null, + onVerticalDragUpdate: canPay ? _onDragUpdate : null, + onVerticalDragEnd: canPay ? _onDragEnd : null, + onVerticalDragCancel: canPay ? _onDragEnd : null, + behavior: HitTestBehavior.opaque, + child: ScaleTransition( + scale: _scale22Anim, + child: SlideTransition( + position: _slide22Anim, + child: SizedBox( + width: 110, + height: 155, + child: Image.asset(payImg), + ), + ), + ), + ); + } + Widget _buildBody(bool isV) => Stack( key: _key, clipBehavior: Clip.none, alignment: Alignment.center, children: [ - Visibility( - visible: _showThunder, - maintainSize: true, - maintainAnimation: true, - maintainState: true, - child: Image.asset(_images[_showThunder ? _imageIndex : 0]), - ), + if (_hasCopyright) + Obx(() { + final index = _thunderIndex.value; + return Offstage( + offstage: index == -1 || index == 3, + child: Image.asset(_thunderImages[index.clamp(0, 2)]), + ); + }), Align( alignment: Alignment.bottomCenter, child: GestureDetector( @@ -241,144 +324,124 @@ class _PayCoinsPageState extends State mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - children: [ - Visibility( - visible: !_isPaying && widget.copyright == 1, - maintainSize: true, - maintainAnimation: true, - maintainState: true, - child: GestureDetector( - onTap: _index == 0 ? null : () => _onScroll(0), - child: Padding( - padding: const EdgeInsets.only(left: 12), - child: Image.asset( - width: 16, - height: 28, - _index == 0 - ? 'assets/images/paycoins/ic_left_disable.png' - : 'assets/images/paycoins/ic_left.png', - ), - ), - ), - ), - Expanded( - child: SizedBox( - height: 100, - child: PageView.builder( - key: const PageStorageKey('PageView'), - physics: const ClampingScrollPhysics(), - itemCount: widget.copyright == 1 ? 2 : 1, - controller: _controller, - onPageChanged: (index) => setState(_scale), - itemBuilder: (context, index) { - return ListenableBuilder( - listenable: _controller, - builder: (context, child) { - double factor = index == 0 ? 1 : 0; - if (_controller.position.hasContentDimensions) { - factor = 1 - (_controller.page! - index).abs(); - } - return Visibility( - visible: !_isPaying || _index == index, - child: Center( - child: SizedBox( - height: 70 + (factor * 30), - width: 70 + (factor * 30), - child: ColorFiltered( - colorFilter: ColorFilter.mode( - _getColorFilter(index), - BlendMode.srcATop, - ), - child: Stack( - clipBehavior: Clip.none, - alignment: Alignment.center, - children: [ - SlideTransition( - position: _boxAnim, - child: Image.asset( - 'assets/images/paycoins/ic_pay_coins_box.png', - ), - ), - SlideTransition( - position: _coinSlideAnim, - child: FadeTransition( - opacity: _coinFadeAnim, - child: Image.asset( - height: 35 + (factor * 15), - width: 35 + (factor * 15), - index == 0 - ? 'assets/images/paycoins/ic_coins_one.png' - : 'assets/images/paycoins/ic_coins_two.png', - ), - ), - ), - ], - ), - ), - ), - ), + if (_hasCopyright) + Stack( + clipBehavior: Clip.none, + alignment: Alignment.center, + children: [ + Padding( + padding: const EdgeInsets.symmetric(horizontal: 28), + child: SizedBox( + height: 100, + child: PageView( + key: const PageStorageKey('PageView'), + physics: const ClampingScrollPhysics(), + controller: _controller, + onPageChanged: (index) { + _scale(); + _pageIndex.value = index; + }, + children: List.generate( + 2, + (index) { + return ListenableBuilder( + listenable: _controller!, + builder: (context, child) { + double factor = index == 0 ? 1 : 0; + if (_controller! + .position + .hasContentDimensions) { + factor = + 1 - (_controller!.page! - index).abs(); + } + return Obx( + () { + if (_pageIndex.value != index && + _isPaying) { + return const SizedBox.shrink(); + } + return _buildCoinWidget(index, factor); + }, + ); + }, ); }, - ); - }, - ), - ), - ), - Visibility( - visible: !_isPaying && widget.copyright == 1, - maintainSize: true, - maintainAnimation: true, - maintainState: true, - child: GestureDetector( - onTap: _index == 1 ? null : () => _onScroll(1), - child: Padding( - padding: const EdgeInsets.only(right: 12), - child: Image.asset( - width: 16, - height: 28, - _index == 1 - ? 'assets/images/paycoins/ic_right_disable.png' - : 'assets/images/paycoins/ic_right.png', - ), - ), - ), - ), - ], - ), - SizedBox(height: isV ? 25 : 10), - GestureDetector( - behavior: HitTestBehavior.opaque, - onPanUpdate: _handlePanUpdate, - child: SizedBox( - width: double.infinity, - height: 155, - child: Center( - child: GestureDetector( - onTap: _canPay ? _onPayCoin : null, - onPanUpdate: _canPay - ? (e) => _handlePanUpdate(e, true) - : null, - child: ScaleTransition( - scale: _scale22Anim, - child: SlideTransition( - position: _slide22Anim, - child: SizedBox( - width: 110, - height: 155, - child: Image.asset(_getImage), ), ), ), ), - ), - ), - ), + Align( + alignment: Alignment.centerLeft, + child: Obx( + () { + final index = _pageIndex.value; + if (_isPaying) { + return const SizedBox.shrink(); + } + return GestureDetector( + onTap: index == 0 ? null : () => _onScroll(0), + behavior: HitTestBehavior.opaque, + child: Padding( + padding: const EdgeInsets.only(left: 12), + child: Image.asset( + width: 16, + height: 28, + index == 0 + ? 'assets/images/paycoins/ic_left_disable.png' + : 'assets/images/paycoins/ic_left.png', + ), + ), + ); + }, + ), + ), + Align( + alignment: Alignment.centerRight, + child: Obx(() { + final index = _pageIndex.value; + if (_isPaying) { + return const SizedBox.shrink(); + } + return GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: index == 1 ? null : () => _onScroll(1), + child: Padding( + padding: const EdgeInsets.only(right: 12), + child: Image.asset( + width: 16, + height: 28, + index == 1 + ? 'assets/images/paycoins/ic_right_disable.png' + : 'assets/images/paycoins/ic_right.png', + ), + ), + ); + }), + ), + ], + ) + else + SizedBox(height: 100, child: _buildCoinWidget(0, 1)), + SizedBox(height: isV ? 25 : 10), + if (_hasCopyright) + GestureDetector( + behavior: HitTestBehavior.opaque, + onHorizontalDragStart: (e) { + _isHorizontal = true; + _onDragDown(e); + }, + onHorizontalDragUpdate: _onDragUpdate, + onHorizontalDragEnd: _onDragEnd, + onHorizontalDragCancel: _onDragEnd, + child: Center(child: Obx(_build22)), + ) + else + Center(child: _build22()), if (_coins != null || widget.hasCoin) ...[ const SizedBox(height: 10), Center( child: Text( - '${_coins != null ? '硬币余额:${_coins!.toDouble().toPrecision(1)}' : ''}${widget.hasCoin ? '${_coins != null ? ',' : ''}已投1枚硬币' : ''}', + '${_coins != null ? '硬币余额:${_coins.toDouble().toPrecision(1)}' : ''}${widget.hasCoin ? '${_coins != null ? ',' : ''}已投1枚硬币' : ''}', style: const TextStyle(color: Colors.white, fontSize: 13), ), ), @@ -394,6 +457,7 @@ class _PayCoinsPageState extends State _coinWithLike.value = newVal; GStorage.setting.put(SettingBoxKey.coinWithLike, newVal); }, + behavior: HitTestBehavior.opaque, child: Row( mainAxisSize: MainAxisSize.min, children: [ @@ -417,6 +481,7 @@ class _PayCoinsPageState extends State Center( child: GestureDetector( onTap: Get.back, + behavior: HitTestBehavior.opaque, child: SizedBox( width: 30, height: 30, @@ -439,42 +504,52 @@ class _PayCoinsPageState extends State ], ); - void _handlePanUpdate(DragUpdateDetails e, [bool needV = false]) { - if (needV && e.delta.dy.abs() > max(2, e.delta.dx.abs())) { - if (e.delta.dy < 0) { - _onPayCoin(); - } - } else if (widget.copyright == 1 && - e.delta.dx.abs() > max(2, e.delta.dy.abs())) { + late bool _isHorizontal = true; + DragStartDetails? _downPos; + void _onDragDown(DragStartDetails detail) => _downPos = detail; + void _onDragEnd([_]) => _downPos = null; + void _onDragUpdate(DragUpdateDetails e) { + if (_downPos == null) { + return; + } + final offset = _isHorizontal + ? (e.localPosition.dx - _downPos!.localPosition.dx).abs() + : (e.localPosition.dy - _downPos!.localPosition.dy).abs(); + if (offset < 20) { + return; + } + _downPos = null; + if (_isHorizontal) { if (e.delta.dx > 0) { - if (_index == 1) { + if (_pageIndex.value == 1) { _onScroll(0); - setState(() {}); } } else { - if (_index == 0) { + if (_pageIndex.value == 0) { _onScroll(1); - setState(() {}); } } + } else { + if (e.delta.dy < 0) { + _onPayCoin(); + } } } void _onPayCoin() { if (_isPaying) return; - setState(() { - _isPaying = true; - }); + _isPaying = true; + _pageIndex.refresh(); _slide22Controller.forward().whenComplete(() { _slide22Controller.reverse().whenComplete(() { - if (_index == 1) { + if (_pageIndex.value == 1) { + _thunderIndex.value += 1; _timer ??= Timer.periodic(const Duration(milliseconds: 50 ~/ 3), (_) { - if (_imageIndex != _images.length) { - setState(() { - _imageIndex = _imageIndex + 1; - }); + final index = _thunderIndex.value; + if (index == _thunderImages.length) { + _cancelTimer(); } else { - _timer?.cancel(); + _thunderIndex.value = index + 1; } }); } @@ -482,7 +557,7 @@ class _PayCoinsPageState extends State _coinSlideController.forward().whenComplete(() { _coinFadeController.forward().whenComplete(() { Get.back(); - widget.onPayCoin(_index + 1, _coinWithLike.value); + widget.onPayCoin(_pageIndex.value + 1, _coinWithLike.value); }); }); }); diff --git a/lib/pages/video/reply_reply/controller.dart b/lib/pages/video/reply_reply/controller.dart index fd1763408..074c8888a 100644 --- a/lib/pages/video/reply_reply/controller.dart +++ b/lib/pages/video/reply_reply/controller.dart @@ -170,17 +170,13 @@ class VideoReplyReplyController extends ReplyController }, transitionDuration: const Duration(milliseconds: 500), transitionBuilder: (context, animation, secondaryAnimation, child) { - const begin = Offset(0.0, 1.0); - const end = Offset.zero; - const curve = Curves.linear; - - var tween = Tween( - begin: begin, - end: end, - ).chain(CurveTween(curve: curve)); - return SlideTransition( - position: animation.drive(tween), + position: animation.drive( + Tween( + begin: const Offset(0.0, 1.0), + end: Offset.zero, + ).chain(CurveTween(curve: Curves.linear)), + ), child: child, ); }, diff --git a/lib/plugin/pl_player/view.dart b/lib/plugin/pl_player/view.dart index 02722f2dc..3e11c2b44 100644 --- a/lib/plugin/pl_player/view.dart +++ b/lib/plugin/pl_player/view.dart @@ -1603,8 +1603,8 @@ class _PLVideoPlayerState extends State child: FractionalTranslation( translation: const Offset(1, -0.4), child: Obx( - () => Visibility( - visible: plPlayerController.showControls.value, + () => Offstage( + offstage: !plPlayerController.showControls.value, child: DecoratedBox( decoration: const BoxDecoration( color: Color(0x45000000), @@ -1647,8 +1647,8 @@ class _PLVideoPlayerState extends State alignment: Alignment.centerRight, child: FractionalTranslation( translation: const Offset(-1, -0.4), - child: Visibility( - visible: plPlayerController.showControls.value, + child: Offstage( + offstage: !plPlayerController.showControls.value, child: DecoratedBox( decoration: const BoxDecoration( color: Color(0x45000000), diff --git a/lib/utils/cache_manage.dart b/lib/utils/cache_manage.dart index a6cbb1370..93d392af4 100644 --- a/lib/utils/cache_manage.dart +++ b/lib/utils/cache_manage.dart @@ -112,13 +112,13 @@ abstract class CacheManage { static Future autoClearCache() async { if (Pref.autoClearCache) { - await CacheManage.clearLibraryCache(); + await clearLibraryCache(); } else { final maxCacheSize = Pref.maxCacheSize; if (maxCacheSize != 0) { final currCache = await loadApplicationCache(); if (currCache >= maxCacheSize) { - await CacheManage.clearLibraryCache(); + await clearLibraryCache(); } } }