feat: unfollow bangumi, change followState

This commit is contained in:
bggRGjQaUbCoE
2024-10-03 12:02:03 +08:00
parent f5202beb44
commit b795d5d2b2
5 changed files with 165 additions and 22 deletions

View File

@@ -41,6 +41,7 @@
## feat
- [x] 取消/追番,更新追番状态
- [x] 取消/订阅合集
- [x] SponsorBlock
- [x] 显示视频完整合集

View File

@@ -320,6 +320,8 @@ class Api {
// 取消追番
static const String bangumiDel = '/pgc/web/follow/del';
static const String bangumiUpdate = '/pgc/web/follow/status/update';
// 番剧列表
// https://api.bilibili.com/pgc/season/index/result?
// st=1&

View File

@@ -766,6 +766,27 @@ class VideoHttp {
}
}
static Future bangumiUpdate({
dynamic seasonId,
dynamic status,
}) async {
var res = await Request().post(
Api.bangumiUpdate,
data: {
'season_id': seasonId,
'status': status,
'csrf': await Request.getCsrf(),
},
options: Options(
contentType: Headers.formUrlEncodedContentType,
),
);
return {
'status': res.data['code'] == 0,
'msg': res.data['result'] == null ? 'failed' : res.data['result']['toast']
};
}
// 查看视频同时在看人数
static Future onlineTotal({int? aid, String? bvid, int? cid}) async {
var res = await Request().get(Api.onlineTotal, data: {

View File

@@ -1,3 +1,6 @@
import 'dart:convert';
import 'package:PiliPalaX/http/init.dart';
import 'package:PiliPalaX/http/loading_state.dart';
import 'package:PiliPalaX/http/user.dart';
import 'package:PiliPalaX/pages/common/common_controller.dart';
@@ -19,6 +22,8 @@ import 'package:PiliPalaX/utils/id_utils.dart';
import 'package:PiliPalaX/utils/storage.dart';
import 'package:share_plus/share_plus.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:html/parser.dart' as html_parser;
import 'package:html/dom.dart' as dom;
class BangumiIntroController extends CommonController {
// 视频bvid
@@ -52,8 +57,6 @@ class BangumiIntroController extends CommonController {
Rx<FavFolderData> favFolderData = FavFolderData().obs;
List addMediaIdsNew = [];
List delMediaIdsNew = [];
// 关注状态 默认未关注
RxMap followStatus = {}.obs;
int _tempThemeValue = -1;
dynamic userInfo;
@@ -96,6 +99,10 @@ class BangumiIntroController extends CommonController {
}
queryData();
if (userLogin) {
queryIsFollowed();
}
}
Future queryVideoTags() async {
@@ -354,6 +361,10 @@ class BangumiIntroController extends CommonController {
Future bangumiAdd() async {
var result = await VideoHttp.bangumiAdd(
seasonId: (loadingState.value as Success).response.seasonId);
if (result['status']) {
isFollowed.value = true;
followStatus.value = 2;
}
SmartDialog.showToast(result['msg']);
}
@@ -361,6 +372,20 @@ class BangumiIntroController extends CommonController {
Future bangumiDel() async {
var result = await VideoHttp.bangumiDel(
seasonId: (loadingState.value as Success).response.seasonId);
if (result['status']) {
isFollowed.value = false;
}
SmartDialog.showToast(result['msg']);
}
Future bangumiUpdate(status) async {
var result = await VideoHttp.bangumiUpdate(
seasonId: (loadingState.value as Success).response.seasonId,
status: status,
);
if (result['status']) {
followStatus.value = status;
}
SmartDialog.showToast(result['msg']);
}
@@ -466,4 +491,22 @@ class BangumiIntroController extends CommonController {
SmartDialog.showToast(result['msg']);
}
}
RxBool isFollowed = false.obs;
RxInt followStatus = (-1).obs;
Future queryIsFollowed() async {
dynamic result = await Request().get(
'https://www.bilibili.com/bangumi/play/ss$seasonId',
);
dom.Document document = html_parser.parse(result.data);
dom.Element? scriptElement = document.querySelector('script#__NEXT_DATA__');
if (scriptElement != null) {
dynamic scriptContent = jsonDecode(scriptElement.text);
isFollowed.value =
scriptContent['props']['pageProps']['followState']['isFollowed'];
followStatus.value =
scriptContent['props']['pageProps']['followState']['followStatus'];
}
}
}

View File

@@ -261,28 +261,49 @@ class _BangumiInfoState extends State<BangumiInfo>
),
),
const SizedBox(width: 20),
SizedBox(
width: 30,
height: 30,
child: IconButton(
tooltip: '收藏',
style: ButtonStyle(
padding: MaterialStateProperty.all(
EdgeInsets.zero),
Obx(
() => FilledButton.tonal(
style: FilledButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 20, vertical: 10),
visualDensity: const VisualDensity(
horizontal: -2,
vertical: -2,
),
foregroundColor:
bangumiIntroController
.isFollowed.value
? t.colorScheme.onSurface
: null,
backgroundColor:
MaterialStateProperty.resolveWith(
(Set<MaterialState> states) {
return t
.colorScheme.primaryContainer
.withOpacity(0.7);
}),
bangumiIntroController
.isFollowed.value
? t.colorScheme
.onInverseSurface
: null,
),
onPressed: () =>
bangumiIntroController.bangumiAdd(),
icon: Icon(
Icons.favorite_border_rounded,
color: t.colorScheme.primary,
size: 22,
onPressed: bangumiIntroController
.followStatus.value ==
-1
? null
: () {
if (bangumiIntroController
.isFollowed.value) {
showDialog(
context: context,
builder: (_) =>
_followDialog(),
);
} else {
bangumiIntroController
.bangumiAdd();
}
},
child: Text(
bangumiIntroController
.isFollowed.value
? '已追番'
: '追番',
),
),
),
@@ -552,6 +573,61 @@ class _BangumiInfoState extends State<BangumiInfo>
text: '转发'),
]);
}
Widget _followDialog() {
return Dialog(
clipBehavior: Clip.hardEdge,
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
_followDialogItem(3, '看过'),
_followDialogItem(2, '在看'),
_followDialogItem(1, '想看'),
ListTile(
dense: true,
title: const Padding(
padding: EdgeInsets.only(left: 10),
child: Text(
'取消追番',
style: TextStyle(fontSize: 14),
),
),
onTap: () {
Get.back();
bangumiIntroController.bangumiDel();
},
)
],
),
),
);
}
Widget _followDialogItem(
int followStatus,
String text,
) {
return ListTile(
dense: true,
enabled: bangumiIntroController.followStatus.value != followStatus,
title: Padding(
padding: const EdgeInsets.only(left: 10),
child: Text(
'标记为 $text',
style: const TextStyle(fontSize: 14),
),
),
trailing: bangumiIntroController.followStatus.value == followStatus
? const Icon(size: 22, Icons.check)
: null,
onTap: () {
Get.back();
bangumiIntroController.bangumiUpdate(followStatus);
},
);
}
}
class AreasAndPubTime extends StatelessWidget {