Merge branch 'main' into design
This commit is contained in:
@ -64,7 +64,7 @@ class LiveRoomController extends GetxController {
|
||||
? liveItem.pic
|
||||
: (liveItem.cover != null && liveItem.cover != '')
|
||||
? liveItem.cover
|
||||
: null;
|
||||
: '';
|
||||
}
|
||||
Request.getBuvid().then((value) => buvid = value);
|
||||
}
|
||||
|
||||
@ -108,6 +108,12 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final mediaQuery = MediaQuery.of(context);
|
||||
final isPortrait = mediaQuery.orientation == Orientation.portrait;
|
||||
final isLandscape = mediaQuery.orientation == Orientation.landscape;
|
||||
|
||||
final padding = mediaQuery.padding;
|
||||
|
||||
Widget videoPlayerPanel = FutureBuilder(
|
||||
future: _futureBuilderFuture,
|
||||
builder: (BuildContext context, AsyncSnapshot snapshot) {
|
||||
@ -187,10 +193,8 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
children: [
|
||||
Obx(
|
||||
() => SizedBox(
|
||||
height: MediaQuery.of(context).padding.top +
|
||||
(_liveRoomController.isPortrait.value ||
|
||||
MediaQuery.of(context).orientation ==
|
||||
Orientation.landscape
|
||||
height: padding.top +
|
||||
(_liveRoomController.isPortrait.value || isLandscape
|
||||
? 0
|
||||
: kToolbarHeight),
|
||||
),
|
||||
@ -201,21 +205,18 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
if (plPlayerController.isFullScreen.value == true) {
|
||||
plPlayerController.triggerFullScreen(status: false);
|
||||
}
|
||||
if (MediaQuery.of(context).orientation ==
|
||||
Orientation.landscape) {
|
||||
if (isLandscape) {
|
||||
verticalScreen();
|
||||
}
|
||||
},
|
||||
child: Obx(
|
||||
() => Container(
|
||||
width: Get.size.width,
|
||||
height: MediaQuery.of(context).orientation ==
|
||||
Orientation.landscape
|
||||
height: isLandscape
|
||||
? Get.size.height
|
||||
: !_liveRoomController.isPortrait.value
|
||||
? Get.size.width * 9 / 16
|
||||
: Get.size.height -
|
||||
MediaQuery.of(context).padding.top,
|
||||
: Get.size.height - padding.top,
|
||||
clipBehavior: Clip.hardEdge,
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: BorderRadius.all(Radius.circular(6)),
|
||||
@ -229,7 +230,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
// 定位 快速滑动到底部
|
||||
Positioned(
|
||||
right: 20,
|
||||
bottom: MediaQuery.of(context).padding.bottom + 80,
|
||||
bottom: padding.bottom + 80,
|
||||
child: SlideTransition(
|
||||
position: Tween<Offset>(
|
||||
begin: const Offset(0, 4),
|
||||
@ -262,10 +263,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
titleSpacing: 0,
|
||||
backgroundColor: Colors.transparent,
|
||||
foregroundColor: Colors.white,
|
||||
toolbarHeight:
|
||||
MediaQuery.of(context).orientation == Orientation.portrait
|
||||
? 56
|
||||
: 0,
|
||||
toolbarHeight: isPortrait ? 56 : 0,
|
||||
title: FutureBuilder(
|
||||
future: _futureBuilder,
|
||||
builder: (context, snapshot) {
|
||||
@ -317,35 +315,38 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
),
|
||||
// 消息列表
|
||||
Obx(
|
||||
() => Positioned(
|
||||
top: MediaQuery.of(context).padding.top +
|
||||
kToolbarHeight +
|
||||
(_liveRoomController.isPortrait.value
|
||||
? Get.size.width
|
||||
: Get.size.width * 9 / 16),
|
||||
bottom: 90 + MediaQuery.of(context).padding.bottom,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: buildMessageListUI(
|
||||
context,
|
||||
_liveRoomController,
|
||||
_scrollController,
|
||||
() => Align(
|
||||
alignment: Alignment.bottomCenter,
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(
|
||||
bottom: 90 + padding.bottom,
|
||||
),
|
||||
height: Get.size.height -
|
||||
(padding.top +
|
||||
kToolbarHeight +
|
||||
(_liveRoomController.isPortrait.value
|
||||
? Get.size.width
|
||||
: Get.size.width * 9 / 16) +
|
||||
100 +
|
||||
padding.bottom),
|
||||
child: buildMessageListUI(
|
||||
context,
|
||||
_liveRoomController,
|
||||
_scrollController,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
// 消息输入框
|
||||
Visibility(
|
||||
visible: MediaQuery.of(context).orientation == Orientation.portrait,
|
||||
visible: isPortrait,
|
||||
child: Positioned(
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(
|
||||
left: 14,
|
||||
right: 14,
|
||||
top: 4,
|
||||
bottom: MediaQuery.of(context).padding.bottom + 20),
|
||||
left: 14, right: 14, top: 4, bottom: padding.bottom + 20),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.grey.withOpacity(0.1),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
||||
@ -421,6 +422,7 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
if (Platform.isAndroid) {
|
||||
return PiPSwitcher(
|
||||
childWhenDisabled: childWhenDisabled,
|
||||
@ -438,84 +440,82 @@ Widget buildMessageListUI(
|
||||
LiveRoomController liveRoomController,
|
||||
ScrollController scrollController,
|
||||
) {
|
||||
return Expanded(
|
||||
child: Obx(
|
||||
() => MediaQuery.removePadding(
|
||||
context: context,
|
||||
removeTop: true,
|
||||
removeBottom: true,
|
||||
child: ShaderMask(
|
||||
shaderCallback: (Rect bounds) {
|
||||
return LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
Colors.transparent,
|
||||
Colors.black.withOpacity(0.5),
|
||||
Colors.black,
|
||||
],
|
||||
stops: const [0.01, 0.05, 0.2],
|
||||
).createShader(bounds);
|
||||
return Obx(
|
||||
() => MediaQuery.removePadding(
|
||||
context: context,
|
||||
removeTop: true,
|
||||
removeBottom: true,
|
||||
child: ShaderMask(
|
||||
shaderCallback: (Rect bounds) {
|
||||
return LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
Colors.transparent,
|
||||
Colors.black.withOpacity(0.5),
|
||||
Colors.black,
|
||||
],
|
||||
stops: const [0.01, 0.05, 0.2],
|
||||
).createShader(bounds);
|
||||
},
|
||||
blendMode: BlendMode.dstIn,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
// 键盘失去焦点
|
||||
FocusScope.of(context).requestFocus(FocusNode());
|
||||
},
|
||||
blendMode: BlendMode.dstIn,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
// 键盘失去焦点
|
||||
FocusScope.of(context).requestFocus(FocusNode());
|
||||
},
|
||||
child: ListView.builder(
|
||||
controller: scrollController,
|
||||
itemCount: liveRoomController.messageList.length,
|
||||
itemBuilder: (context, index) {
|
||||
final LiveMessageModel liveMsgItem =
|
||||
liveRoomController.messageList[index];
|
||||
return Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: liveRoomController.isPortrait.value
|
||||
? Colors.black.withOpacity(0.3)
|
||||
: Colors.grey.withOpacity(0.1),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
||||
),
|
||||
margin: EdgeInsets.only(
|
||||
top: index == 0 ? 20.0 : 0.0,
|
||||
bottom: 6.0,
|
||||
left: 14.0,
|
||||
right: 14.0,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 3.0,
|
||||
horizontal: 10.0,
|
||||
),
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
style: const TextStyle(color: Colors.white),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: '${liveMsgItem.userName}: ',
|
||||
style: TextStyle(
|
||||
color: Colors.white.withOpacity(0.6),
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
// 处理点击事件
|
||||
print('Text clicked');
|
||||
},
|
||||
child: ListView.builder(
|
||||
controller: scrollController,
|
||||
itemCount: liveRoomController.messageList.length,
|
||||
itemBuilder: (context, index) {
|
||||
final LiveMessageModel liveMsgItem =
|
||||
liveRoomController.messageList[index];
|
||||
return Align(
|
||||
alignment: Alignment.centerLeft,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: liveRoomController.isPortrait.value
|
||||
? Colors.black.withOpacity(0.3)
|
||||
: Colors.grey.withOpacity(0.1),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
||||
),
|
||||
margin: EdgeInsets.only(
|
||||
top: index == 0 ? 20.0 : 0.0,
|
||||
bottom: 6.0,
|
||||
left: 14.0,
|
||||
right: 14.0,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 3.0,
|
||||
horizontal: 10.0,
|
||||
),
|
||||
child: Text.rich(
|
||||
TextSpan(
|
||||
style: const TextStyle(color: Colors.white),
|
||||
children: [
|
||||
TextSpan(
|
||||
text: '${liveMsgItem.userName}: ',
|
||||
style: TextStyle(
|
||||
color: Colors.white.withOpacity(0.6),
|
||||
),
|
||||
TextSpan(
|
||||
children: [
|
||||
...buildMessageTextSpan(context, liveMsgItem)
|
||||
],
|
||||
// text: liveMsgItem.message,
|
||||
),
|
||||
],
|
||||
),
|
||||
recognizer: TapGestureRecognizer()
|
||||
..onTap = () {
|
||||
// 处理点击事件
|
||||
print('Text clicked');
|
||||
},
|
||||
),
|
||||
TextSpan(
|
||||
children: [
|
||||
...buildMessageTextSpan(context, liveMsgItem)
|
||||
],
|
||||
// text: liveMsgItem.message,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -24,8 +24,8 @@ class _MainAppState extends State<MainApp> with SingleTickerProviderStateMixin {
|
||||
final MainController _mainController = Get.put(MainController());
|
||||
late HomeController _homeController;
|
||||
RankController? _rankController;
|
||||
DynamicsController? _dynamicController;
|
||||
MediaController? _mediaController;
|
||||
late DynamicsController _dynamicController;
|
||||
late MediaController _mediaController;
|
||||
|
||||
int? _lastSelectTime; //上次点击时间
|
||||
Box setting = GStrorage.setting;
|
||||
@ -76,28 +76,30 @@ class _MainAppState extends State<MainApp> with SingleTickerProviderStateMixin {
|
||||
}
|
||||
|
||||
if (currentPage is DynamicsPage) {
|
||||
if (_dynamicController!.flag) {
|
||||
if (_dynamicController.flag) {
|
||||
// 单击返回顶部 双击并刷新
|
||||
if (DateTime.now().millisecondsSinceEpoch - _lastSelectTime! < 500) {
|
||||
_dynamicController!.onRefresh();
|
||||
_dynamicController.onRefresh();
|
||||
} else {
|
||||
_dynamicController!.animateToTop();
|
||||
_dynamicController.animateToTop();
|
||||
}
|
||||
_lastSelectTime = DateTime.now().millisecondsSinceEpoch;
|
||||
}
|
||||
_dynamicController!.flag = true;
|
||||
_dynamicController.flag = true;
|
||||
_mainController.clearUnread();
|
||||
} else {
|
||||
_dynamicController?.flag = false;
|
||||
_dynamicController.flag = false;
|
||||
}
|
||||
|
||||
if (currentPage is MediaPage) {
|
||||
_mediaController!.queryFavFolder();
|
||||
_mediaController.queryFavFolder();
|
||||
}
|
||||
}
|
||||
|
||||
void controllerInit() {
|
||||
_homeController = Get.put(HomeController());
|
||||
_dynamicController = Get.put(DynamicsController());
|
||||
_mediaController = Get.put(MediaController());
|
||||
if (_mainController.pagesIds.contains(1)) {
|
||||
_rankController = Get.put(RankController());
|
||||
}
|
||||
|
||||
@ -411,7 +411,12 @@ class VideoIntroController extends GetxController {
|
||||
}
|
||||
|
||||
// 修改分P或番剧分集
|
||||
Future changeSeasonOrbangu(bvid, cid, aid, cover) async {
|
||||
Future changeSeasonOrbangu(
|
||||
String bvid,
|
||||
int cid,
|
||||
int? aid,
|
||||
String? cover,
|
||||
) async {
|
||||
// 重新获取视频资源
|
||||
final VideoDetailController videoDetailCtr =
|
||||
Get.find<VideoDetailController>(tag: heroTag);
|
||||
@ -422,13 +427,14 @@ class VideoIntroController extends GetxController {
|
||||
releatedCtr.queryRelatedVideo();
|
||||
}
|
||||
|
||||
videoDetailCtr.bvid = bvid;
|
||||
videoDetailCtr.oid.value = aid ?? IdUtils.bv2av(bvid);
|
||||
videoDetailCtr.cid.value = cid;
|
||||
videoDetailCtr.danmakuCid.value = cid;
|
||||
videoDetailCtr.cover.value = cover;
|
||||
videoDetailCtr.queryVideoUrl();
|
||||
videoDetailCtr.clearSubtitleContent();
|
||||
videoDetailCtr
|
||||
..bvid = bvid
|
||||
..oid.value = aid ?? IdUtils.bv2av(bvid)
|
||||
..cid.value = cid
|
||||
..danmakuCid.value = cid
|
||||
..cover.value = cover ?? ''
|
||||
..queryVideoUrl()
|
||||
..clearSubtitleContent();
|
||||
await videoDetailCtr.getSubtitle();
|
||||
videoDetailCtr.setSubtitleContent();
|
||||
// 重新请求评论
|
||||
@ -478,7 +484,13 @@ class VideoIntroController extends GetxController {
|
||||
final List episodes = [];
|
||||
bool isPages = false;
|
||||
late String cover;
|
||||
if (videoDetail.value.ugcSeason != null) {
|
||||
final VideoDetailController videoDetailCtr =
|
||||
Get.find<VideoDetailController>(tag: heroTag);
|
||||
|
||||
/// 优先稍后再看、收藏夹
|
||||
if (videoDetailCtr.isWatchLaterVisible.value) {
|
||||
episodes.addAll(videoDetailCtr.mediaList);
|
||||
} else if (videoDetail.value.ugcSeason != null) {
|
||||
final UgcSeason ugcSeason = videoDetail.value.ugcSeason!;
|
||||
final List<SectionItem> sections = ugcSeason.sections!;
|
||||
for (int i = 0; i < sections.length; i++) {
|
||||
@ -495,10 +507,15 @@ class VideoIntroController extends GetxController {
|
||||
episodes.indexWhere((e) => e.cid == lastPlayCid.value);
|
||||
int nextIndex = currentIndex + 1;
|
||||
cover = episodes[nextIndex].cover;
|
||||
final VideoDetailController videoDetailCtr =
|
||||
Get.find<VideoDetailController>(tag: heroTag);
|
||||
final PlayRepeat platRepeat = videoDetailCtr.plPlayerController.playRepeat;
|
||||
|
||||
int cid = episodes[nextIndex].cid!;
|
||||
while (cid == -1) {
|
||||
nextIndex += 1;
|
||||
SmartDialog.showToast('当前视频暂不支持播放,自动跳过');
|
||||
cid = episodes[nextIndex].cid!;
|
||||
}
|
||||
|
||||
// 列表循环
|
||||
if (nextIndex >= episodes.length) {
|
||||
if (platRepeat == PlayRepeat.listCycle) {
|
||||
@ -508,7 +525,6 @@ class VideoIntroController extends GetxController {
|
||||
return;
|
||||
}
|
||||
}
|
||||
final int cid = episodes[nextIndex].cid!;
|
||||
final String rBvid = isPages ? bvid : episodes[nextIndex].bvid;
|
||||
final int rAid = isPages ? IdUtils.bv2av(bvid) : episodes[nextIndex].aid!;
|
||||
changeSeasonOrbangu(rBvid, cid, rAid, cover);
|
||||
|
||||
@ -109,7 +109,7 @@ class _MediaListPanelState extends State<MediaListPanel> {
|
||||
var item = mediaList[index];
|
||||
return InkWell(
|
||||
onTap: () async {
|
||||
String bvid = item.bvId!;
|
||||
String bvid = item.bvid!;
|
||||
int? aid = item.id;
|
||||
String cover = item.cover ?? '';
|
||||
final int cid =
|
||||
@ -173,7 +173,7 @@ class _MediaListPanelState extends State<MediaListPanel> {
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.w500,
|
||||
color: item.bvId == widget.bvid
|
||||
color: item.bvid == widget.bvid
|
||||
? Theme.of(context)
|
||||
.colorScheme
|
||||
.primary
|
||||
|
||||
Reference in New Issue
Block a user