mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
feat: unfollow bangumi, change followState
This commit is contained in:
@@ -41,6 +41,7 @@
|
||||
|
||||
## feat
|
||||
|
||||
- [x] 取消/追番,更新追番状态
|
||||
- [x] 取消/订阅合集
|
||||
- [x] SponsorBlock
|
||||
- [x] 显示视频完整合集
|
||||
|
||||
@@ -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&
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user