mod: remove disliked rcmd

Closes #80

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-01-01 11:35:01 +08:00
parent 1dd7b9ed0a
commit dda0fc15c7
11 changed files with 124 additions and 96 deletions

View File

@@ -1,7 +1,6 @@
import 'package:PiliPalaX/common/widgets/image_save.dart'; import 'package:PiliPalaX/common/widgets/image_save.dart';
import 'package:PiliPalaX/http/search.dart'; import 'package:PiliPalaX/http/search.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import '../../models/home/rcmd/result.dart'; import '../../models/home/rcmd/result.dart';
@@ -19,10 +18,12 @@ import 'video_popup_menu.dart';
// 视频卡片 - 垂直布局 // 视频卡片 - 垂直布局
class VideoCardV extends StatelessWidget { class VideoCardV extends StatelessWidget {
final dynamic videoItem; final dynamic videoItem;
final VoidCallback? onRemove;
const VideoCardV({ const VideoCardV({
super.key, super.key,
required this.videoItem, required this.videoItem,
this.onRemove,
}); });
bool isStringNumeric(String str) { bool isStringNumeric(String str) {
@@ -208,6 +209,7 @@ class VideoCardV extends StatelessWidget {
size: 29, size: 29,
iconSize: 17, iconSize: 17,
videoItem: videoItem, videoItem: videoItem,
onRemove: onRemove,
), ),
), ),
]); ]);

View File

@@ -1,3 +1,4 @@
import 'package:PiliPalaX/pages/search/widgets/search_text.dart';
import 'package:PiliPalaX/utils/utils.dart'; import 'package:PiliPalaX/utils/utils.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
@@ -23,7 +24,9 @@ class VideoCustomActions {
dynamic videoItem; dynamic videoItem;
BuildContext context; BuildContext context;
late List<VideoCustomAction> actions; late List<VideoCustomAction> actions;
VideoCustomActions(this.videoItem, this.context) { VoidCallback? onRemove;
VideoCustomActions(this.videoItem, this.context, [this.onRemove]) {
actions = [ actions = [
if ((videoItem.bvid as String?)?.isNotEmpty == true) if ((videoItem.bvid as String?)?.isNotEmpty == true)
VideoCustomAction( VideoCustomAction(
@@ -82,12 +85,10 @@ class VideoCustomActions {
return; return;
} }
Widget actionButton(DislikeReason? r, FeedbackReason? f) { Widget actionButton(DislikeReason? r, FeedbackReason? f) {
return ElevatedButton( return SearchText(
style: ElevatedButton.styleFrom( text: r?.name ?? f?.name ?? '未知',
padding: const EdgeInsets.symmetric( onTap: (_) async {
horizontal: 12.0, vertical: 0.0), Get.back();
),
onPressed: () async {
SmartDialog.showLoading(msg: '正在提交'); SmartDialog.showLoading(msg: '正在提交');
var res = await VideoHttp.feedDislike( var res = await VideoHttp.feedDislike(
reasonId: r?.id, reasonId: r?.id,
@@ -97,10 +98,12 @@ class VideoCustomActions {
); );
SmartDialog.dismiss(); SmartDialog.dismiss();
SmartDialog.showToast( SmartDialog.showToast(
res['status'] ? (r?.toast ?? f?.toast) : res['msg']); res['status'] ? (r?.toast ?? f?.toast) : res['msg'],
Get.back(); );
if (res['status']) {
onRemove?.call();
}
}, },
child: Text(r?.name ?? f?.name ?? '未知'),
); );
} }
@@ -108,53 +111,57 @@ class VideoCustomActions {
context: context, context: context,
builder: (context) { builder: (context) {
return AlertDialog( return AlertDialog(
title: const Text('请选择'),
content: SingleChildScrollView( content: SingleChildScrollView(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
if (tp.dislikeReasons != null) if (tp.dislikeReasons != null) ...[
const Padding( Text('我不想看'),
padding: EdgeInsets.symmetric(vertical: 8.0), const SizedBox(height: 5),
child: Text('我不想看'),
),
if (tp.dislikeReasons != null)
Wrap( Wrap(
spacing: 5.0, spacing: 8.0,
runSpacing: 2.0, runSpacing: 8.0,
children: tp.dislikeReasons!.map((item) { children: tp.dislikeReasons!.map((item) {
return actionButton(item, null); return actionButton(item, null);
}).toList(), }).toList(),
), ),
if (tp.feedbacks != null) ],
const Padding( if (tp.feedbacks != null) ...[
padding: EdgeInsets.symmetric(vertical: 8.0), const SizedBox(height: 5),
child: Text('反馈'), Text('反馈'),
), const SizedBox(height: 5),
if (tp.feedbacks != null)
Wrap( Wrap(
spacing: 5.0, spacing: 8.0,
runSpacing: 2.0, runSpacing: 8.0,
children: tp.feedbacks!.map((item) { children: tp.feedbacks!.map((item) {
return actionButton(null, item); return actionButton(null, item);
}).toList(), }).toList(),
), ),
//分割线 ],
const Divider(), const Divider(),
ElevatedButton( Center(
onPressed: () async { child: FilledButton.tonal(
SmartDialog.showLoading(msg: '正在提交'); onPressed: () async {
var res = await VideoHttp.feedDislikeCancel( SmartDialog.showLoading(msg: '正在提交');
// reasonId: r?.id, var res = await VideoHttp.feedDislikeCancel(
// feedbackId: f?.id, // reasonId: r?.id,
id: v.param!, // feedbackId: f?.id,
goto: v.goto!, id: v.param!,
); goto: v.goto!,
SmartDialog.dismiss(); );
SmartDialog.showToast( SmartDialog.dismiss();
res['status'] ? "成功" : res['msg']); SmartDialog.showToast(
Get.back(); res['status'] ? "成功" : res['msg']);
}, Get.back();
child: const Text("撤销"), },
style: FilledButton.styleFrom(
visualDensity: VisualDensity(
horizontal: -2,
vertical: -2,
),
),
child: const Text("撤销"),
),
), ),
], ],
), ),
@@ -167,7 +174,6 @@ class VideoCustomActions {
context: context, context: context,
builder: (context) { builder: (context) {
return AlertDialog( return AlertDialog(
title: const Text('点踩该视频?'),
content: SingleChildScrollView( content: SingleChildScrollView(
child: Column( child: Column(
children: [ children: [
@@ -178,20 +184,28 @@ class VideoCustomActions {
spacing: 5.0, spacing: 5.0,
runSpacing: 2.0, runSpacing: 2.0,
children: [ children: [
ElevatedButton( FilledButton.tonal(
onPressed: () async { onPressed: () async {
Get.back();
SmartDialog.showLoading(msg: '正在提交'); SmartDialog.showLoading(msg: '正在提交');
var res = await VideoHttp.dislikeVideo( var res = await VideoHttp.dislikeVideo(
bvid: videoItem.bvid as String, type: true); bvid: videoItem.bvid as String, type: true);
SmartDialog.dismiss(); SmartDialog.dismiss();
SmartDialog.showToast( SmartDialog.showToast(
res['status'] ? "点踩成功" : res['msg']); res['status'] ? "点踩成功" : res['msg'],
Get.back(); );
}, },
style: FilledButton.styleFrom(
visualDensity: VisualDensity(
horizontal: -2,
vertical: -2,
),
),
child: const Text("点踩"), child: const Text("点踩"),
), ),
ElevatedButton( FilledButton.tonal(
onPressed: () async { onPressed: () async {
Get.back();
SmartDialog.showLoading(msg: '正在提交'); SmartDialog.showLoading(msg: '正在提交');
var res = await VideoHttp.dislikeVideo( var res = await VideoHttp.dislikeVideo(
bvid: videoItem.bvid as String, bvid: videoItem.bvid as String,
@@ -199,8 +213,13 @@ class VideoCustomActions {
SmartDialog.dismiss(); SmartDialog.dismiss();
SmartDialog.showToast( SmartDialog.showToast(
res['status'] ? "取消踩" : res['msg']); res['status'] ? "取消踩" : res['msg']);
Get.back();
}, },
style: FilledButton.styleFrom(
visualDensity: VisualDensity(
horizontal: -2,
vertical: -2,
),
),
child: const Text("撤销"), child: const Text("撤销"),
), ),
], ],
@@ -272,12 +291,14 @@ class VideoPopupMenu extends StatelessWidget {
final double? iconSize; final double? iconSize;
final double menuItemHeight = 45; final double menuItemHeight = 45;
final dynamic videoItem; final dynamic videoItem;
final VoidCallback? onRemove;
const VideoPopupMenu({ const VideoPopupMenu({
super.key, super.key,
required this.size, required this.size,
required this.iconSize, required this.iconSize,
required this.videoItem, required this.videoItem,
this.onRemove,
}); });
@override @override
@@ -296,7 +317,7 @@ class VideoPopupMenu extends StatelessWidget {
position: PopupMenuPosition.under, position: PopupMenuPosition.under,
onSelected: (String type) {}, onSelected: (String type) {},
itemBuilder: (BuildContext context) => itemBuilder: (BuildContext context) =>
VideoCustomActions(videoItem, context).actions.map((e) { VideoCustomActions(videoItem, context, onRemove).actions.map((e) {
return PopupMenuItem<String>( return PopupMenuItem<String>(
value: e.value, value: e.value,
height: menuItemHeight, height: menuItemHeight,

View File

@@ -121,10 +121,10 @@ class IntroDetail extends StatelessWidget {
.map( .map(
(item) => SearchText( (item) => SearchText(
fontSize: 13, fontSize: 13,
searchText: item['tag_name'], text: item['tag_name'],
onSelect: (_) => Get.toNamed('/searchResult', onTap: (_) => Get.toNamed('/searchResult',
parameters: {'keyword': item['tag_name']}), parameters: {'keyword': item['tag_name']}),
onLongSelect: (_) => onLongPress: (_) =>
Utils.copyText(item['tag_name']), Utils.copyText(item['tag_name']),
), ),
) )

View File

@@ -128,6 +128,10 @@ class _RcmdPageState extends State<RcmdPage>
? widget.tabType == TabType.rcmd ? widget.tabType == TabType.rcmd
? VideoCardV( ? VideoCardV(
videoItem: loadingState.response[index], videoItem: loadingState.response[index],
onRemove: () {
_controller.loadingState.value = LoadingState.success(
(loadingState.response as List)..removeAt(index));
},
) )
: LiveCardV( : LiveCardV(
liveItem: loadingState.response[index], liveItem: loadingState.response[index],

View File

@@ -217,9 +217,9 @@ class _SearchPageState extends State<SearchPage> with RouteAware {
children: _searchController.historyList children: _searchController.historyList
.map( .map(
(item) => SearchText( (item) => SearchText(
searchText: item, text: item,
onSelect: _searchController.onClickKeyword, onTap: _searchController.onClickKeyword,
onLongSelect: _searchController.onLongSelect, onLongPress: _searchController.onLongSelect,
), ),
) )
.toList(), .toList(),

View File

@@ -1,18 +1,19 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class SearchText extends StatelessWidget { class SearchText extends StatelessWidget {
final String? searchText; final String text;
final Function? onSelect; final ValueChanged<String>? onTap;
final Function? onLongSelect; final ValueChanged<String>? onLongPress;
final double? fontSize; final double? fontSize;
final Color? bgColor; final Color? bgColor;
final Color? textColor; final Color? textColor;
final TextAlign? textAlign; final TextAlign? textAlign;
const SearchText({ const SearchText({
super.key, super.key,
this.searchText, required this.text,
this.onSelect, this.onTap,
this.onLongSelect, this.onLongPress,
this.fontSize, this.fontSize,
this.bgColor, this.bgColor,
this.textColor, this.textColor,
@@ -28,17 +29,17 @@ class SearchText extends StatelessWidget {
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
child: InkWell( child: InkWell(
onTap: () { onTap: () {
onSelect?.call(searchText); onTap?.call(text);
}, },
onLongPress: () { onLongPress: () {
onLongSelect?.call(searchText); onLongPress?.call(text);
}, },
borderRadius: BorderRadius.circular(6), borderRadius: BorderRadius.circular(6),
child: Padding( child: Padding(
padding: padding:
const EdgeInsets.only(top: 5, bottom: 5, left: 11, right: 11), const EdgeInsets.only(top: 5, bottom: 5, left: 11, right: 11),
child: Text( child: Text(
searchText!, text,
textAlign: textAlign, textAlign: textAlign,
style: TextStyle( style: TextStyle(
fontSize: fontSize, fontSize: fontSize,

View File

@@ -283,8 +283,8 @@ class ArticlePanelController extends GetxController {
children: orderFiltersList children: orderFiltersList
.map( .map(
(item) => SearchText( (item) => SearchText(
searchText: item['label'], text: item['label'],
onSelect: (_) async { onTap: (_) async {
Get.back(); Get.back();
currentOrderFilterval.value = item['value']; currentOrderFilterval.value = item['value'];
SmartDialog.dismiss(); SmartDialog.dismiss();
@@ -297,7 +297,7 @@ class ArticlePanelController extends GetxController {
await ctr.onRefresh(); await ctr.onRefresh();
SmartDialog.dismiss(); SmartDialog.dismiss();
}, },
onLongSelect: (_) {}, onLongPress: (_) {},
bgColor: item['value'] == currentOrderFilterval.value bgColor: item['value'] == currentOrderFilterval.value
? Theme.of(context).colorScheme.secondaryContainer ? Theme.of(context).colorScheme.secondaryContainer
: null, : null,
@@ -317,8 +317,8 @@ class ArticlePanelController extends GetxController {
children: zoneFiltersList children: zoneFiltersList
.map( .map(
(item) => SearchText( (item) => SearchText(
searchText: item['label'], text: item['label'],
onSelect: (_) async { onTap: (_) async {
Get.back(); Get.back();
currentZoneFilterval.value = item['value']; currentZoneFilterval.value = item['value'];
SmartDialog.dismiss(); SmartDialog.dismiss();
@@ -331,7 +331,7 @@ class ArticlePanelController extends GetxController {
await ctr.onRefresh(); await ctr.onRefresh();
SmartDialog.dismiss(); SmartDialog.dismiss();
}, },
onLongSelect: (_) {}, onLongPress: (_) {},
bgColor: item['value'] == currentZoneFilterval.value bgColor: item['value'] == currentZoneFilterval.value
? Theme.of(context).colorScheme.secondaryContainer ? Theme.of(context).colorScheme.secondaryContainer
: null, : null,

View File

@@ -206,8 +206,8 @@ class UserPanelController extends GetxController {
children: orderFiltersList children: orderFiltersList
.map( .map(
(item) => SearchText( (item) => SearchText(
searchText: item['label'], text: item['label'],
onSelect: (_) async { onTap: (_) async {
Get.back(); Get.back();
currentOrderFilterval.value = item['value']; currentOrderFilterval.value = item['value'];
SmartDialog.dismiss(); SmartDialog.dismiss();
@@ -221,7 +221,7 @@ class UserPanelController extends GetxController {
await ctr.onRefresh(); await ctr.onRefresh();
SmartDialog.dismiss(); SmartDialog.dismiss();
}, },
onLongSelect: (_) {}, onLongPress: (_) {},
bgColor: item['value'] == currentOrderFilterval.value bgColor: item['value'] == currentOrderFilterval.value
? Theme.of(context).colorScheme.secondaryContainer ? Theme.of(context).colorScheme.secondaryContainer
: null, : null,
@@ -241,8 +241,8 @@ class UserPanelController extends GetxController {
children: userTypeFiltersList children: userTypeFiltersList
.map( .map(
(item) => SearchText( (item) => SearchText(
searchText: item['label'], text: item['label'],
onSelect: (_) async { onTap: (_) async {
Get.back(); Get.back();
currentUserTypeFilterval.value = item['value']; currentUserTypeFilterval.value = item['value'];
SmartDialog.dismiss(); SmartDialog.dismiss();
@@ -255,7 +255,7 @@ class UserPanelController extends GetxController {
await ctr.onRefresh(); await ctr.onRefresh();
SmartDialog.dismiss(); SmartDialog.dismiss();
}, },
onLongSelect: (_) {}, onLongPress: (_) {},
bgColor: item['value'] == currentUserTypeFilterval.value bgColor: item['value'] == currentUserTypeFilterval.value
? Theme.of(context).colorScheme.secondaryContainer ? Theme.of(context).colorScheme.secondaryContainer
: null, : null,

View File

@@ -255,10 +255,10 @@ class VideoPanelController extends GetxController {
builder: (context, setState) { builder: (context, setState) {
Widget dateWidget([bool isFirst = true]) { Widget dateWidget([bool isFirst = true]) {
return SearchText( return SearchText(
searchText: text:
DateFormat('yyyy-MM-dd').format(isFirst ? pubBegin : pubEnd), DateFormat('yyyy-MM-dd').format(isFirst ? pubBegin : pubEnd),
textAlign: TextAlign.center, textAlign: TextAlign.center,
onSelect: (text) { onTap: (text) {
showDatePicker( showDatePicker(
context: context, context: context,
initialDate: isFirst ? pubBegin : pubEnd, initialDate: isFirst ? pubBegin : pubEnd,
@@ -303,7 +303,7 @@ class VideoPanelController extends GetxController {
} }
}); });
}, },
onLongSelect: (_) {}, onLongPress: (_) {},
bgColor: currentPubTimeFilterval == -1 && bgColor: currentPubTimeFilterval == -1 &&
(isFirst ? customPubBegin : customPubEnd) (isFirst ? customPubBegin : customPubEnd)
? Theme.of(context).colorScheme.secondaryContainer ? Theme.of(context).colorScheme.secondaryContainer
@@ -337,8 +337,8 @@ class VideoPanelController extends GetxController {
children: pubTimeFiltersList children: pubTimeFiltersList
.map( .map(
(item) => SearchText( (item) => SearchText(
searchText: item['label'], text: item['label'],
onSelect: (text) async { onTap: (text) async {
Get.back(); Get.back();
currentPubTimeFilterval = item['value']; currentPubTimeFilterval = item['value'];
SmartDialog.dismiss(); SmartDialog.dismiss();
@@ -379,7 +379,7 @@ class VideoPanelController extends GetxController {
await ctr.onRefresh(); await ctr.onRefresh();
SmartDialog.dismiss(); SmartDialog.dismiss();
}, },
onLongSelect: (_) {}, onLongPress: (_) {},
bgColor: item['value'] == currentPubTimeFilterval bgColor: item['value'] == currentPubTimeFilterval
? Theme.of(context) ? Theme.of(context)
.colorScheme .colorScheme
@@ -416,8 +416,8 @@ class VideoPanelController extends GetxController {
children: timeFiltersList children: timeFiltersList
.map( .map(
(item) => SearchText( (item) => SearchText(
searchText: item['label'], text: item['label'],
onSelect: (text) async { onTap: (text) async {
Get.back(); Get.back();
currentTimeFilterval = item['value']; currentTimeFilterval = item['value'];
SmartDialog.dismiss(); SmartDialog.dismiss();
@@ -430,7 +430,7 @@ class VideoPanelController extends GetxController {
await ctr.onRefresh(); await ctr.onRefresh();
SmartDialog.dismiss(); SmartDialog.dismiss();
}, },
onLongSelect: (_) {}, onLongPress: (_) {},
bgColor: item['value'] == currentTimeFilterval bgColor: item['value'] == currentTimeFilterval
? Theme.of(context) ? Theme.of(context)
.colorScheme .colorScheme
@@ -454,8 +454,8 @@ class VideoPanelController extends GetxController {
children: zoneFiltersList children: zoneFiltersList
.map( .map(
(item) => SearchText( (item) => SearchText(
searchText: item['label'], text: item['label'],
onSelect: (text) async { onTap: (text) async {
Get.back(); Get.back();
currentZoneFilterval = item['value']; currentZoneFilterval = item['value'];
SmartDialog.dismiss(); SmartDialog.dismiss();
@@ -468,7 +468,7 @@ class VideoPanelController extends GetxController {
await ctr.onRefresh(); await ctr.onRefresh();
SmartDialog.dismiss(); SmartDialog.dismiss();
}, },
onLongSelect: (_) {}, onLongPress: (_) {},
bgColor: item['value'] == currentZoneFilterval bgColor: item['value'] == currentZoneFilterval
? Theme.of(context) ? Theme.of(context)
.colorScheme .colorScheme

View File

@@ -620,12 +620,12 @@ class _VideoInfoState extends State<VideoInfo> with TickerProviderStateMixin {
.map( .map(
(item) => SearchText( (item) => SearchText(
fontSize: 13, fontSize: 13,
searchText: item['tag_name'], text: item['tag_name'],
onSelect: (_) => Get.toNamed('/searchResult', onTap: (_) => Get.toNamed('/searchResult',
parameters: { parameters: {
'keyword': item['tag_name'] 'keyword': item['tag_name']
}), }),
onLongSelect: (_) => onLongPress: (_) =>
Utils.copyText(item['tag_name']), Utils.copyText(item['tag_name']),
), ),
) )

View File

@@ -86,10 +86,10 @@ class IntroDetail extends StatelessWidget {
.map( .map(
(item) => SearchText( (item) => SearchText(
fontSize: 13, fontSize: 13,
searchText: item['tag_name'], text: item['tag_name'],
onSelect: (_) => Get.toNamed('/searchResult', onTap: (_) => Get.toNamed('/searchResult',
parameters: {'keyword': item['tag_name']}), parameters: {'keyword': item['tag_name']}),
onLongSelect: (_) => onLongPress: (_) =>
Utils.copyText(item['tag_name']), Utils.copyText(item['tag_name']),
), ),
) )