Skip to content

Commit

Permalink
feat: 重构选集功能,播放器添加选集,修复连播退全屏、无法保存已看完状态
Browse files Browse the repository at this point in the history
  • Loading branch information
orz12 committed Apr 5, 2024
1 parent df461c2 commit 3776cfe
Show file tree
Hide file tree
Showing 15 changed files with 728 additions and 674 deletions.
169 changes: 169 additions & 0 deletions lib/common/widgets/list_sheet.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
import 'package:flutter/material.dart';
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';

import '../../utils/storage.dart';
import '../../utils/utils.dart';

class ListSheet {
final dynamic episodes;
final String? bvid;
final int? aid;
final int currentCid;
final Function changeFucCall;
final BuildContext context;
PersistentBottomSheetController? bottomSheetController;
ListSheet({
required this.episodes,
this.bvid,
this.aid,
required this.currentCid,
required this.changeFucCall,
required this.context,
});

Widget buildEpisodeListItem(
dynamic episode,
int index,
bool isCurrentIndex,
PersistentBottomSheetController bottomSheetController,
) {
Color primary = Theme.of(context).colorScheme.primary;
late String title;
if (episode.runtimeType.toString() == "EpisodeItem") {
if (episode.longTitle != null && episode.longTitle != "") {
title = "第${(episode.title ?? '${index + 1}')}话 ${episode.longTitle!}";
} else {
title = episode.title!;
}
} else if (episode.runtimeType.toString() == "PageItem") {
title = episode.pagePart!;
} else if (episode.runtimeType.toString() == "Part") {
title = episode.pagePart!;
// print("未知类型:${episode.runtimeType}");
}
return ListTile(
onTap: () {
if (episode.badge != null && episode.badge == "会员") {
dynamic userInfo = GStrorage.userInfo.get('userInfoCache');
int vipStatus = 0;
if (userInfo != null) {
vipStatus = userInfo.vipStatus;
}
if (vipStatus != 1) {
SmartDialog.showToast('需要大会员');
return;
}
}
SmartDialog.showToast('切换到:$title');
bottomSheetController.close();
print(episode.runtimeType.toString());
if (episode.runtimeType.toString() == "EpisodeItem") {
print(episode.bvid);
print(episode.cid);
print(episode.aid);
changeFucCall(episode.bvid, episode.cid, episode.aid);
} else {
changeFucCall(bvid!, episode.cid, aid!);
}
},
dense: false,
leading: isCurrentIndex
? Image.asset(
'assets/images/live.png',
color: primary,
height: 12,
semanticLabel: "正在播放:",
)
: null,
title: Text(
title,
style: TextStyle(
fontSize: 14,
color: isCurrentIndex
? primary
: Theme.of(context).colorScheme.onSurface,
),
),
trailing: episode.badge == null
? null
: (episode.badge == '会员'
? Image.asset(
'assets/images/big-vip.png',
height: 20,
semanticLabel: "大会员",
)
: Text(episode.badge)),
);
}

void buildShowBottomSheet() {
int currentIndex =
episodes!.indexWhere((dynamic e) => e.cid == currentCid) ?? 0;
final ItemScrollController itemScrollController = ItemScrollController();
bottomSheetController = showBottomSheet(
context: context,
builder: (BuildContext context) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setState) {
WidgetsBinding.instance.addPostFrameCallback((_) async {
itemScrollController.jumpTo(index: currentIndex);
});
return Container(
height: Utils.getSheetHeight(context),
color: Theme.of(context).colorScheme.background,
child: Column(
children: [
Container(
height: 45,
padding: const EdgeInsets.only(left: 14, right: 14),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'合集(${episodes!.length})',
style: Theme.of(context).textTheme.titleMedium,
),
IconButton(
tooltip: '关闭',
icon: const Icon(Icons.close),
onPressed: () => bottomSheetController!.close(),
),
],
),
),
Divider(
height: 1,
color: Theme.of(context).dividerColor.withOpacity(0.1),
),
Expanded(
child: Material(
child: ScrollablePositionedList.builder(
itemCount: episodes!.length + 1,
itemBuilder: (BuildContext context, int index) {
bool isLastItem = index == episodes!.length;
bool isCurrentIndex = currentIndex == index;
return isLastItem
? SizedBox(
height:
MediaQuery.of(context).padding.bottom + 20,
)
: buildEpisodeListItem(
episodes![index],
index,
isCurrentIndex,
bottomSheetController!,
);
},
itemScrollController: itemScrollController,
),
),
),
],
),
);
});
},
);
}
}
10 changes: 10 additions & 0 deletions lib/models/video_detail_res.dart
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,7 @@ class Part {
String? weblink;
Dimension? dimension;
String? firstFrame;
String? badge;

Part({
this.cid,
Expand All @@ -389,6 +390,7 @@ class Part {
this.weblink,
this.dimension,
this.firstFrame,
this.badge,
});

fromRawJson(String str) => Part.fromJson(json.decode(str));
Expand All @@ -407,6 +409,7 @@ class Part {
? null
: Dimension.fromJson(json["dimension"]);
firstFrame = json["first_frame"];
badge = json["badge"];
}

Map<String, dynamic> toJson() {
Expand All @@ -420,6 +423,7 @@ class Part {
data["weblink"] = weblink;
data["dimension"] = dimension?.toJson();
data["first_frame"] = firstFrame;
data["badge"] = badge;
return data;
}
}
Expand Down Expand Up @@ -627,19 +631,23 @@ class EpisodeItem {
this.aid,
this.cid,
this.title,
this.longTitle,
this.attribute,
this.page,
this.bvid,
this.badge,
});
int? seasonId;
int? sectionId;
int? id;
int? aid;
int? cid;
String? title;
String? longTitle;
int? attribute;
Part? page;
String? bvid;
String? badge;

EpisodeItem.fromJson(Map<String, dynamic> json) {
seasonId = json['season_id'];
Expand All @@ -648,8 +656,10 @@ class EpisodeItem {
aid = json['aid'];
cid = json['cid'];
title = json['title'];
longTitle = json['long_title'];
attribute = json['attribute'];
page = Part.fromJson(json['page']);
bvid = json['bvid'];
badge = json['badge'];
}
}
9 changes: 6 additions & 3 deletions lib/pages/bangumi/introduction/controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ class BangumiIntroController extends GetxController {
}

/// 列表循环或者顺序播放时,自动播放下一个
void nextPlay() {
bool nextPlay() {
late List episodes;
if (bangumiDetail.value.episodes != null) {
episodes = bangumiDetail.value.episodes!;
Expand All @@ -312,12 +312,15 @@ class BangumiIntroController extends GetxController {
nextIndex = 0;
}
}
if (nextIndex <= episodes.length - 1 &&
platRepeat == PlayRepeat.listOrder) {}
if (nextIndex == episodes.length - 1 &&
platRepeat == PlayRepeat.listOrder) {
return false;
}

int cid = episodes[nextIndex].cid!;
String bvid = episodes[nextIndex].bvid!;
int aid = episodes[nextIndex].aid!;
changeSeasonOrbangu(bvid, cid, aid);
return true;
}
}
6 changes: 3 additions & 3 deletions lib/pages/bangumi/introduction/view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class _BangumiIntroPanelState extends State<BangumiIntroPanel>
_futureBuilderFuture = bangumiIntroController.queryBangumiIntro();
videoDetailCtr.cid.listen((int p0) {
cid = p0;
if (!mounted) return;
setState(() {});
});
}
Expand Down Expand Up @@ -138,7 +139,7 @@ class _BangumiInfoState extends State<BangumiInfo> {
print('cid: $cid');
videoDetailCtr.cid.listen((p0) {
cid = p0;
print('cid: $cid');
if (!mounted) return;
setState(() {});
});
}
Expand Down Expand Up @@ -371,8 +372,7 @@ class _BangumiInfoState extends State<BangumiInfo> {
(bangumiItem != null
? bangumiItem!.episodes!.first.cid
: widget.bangumiDetail!.episodes!.first.cid),
changeFuc: (bvid, cid, aid) => bangumiIntroController
.changeSeasonOrbangu(bvid, cid, aid),
changeFuc: bangumiIntroController.changeSeasonOrbangu,
)
],
],
Expand Down
Loading

0 comments on commit 3776cfe

Please sign in to comment.