diff --git a/assets/images/paycoins/ic_panel_close.png b/assets/images/paycoins/ic_panel_close.png new file mode 100644 index 00000000..dbacb931 Binary files /dev/null and b/assets/images/paycoins/ic_panel_close.png differ diff --git a/lib/http/video.dart b/lib/http/video.dart index ae8d01cd..12115fc8 100644 --- a/lib/http/video.dart +++ b/lib/http/video.dart @@ -421,14 +421,18 @@ class VideoHttp { } // 投币 - static Future coinVideo({required String bvid, required int multiply}) async { + static Future coinVideo({ + required String bvid, + required int multiply, + int selectLike = 0, + }) async { var res = await Request().post( Api.coinVideo, queryParameters: { 'aid': IdUtils.bv2av(bvid), // 'bvid': bvid, 'multiply': multiply, - 'select_like': 0, + 'select_like': selectLike, 'access_key': GStorage.localCache .get(LocalCacheKey.accessKey, defaultValue: {})['value'], // 'csrf': await Request.getCsrf(), diff --git a/lib/pages/video/detail/introduction/controller.dart b/lib/pages/video/detail/introduction/controller.dart index 0fe74be1..4b5a8ab9 100644 --- a/lib/pages/video/detail/introduction/controller.dart +++ b/lib/pages/video/detail/introduction/controller.dart @@ -309,16 +309,24 @@ class VideoIntroController extends GetxController } } - void coinVideo(int coin) async { + void coinVideo(int coin, [bool selectLike = false]) async { if (videoDetail.value.stat?.coin == null) { // not init return; } - var res = await VideoHttp.coinVideo(bvid: bvid, multiply: coin); + var res = await VideoHttp.coinVideo( + bvid: bvid, + multiply: coin, + selectLike: selectLike ? 1 : 0, + ); if (res['status']) { SmartDialog.showToast('投币成功'); hasCoin.value = true; videoDetail.value.stat!.coin = videoDetail.value.stat!.coin! + coin; + if (selectLike && hasLike.value.not) { + hasLike.value = true; + videoDetail.value.stat!.like = videoDetail.value.stat!.like! + 1; + } } else { SmartDialog.showToast(res['msg']); } diff --git a/lib/pages/video/detail/introduction/pay_coins_page.dart b/lib/pages/video/detail/introduction/pay_coins_page.dart index 93c74a4f..2babd958 100644 --- a/lib/pages/video/detail/introduction/pay_coins_page.dart +++ b/lib/pages/video/detail/introduction/pay_coins_page.dart @@ -1,6 +1,8 @@ import 'dart:async'; import 'dart:math'; +import 'package:PiliPlus/utils/extension.dart'; +import 'package:PiliPlus/utils/storage.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; @@ -22,6 +24,8 @@ class _PayCoinsPageState extends State with TickerProviderStateMixin { bool _isPaying = false; late final _controller = PageController(viewportFraction: 0.30); + late final RxBool _coinWithLike = GStorage.coinWithLike.obs; + final _key = GlobalKey(); int get _index => _controller.hasClients ? _controller.page?.round() ?? 0 : 0; @@ -96,11 +100,20 @@ class _PayCoinsPageState extends State @override Widget build(BuildContext context) { return LayoutBuilder(builder: (context, constraints) { - return _buildBody(constraints.maxHeight > constraints.maxWidth); + bool isV = constraints.maxHeight > constraints.maxWidth; + return isV + ? _buildBody(isV) + : Row( + children: [ + const Spacer(), + Expanded(child: _buildBody(isV)), + ], + ); }); } Widget _buildBody(isV) => Stack( + key: _key, alignment: Alignment.center, children: [ Visibility( @@ -110,168 +123,226 @@ class _PayCoinsPageState extends State maintainState: true, child: Image.asset(_images[_showThunder ? _imageIndex : 0]), ), - Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Row( + Align( + alignment: Alignment.bottomCenter, + child: GestureDetector( + behavior: HitTestBehavior.opaque, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, 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', + 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( - 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: Stack( - alignment: Alignment.center, - children: [ - SlideTransition( - position: _boxAnimController.drive( - Tween( - begin: const Offset(0.0, 0.0), - end: const Offset(0.0, -0.2), + Expanded( + child: SizedBox( + height: 100, + child: PageView.builder( + key: PageStorageKey('PageView'), + 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: Stack( + alignment: Alignment.center, + children: [ + SlideTransition( + position: + _boxAnimController.drive( + Tween( + begin: const Offset(0.0, 0.0), + end: const Offset(0.0, -0.2), + ), + ), + child: Image.asset( + 'assets/images/paycoins/ic_pay_coins_box.png', + ), ), - ), - child: Image.asset( - 'assets/images/paycoins/ic_pay_coins_box.png', - ), + SlideTransition( + position: + _coinSlideController.drive( + Tween( + begin: const Offset(0.0, 0.0), + end: const Offset(0.0, -2), + ), + ), + child: FadeTransition( + opacity: Tween( + begin: 1, end: 0) + .animate( + _coinFadeController), + 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', + ), + ), + ), + ], ), - SlideTransition( - position: _coinSlideController.drive( - Tween( - begin: const Offset(0.0, 0.0), - end: const Offset(0.0, -2), - ), - ), - child: FadeTransition( - opacity: Tween( - begin: 1, end: 0) - .animate(_coinFadeController), - 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', - ), - ), - ), - ], + ), ), - ), - ), + ); + }, ); }, + ), + ), + ), + 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: _onPayCoin, + onPanUpdate: (e) => _handlePanUpdate(e, true), + child: ScaleTransition( + scale: _scale22Controller.drive( + Tween(begin: 1, end: 1.1), + ), + child: SlideTransition( + position: _slide22Controller.drive( + Tween( + begin: const Offset(0.0, 0.0), + end: const Offset(0.0, -0.2), + ), + ), + child: SizedBox( + width: 110, + height: 155, + child: Image.asset( + _index == 0 + ? 'assets/images/paycoins/ic_22_mario.png' + : 'assets/images/paycoins/ic_22_gun_sister.png', + ), + ), + ), + ), + ), + ), + ), + ), + const SizedBox(height: 10), + Stack( + alignment: Alignment.centerLeft, + children: [ + GestureDetector( + onTap: () { + _coinWithLike.value = _coinWithLike.value.not; + GStorage.setting.put( + SettingBoxKey.coinWithLike, + _coinWithLike.value, ); }, - ), - ), - ), - 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', + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + const SizedBox(width: 12), + Obx( + () => Icon( + _coinWithLike.value + ? Icons.check_box_outlined + : Icons.check_box_outline_blank, + size: 20, + ), + ), + const Text( + ' 同时点赞', + style: TextStyle(color: Colors.white), + ), + ], ), ), - ), + Center( + child: GestureDetector( + onTap: Get.back, + child: SizedBox( + width: 30, + height: 30, + child: Image.asset( + 'assets/images/paycoins/ic_panel_close.png', + ), + ), + ), + ), + ], ), + SizedBox( + height: (isV ? 50 : 10) + + MediaQuery.of(context).padding.bottom), ], ), - const SizedBox(height: 25), - GestureDetector( - behavior: HitTestBehavior.opaque, - onPanUpdate: _handlePanUpdate, - child: SizedBox( - width: double.infinity, - height: 140, - child: Center( - child: GestureDetector( - onTap: _onPayCoin, - onPanUpdate: (e) => _handlePanUpdate(e, true), - child: ScaleTransition( - scale: _scale22Controller.drive( - Tween(begin: 1, end: 1.2), - ), - child: SlideTransition( - position: _slide22Controller.drive( - Tween( - begin: const Offset(0.0, 0.0), - end: const Offset(0.0, -0.2), - ), - ), - child: SizedBox( - width: 100, - height: 140, - child: Image.asset( - _index == 0 - ? 'assets/images/paycoins/ic_22_mario.png' - : 'assets/images/paycoins/ic_22_gun_sister.png', - ), - ), - ), - ), - ), - ), - ), - ), - SizedBox( - height: - (isV ? 50 : 0) + MediaQuery.of(context).padding.bottom), - ], + ), ), ], ); @@ -321,7 +392,7 @@ class _PayCoinsPageState extends State _coinSlideController.forward().whenComplete(() { _coinFadeController.forward().whenComplete(() { Get.back(); - widget.callback(_index + 1); + widget.callback(_index + 1, _coinWithLike.value); }); }); }); diff --git a/lib/utils/storage.dart b/lib/utils/storage.dart index 2112c415..72accc89 100644 --- a/lib/utils/storage.dart +++ b/lib/utils/storage.dart @@ -364,6 +364,9 @@ class GStorage { static bool get enableCommAntifraud => GStorage.setting .get(SettingBoxKey.enableCommAntifraud, defaultValue: false); + static bool get coinWithLike => + GStorage.setting.get(SettingBoxKey.coinWithLike, defaultValue: false); + static List get dynamicDetailRatio => List.from(setting .get(SettingBoxKey.dynamicDetailRatio, defaultValue: [60.0, 40.0])); @@ -595,6 +598,7 @@ class SettingBoxKey { showSeekPreview = 'showSeekPreview', showDmChart = 'showDmChart', enableCommAntifraud = 'enableCommAntifraud', + coinWithLike = 'coinWithLike', // Sponsor Block enableSponsorBlock = 'enableSponsorBlock',