mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-07-30 23:40:13 +08:00
@@ -97,12 +97,11 @@ class _AboutPageState extends State<AboutPage> {
|
||||
);
|
||||
}
|
||||
},
|
||||
child: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxHeight: 150),
|
||||
child: ExcludeSemantics(
|
||||
child: Image.asset(
|
||||
'assets/images/logo/logo.png',
|
||||
),
|
||||
child: ExcludeSemantics(
|
||||
child: Image.asset(
|
||||
width: 150,
|
||||
height: 150,
|
||||
'assets/images/logo/logo.png',
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@@ -106,20 +106,21 @@ abstract class ReplyController<R> extends CommonListController<R, ReplyInfo> {
|
||||
}
|
||||
|
||||
(bool inputDisable, String? hint) get replyHint {
|
||||
bool inputDisable = false;
|
||||
String? hint;
|
||||
try {
|
||||
if (subjectControl != null && subjectControl!.hasRootText()) {
|
||||
if (subjectControl!.inputDisable) {
|
||||
SmartDialog.showToast(subjectControl!.rootText);
|
||||
return (true, null);
|
||||
final rootText = subjectControl!.rootText;
|
||||
inputDisable = subjectControl!.inputDisable;
|
||||
if (inputDisable) {
|
||||
SmartDialog.showToast(rootText);
|
||||
}
|
||||
if ((subjectControl!.hasSwitcherType() &&
|
||||
subjectControl!.switcherType != 1) ||
|
||||
subjectControl!.rootText.contains('可发评论')) {
|
||||
return (false, subjectControl!.rootText);
|
||||
if (rootText.contains('可发') || rootText.contains('可见')) {
|
||||
hint = rootText;
|
||||
}
|
||||
}
|
||||
} catch (_) {}
|
||||
return (false, null);
|
||||
return (inputDisable, hint);
|
||||
}
|
||||
|
||||
void onReply(
|
||||
|
||||
@@ -144,18 +144,11 @@ class LiveRoomController extends GetxController {
|
||||
acceptQnList = item.acceptQn!.map((e) {
|
||||
return (
|
||||
code: e,
|
||||
desc:
|
||||
LiveQuality.values
|
||||
.firstWhereOrNull((element) => element.code == e)
|
||||
?.description ??
|
||||
e.toString(),
|
||||
desc: LiveQuality.fromCode(e)?.desc ?? e.toString(),
|
||||
);
|
||||
}).toList();
|
||||
currentQnDesc.value =
|
||||
LiveQuality.values
|
||||
.firstWhereOrNull((element) => element.code == currentQn)
|
||||
?.description ??
|
||||
currentQn.toString();
|
||||
LiveQuality.fromCode(currentQn)?.desc ?? currentQn.toString();
|
||||
videoUrl = VideoUtils.getCdnUrl(item);
|
||||
await playerInit();
|
||||
isLoaded.value = true;
|
||||
@@ -286,10 +279,7 @@ class LiveRoomController extends GetxController {
|
||||
}
|
||||
currentQn = qn;
|
||||
currentQnDesc.value =
|
||||
LiveQuality.values
|
||||
.firstWhereOrNull((element) => element.code == currentQn)
|
||||
?.description ??
|
||||
currentQn.toString();
|
||||
LiveQuality.fromCode(currentQn)?.desc ?? currentQn.toString();
|
||||
return queryLiveUrl();
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import 'package:PiliPlus/plugin/pl_player/controller.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/models/play_status.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/view.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/widgets/common_btn.dart';
|
||||
import 'package:PiliPlus/services/service_locator.dart';
|
||||
import 'package:PiliPlus/utils/duration_util.dart';
|
||||
import 'package:PiliPlus/utils/extension.dart';
|
||||
@@ -46,8 +47,6 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
final GlobalKey chatKey = GlobalKey();
|
||||
final GlobalKey playerKey = GlobalKey();
|
||||
|
||||
final Color _color = const Color(0xFFEEEEEE);
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
@@ -630,13 +629,14 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 5, bottom: 10),
|
||||
child: Row(
|
||||
spacing: 6,
|
||||
children: [
|
||||
Obx(
|
||||
() {
|
||||
final enableShowDanmaku =
|
||||
plPlayerController.enableShowDanmaku.value;
|
||||
return IconButton(
|
||||
onPressed: () {
|
||||
return ComBtn(
|
||||
onTap: () {
|
||||
final newVal = !enableShowDanmaku;
|
||||
plPlayerController.enableShowDanmaku.value = newVal;
|
||||
if (!plPlayerController.tempPlayerConf) {
|
||||
@@ -646,19 +646,24 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
);
|
||||
}
|
||||
},
|
||||
icon: Icon(
|
||||
enableShowDanmaku
|
||||
? Icons.subtitles_outlined
|
||||
: Icons.subtitles_off_outlined,
|
||||
color: _color,
|
||||
),
|
||||
icon: enableShowDanmaku
|
||||
? const Icon(
|
||||
size: 22,
|
||||
Icons.subtitles_outlined,
|
||||
color: Color(0xFFEEEEEE),
|
||||
)
|
||||
: const Icon(
|
||||
size: 22,
|
||||
Icons.subtitles_off_outlined,
|
||||
color: Color(0xFFEEEEEE),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
Expanded(
|
||||
const Expanded(
|
||||
child: Text(
|
||||
'发送弹幕',
|
||||
style: TextStyle(color: _color),
|
||||
style: TextStyle(color: Color(0xFFEEEEEE)),
|
||||
),
|
||||
),
|
||||
Builder(
|
||||
@@ -675,9 +680,13 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
onTapDown: _liveRoomController.onLikeTapDown,
|
||||
onTapUp: _liveRoomController.onLikeTapUp,
|
||||
onTapCancel: _liveRoomController.onLikeTapUp,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Icon(Icons.thumb_up_off_alt, color: _color),
|
||||
child: const SizedBox.square(
|
||||
dimension: 34,
|
||||
child: Icon(
|
||||
size: 22,
|
||||
color: Color(0xFFEEEEEE),
|
||||
Icons.thumb_up_off_alt,
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
@@ -715,9 +724,13 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
);
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => onSendDanmaku(true),
|
||||
icon: Icon(Icons.emoji_emotions_outlined, color: _color),
|
||||
ComBtn(
|
||||
onTap: () => onSendDanmaku(true),
|
||||
icon: const Icon(
|
||||
size: 22,
|
||||
color: Color(0xFFEEEEEE),
|
||||
Icons.emoji_emotions_outlined,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -37,6 +37,7 @@ class BottomControl extends StatelessWidget {
|
||||
children: [
|
||||
PlayOrPauseButton(plPlayerController: plPlayerController),
|
||||
ComBtn(
|
||||
height: 30,
|
||||
icon: const Icon(
|
||||
Icons.refresh,
|
||||
size: 18,
|
||||
@@ -45,92 +46,81 @@ class BottomControl extends StatelessWidget {
|
||||
onTap: onRefresh,
|
||||
),
|
||||
const Spacer(),
|
||||
SizedBox(
|
||||
width: 35,
|
||||
height: 35,
|
||||
child: IconButton(
|
||||
tooltip: '弹幕屏蔽',
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () {
|
||||
if (liveRoomCtr.isLogin) {
|
||||
Get.toNamed(
|
||||
'/liveDmBlockPage',
|
||||
parameters: {
|
||||
'roomId': liveRoomCtr.roomId.toString(),
|
||||
},
|
||||
);
|
||||
} else {
|
||||
SmartDialog.showToast('账号未登录');
|
||||
}
|
||||
},
|
||||
icon: const Icon(
|
||||
size: 18,
|
||||
Icons.block,
|
||||
color: Colors.white,
|
||||
),
|
||||
ComBtn(
|
||||
height: 30,
|
||||
icon: const Icon(
|
||||
size: 18,
|
||||
Icons.block,
|
||||
color: Colors.white,
|
||||
),
|
||||
onTap: () {
|
||||
if (liveRoomCtr.isLogin) {
|
||||
Get.toNamed(
|
||||
'/liveDmBlockPage',
|
||||
parameters: {
|
||||
'roomId': liveRoomCtr.roomId.toString(),
|
||||
},
|
||||
);
|
||||
} else {
|
||||
SmartDialog.showToast('账号未登录');
|
||||
}
|
||||
},
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
const SizedBox(width: 3),
|
||||
Obx(
|
||||
() {
|
||||
final enableShowDanmaku =
|
||||
plPlayerController.enableShowDanmaku.value;
|
||||
return SizedBox(
|
||||
width: 35,
|
||||
height: 35,
|
||||
child: IconButton(
|
||||
tooltip: '弹幕开关',
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () {
|
||||
final newVal = !enableShowDanmaku;
|
||||
plPlayerController.enableShowDanmaku.value = newVal;
|
||||
if (!plPlayerController.tempPlayerConf) {
|
||||
GStorage.setting.put(
|
||||
SettingBoxKey.enableShowDanmaku,
|
||||
newVal,
|
||||
);
|
||||
}
|
||||
},
|
||||
icon: Icon(
|
||||
size: 18,
|
||||
enableShowDanmaku
|
||||
? Icons.subtitles_outlined
|
||||
: Icons.subtitles_off_outlined,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
return ComBtn(
|
||||
icon: enableShowDanmaku
|
||||
? const Icon(
|
||||
size: 18,
|
||||
Icons.subtitles_outlined,
|
||||
color: Colors.white,
|
||||
)
|
||||
: const Icon(
|
||||
size: 18,
|
||||
Icons.subtitles_off_outlined,
|
||||
color: Colors.white,
|
||||
),
|
||||
onTap: () {
|
||||
final newVal = !enableShowDanmaku;
|
||||
plPlayerController.enableShowDanmaku.value = newVal;
|
||||
if (!plPlayerController.tempPlayerConf) {
|
||||
GStorage.setting.put(
|
||||
SettingBoxKey.enableShowDanmaku,
|
||||
newVal,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
Obx(
|
||||
() => Container(
|
||||
height: 30,
|
||||
margin: const EdgeInsets.symmetric(horizontal: 10),
|
||||
alignment: Alignment.center,
|
||||
child: PopupMenuButton<BoxFit>(
|
||||
initialValue: plPlayerController.videoFit.value,
|
||||
color: Colors.black.withValues(alpha: 0.8),
|
||||
itemBuilder: (BuildContext context) {
|
||||
return BoxFit.values.map((BoxFit boxFit) {
|
||||
return PopupMenuItem<BoxFit>(
|
||||
height: 35,
|
||||
padding: const EdgeInsets.only(left: 30),
|
||||
value: boxFit,
|
||||
onTap: () => plPlayerController.toggleVideoFit(boxFit),
|
||||
child: Text(
|
||||
boxFit.desc,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 13,
|
||||
() => PopupMenuButton<BoxFit>(
|
||||
initialValue: plPlayerController.videoFit.value,
|
||||
color: Colors.black.withValues(alpha: 0.8),
|
||||
itemBuilder: (context) {
|
||||
return BoxFit.values
|
||||
.map(
|
||||
(BoxFit boxFit) => PopupMenuItem<BoxFit>(
|
||||
height: 35,
|
||||
padding: const EdgeInsets.only(left: 30),
|
||||
value: boxFit,
|
||||
onTap: () => plPlayerController.toggleVideoFit(boxFit),
|
||||
child: Text(
|
||||
boxFit.desc,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList();
|
||||
},
|
||||
)
|
||||
.toList();
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
child: Text(
|
||||
plPlayerController.videoFit.value.desc,
|
||||
style: const TextStyle(color: Colors.white, fontSize: 13),
|
||||
@@ -138,46 +128,54 @@ class BottomControl extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Obx(
|
||||
() => SizedBox(
|
||||
width: 30,
|
||||
child: PopupMenuButton<int>(
|
||||
padding: EdgeInsets.zero,
|
||||
initialValue: liveRoomCtr.currentQn,
|
||||
color: Colors.black.withValues(alpha: 0.8),
|
||||
() => PopupMenuButton<int>(
|
||||
padding: EdgeInsets.zero,
|
||||
initialValue: liveRoomCtr.currentQn,
|
||||
color: Colors.black.withValues(alpha: 0.8),
|
||||
itemBuilder: (context) {
|
||||
return liveRoomCtr.acceptQnList
|
||||
.map(
|
||||
(e) => PopupMenuItem<int>(
|
||||
height: 35,
|
||||
padding: const EdgeInsets.only(left: 30),
|
||||
value: e.code,
|
||||
onTap: () => liveRoomCtr.changeQn(e.code),
|
||||
child: Text(
|
||||
e.desc,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10),
|
||||
child: Text(
|
||||
liveRoomCtr.currentQnDesc.value,
|
||||
style: const TextStyle(color: Colors.white, fontSize: 13),
|
||||
),
|
||||
itemBuilder: (BuildContext context) {
|
||||
return liveRoomCtr.acceptQnList.map((e) {
|
||||
return PopupMenuItem<int>(
|
||||
height: 35,
|
||||
padding: const EdgeInsets.only(left: 30),
|
||||
value: e.code,
|
||||
onTap: () => liveRoomCtr.changeQn(e.code),
|
||||
child: Text(
|
||||
e.desc,
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList();
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
ComBtn(
|
||||
icon: const Icon(
|
||||
Icons.fullscreen,
|
||||
semanticLabel: '全屏切换',
|
||||
size: 20,
|
||||
color: Colors.white,
|
||||
),
|
||||
height: 30,
|
||||
icon: plPlayerController.isFullScreen.value
|
||||
? const Icon(
|
||||
Icons.fullscreen_exit,
|
||||
semanticLabel: '退出全屏',
|
||||
size: 24,
|
||||
color: Colors.white,
|
||||
)
|
||||
: const Icon(
|
||||
Icons.fullscreen,
|
||||
semanticLabel: '全屏',
|
||||
size: 24,
|
||||
color: Colors.white,
|
||||
),
|
||||
onTap: () => plPlayerController.triggerFullScreen(
|
||||
status: !plPlayerController.isFullScreen.value,
|
||||
),
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:PiliPlus/plugin/pl_player/controller.dart';
|
||||
import 'package:PiliPlus/plugin/pl_player/widgets/common_btn.dart';
|
||||
import 'package:PiliPlus/utils/page_utils.dart';
|
||||
import 'package:floating/floating.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -27,6 +28,39 @@ class LiveHeaderControl extends StatelessWidget {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final isFullScreen = plPlayerController.isFullScreen.value;
|
||||
Widget child;
|
||||
if (title != null) {
|
||||
child = Text(
|
||||
title!,
|
||||
maxLines: 1,
|
||||
style: const TextStyle(
|
||||
fontSize: 15,
|
||||
height: 1,
|
||||
color: Colors.white,
|
||||
),
|
||||
);
|
||||
if (isFullScreen && upName != null) {
|
||||
child = Column(
|
||||
spacing: 5,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
child,
|
||||
Text(
|
||||
upName!,
|
||||
maxLines: 1,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
height: 1,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
child = Expanded(child: child);
|
||||
} else {
|
||||
child = const Spacer();
|
||||
}
|
||||
return AppBar(
|
||||
backgroundColor: Colors.transparent,
|
||||
foregroundColor: Colors.white,
|
||||
@@ -37,147 +71,75 @@ class LiveHeaderControl extends StatelessWidget {
|
||||
spacing: 10,
|
||||
children: [
|
||||
if (isFullScreen)
|
||||
SizedBox(
|
||||
width: 35,
|
||||
height: 35,
|
||||
child: IconButton(
|
||||
tooltip: '返回',
|
||||
icon: const Icon(
|
||||
FontAwesomeIcons.arrowLeft,
|
||||
size: 15,
|
||||
),
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () =>
|
||||
plPlayerController.triggerFullScreen(status: false),
|
||||
),
|
||||
ComBtn(
|
||||
icon: const Icon(FontAwesomeIcons.arrowLeft, size: 15),
|
||||
onTap: () => plPlayerController.triggerFullScreen(status: false),
|
||||
),
|
||||
if (title != null)
|
||||
Expanded(
|
||||
child: Column(
|
||||
spacing: 5,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title!,
|
||||
maxLines: 1,
|
||||
style: const TextStyle(
|
||||
fontSize: 15,
|
||||
height: 1,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
if (isFullScreen && upName != null)
|
||||
Text(
|
||||
upName!,
|
||||
maxLines: 1,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
height: 1,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
else
|
||||
const Spacer(),
|
||||
SizedBox(
|
||||
width: 35,
|
||||
height: 35,
|
||||
child: IconButton(
|
||||
tooltip: '发弹幕',
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: onSendDanmaku,
|
||||
icon: const Icon(
|
||||
Icons.comment_outlined,
|
||||
size: 18,
|
||||
color: Colors.white,
|
||||
),
|
||||
child,
|
||||
ComBtn(
|
||||
icon: const Icon(
|
||||
size: 18,
|
||||
Icons.comment_outlined,
|
||||
color: Colors.white,
|
||||
),
|
||||
onTap: onSendDanmaku,
|
||||
),
|
||||
Obx(
|
||||
() {
|
||||
final onlyPlayAudio = plPlayerController.onlyPlayAudio.value;
|
||||
return SizedBox(
|
||||
width: 35,
|
||||
height: 35,
|
||||
child: IconButton(
|
||||
onPressed: () {
|
||||
plPlayerController.onlyPlayAudio.value = !onlyPlayAudio;
|
||||
onPlayAudio();
|
||||
},
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
icon: onlyPlayAudio
|
||||
? const Icon(
|
||||
size: 18,
|
||||
MdiIcons.musicCircle,
|
||||
color: Colors.white,
|
||||
)
|
||||
: const Icon(
|
||||
size: 18,
|
||||
MdiIcons.musicCircleOutline,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
return ComBtn(
|
||||
onTap: () {
|
||||
plPlayerController.onlyPlayAudio.value = !onlyPlayAudio;
|
||||
onPlayAudio();
|
||||
},
|
||||
icon: onlyPlayAudio
|
||||
? const Icon(
|
||||
size: 18,
|
||||
MdiIcons.musicCircle,
|
||||
color: Colors.white,
|
||||
)
|
||||
: const Icon(
|
||||
size: 18,
|
||||
MdiIcons.musicCircleOutline,
|
||||
color: Colors.white,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
if (Platform.isAndroid)
|
||||
SizedBox(
|
||||
width: 35,
|
||||
height: 35,
|
||||
child: IconButton(
|
||||
tooltip: '画中画',
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () async {
|
||||
try {
|
||||
var floating = Floating();
|
||||
if ((await floating.isPipAvailable) == true) {
|
||||
plPlayerController.hiddenControls(false);
|
||||
floating.enable(
|
||||
plPlayerController.isVertical
|
||||
? const EnableManual(
|
||||
aspectRatio: Rational.vertical(),
|
||||
)
|
||||
: const EnableManual(),
|
||||
);
|
||||
}
|
||||
} catch (_) {}
|
||||
},
|
||||
icon: const Icon(
|
||||
Icons.picture_in_picture_outlined,
|
||||
size: 18,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: 35,
|
||||
height: 35,
|
||||
child: IconButton(
|
||||
tooltip: '定时关闭',
|
||||
style: ButtonStyle(
|
||||
padding: WidgetStateProperty.all(EdgeInsets.zero),
|
||||
),
|
||||
onPressed: () => PageUtils.scheduleExit(
|
||||
context,
|
||||
plPlayerController.isFullScreen.value,
|
||||
true,
|
||||
),
|
||||
ComBtn(
|
||||
onTap: () async {
|
||||
try {
|
||||
var floating = Floating();
|
||||
if ((await floating.isPipAvailable) == true) {
|
||||
plPlayerController.hiddenControls(false);
|
||||
floating.enable(
|
||||
plPlayerController.isVertical
|
||||
? const EnableManual(
|
||||
aspectRatio: Rational.vertical(),
|
||||
)
|
||||
: const EnableManual(),
|
||||
);
|
||||
}
|
||||
} catch (_) {}
|
||||
},
|
||||
icon: const Icon(
|
||||
size: 18,
|
||||
Icons.schedule,
|
||||
Icons.picture_in_picture_outlined,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
ComBtn(
|
||||
onTap: () => PageUtils.scheduleExit(
|
||||
context,
|
||||
plPlayerController.isFullScreen.value,
|
||||
true,
|
||||
),
|
||||
icon: const Icon(
|
||||
size: 18,
|
||||
Icons.schedule,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -25,7 +25,6 @@ class MemberController extends CommonDataController<SpaceData, SpaceData?>
|
||||
MemberController({required this.mid});
|
||||
int mid;
|
||||
String? username;
|
||||
RxBool showUname = false.obs;
|
||||
|
||||
AccountService accountService = Get.find<AccountService>();
|
||||
|
||||
@@ -131,7 +130,6 @@ class MemberController extends CommonDataController<SpaceData, SpaceData?>
|
||||
vsync: this,
|
||||
length: tabs.length,
|
||||
);
|
||||
showUname.value = true;
|
||||
username = errMsg;
|
||||
loadingState.value = const Success(null);
|
||||
return true;
|
||||
|
||||
@@ -110,7 +110,7 @@ class UserInfoCard extends StatelessWidget {
|
||||
|
||||
List<Widget> _buildLeft(BuildContext context, ThemeData theme) => [
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 20, right: 20, top: 5),
|
||||
padding: const EdgeInsets.only(left: 20, right: 20),
|
||||
child: Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 8,
|
||||
@@ -461,6 +461,7 @@ class UserInfoCard extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
..._buildLeft(context, theme),
|
||||
if (card.prInfo?.content?.isNotEmpty == true) buildPrInfo(theme),
|
||||
const SizedBox(height: 5),
|
||||
|
||||
@@ -61,27 +61,28 @@ class _MemberVideoState extends State<MemberVideo>
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
final theme = Theme.of(context);
|
||||
return Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
refreshIndicator(
|
||||
onRefresh: _controller.onRefresh,
|
||||
child: CustomScrollView(
|
||||
physics: ReloadScrollPhysics(controller: _controller),
|
||||
slivers: [
|
||||
SliverPadding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: MediaQuery.paddingOf(context).bottom + 80,
|
||||
),
|
||||
sliver: Obx(
|
||||
() => _buildBody(theme, _controller.loadingState.value),
|
||||
),
|
||||
),
|
||||
],
|
||||
Widget child = refreshIndicator(
|
||||
onRefresh: _controller.onRefresh,
|
||||
child: CustomScrollView(
|
||||
physics: ReloadScrollPhysics(controller: _controller),
|
||||
slivers: [
|
||||
SliverPadding(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: MediaQuery.paddingOf(context).bottom + 80,
|
||||
),
|
||||
sliver: Obx(
|
||||
() => _buildBody(theme, _controller.loadingState.value),
|
||||
),
|
||||
),
|
||||
),
|
||||
if (widget.type == ContributeType.video &&
|
||||
_controller.fromViewAid?.isNotEmpty == true)
|
||||
],
|
||||
),
|
||||
);
|
||||
if (widget.type == ContributeType.video &&
|
||||
_controller.fromViewAid?.isNotEmpty == true) {
|
||||
return Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
child,
|
||||
Obx(
|
||||
() => _controller.isLocating.value != true
|
||||
? Positioned(
|
||||
@@ -103,6 +104,7 @@ class _MemberVideoState extends State<MemberVideo>
|
||||
?.indexWhere((i) => i.param == fromViewAid);
|
||||
if (locatedIndex == null || locatedIndex == -1) {
|
||||
_controller
|
||||
..reload = true
|
||||
..page = 0
|
||||
..loadingState.value = LoadingState.loading()
|
||||
..queryData();
|
||||
@@ -120,8 +122,10 @@ class _MemberVideoState extends State<MemberVideo>
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
],
|
||||
);
|
||||
],
|
||||
);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
Widget _buildBody(
|
||||
|
||||
@@ -527,14 +527,14 @@ List<SettingsModel> get extraSettings => [
|
||||
title: '超分辨率',
|
||||
leading: const Icon(Icons.stay_current_landscape_outlined),
|
||||
getSubtitle: () =>
|
||||
'当前:「${SuperResolutionType.values[Pref.superResolutionType].title}」\n默认设置对番剧生效, 其他视频默认关闭\n超分辨率需要启用硬件解码, 若启用硬件解码后仍然不生效, 尝试切换硬件解码器为 auto-copy',
|
||||
'当前:「${Pref.superResolutionType.title}」\n默认设置对番剧生效, 其他视频默认关闭\n超分辨率需要启用硬件解码, 若启用硬件解码后仍然不生效, 尝试切换硬件解码器为 auto-copy',
|
||||
onTap: (setState) async {
|
||||
SuperResolutionType? result = await showDialog(
|
||||
context: Get.context!,
|
||||
builder: (context) {
|
||||
return SelectDialog<SuperResolutionType>(
|
||||
title: '超分辨率',
|
||||
value: SuperResolutionType.values[Pref.superResolutionType],
|
||||
value: Pref.superResolutionType,
|
||||
values: SuperResolutionType.values
|
||||
.map((e) => (e, e.title))
|
||||
.toList(),
|
||||
|
||||
@@ -204,8 +204,7 @@ List<SettingsModel> get videoSettings => [
|
||||
settingsType: SettingsType.normal,
|
||||
title: '直播默认画质',
|
||||
leading: const Icon(Icons.video_settings_outlined),
|
||||
getSubtitle: () =>
|
||||
'当前画质:${LiveQualityExt.fromCode(Pref.liveQuality)!.description}',
|
||||
getSubtitle: () => '当前画质:${LiveQuality.fromCode(Pref.liveQuality)?.desc}',
|
||||
onTap: (setState) async {
|
||||
int? result = await showDialog(
|
||||
context: Get.context!,
|
||||
@@ -213,9 +212,7 @@ List<SettingsModel> get videoSettings => [
|
||||
return SelectDialog<int>(
|
||||
title: '直播默认画质',
|
||||
value: Pref.liveQuality,
|
||||
values: LiveQuality.values
|
||||
.map((e) => (e.code, e.description))
|
||||
.toList(),
|
||||
values: LiveQuality.values.map((e) => (e.code, e.desc)).toList(),
|
||||
);
|
||||
},
|
||||
);
|
||||
@@ -230,17 +227,15 @@ List<SettingsModel> get videoSettings => [
|
||||
title: '蜂窝网络直播默认画质',
|
||||
leading: const Icon(Icons.video_settings_outlined),
|
||||
getSubtitle: () =>
|
||||
'当前画质:${LiveQualityExt.fromCode(Pref.liveQualityCellular)!.description}',
|
||||
'当前画质:${LiveQuality.fromCode(Pref.liveQualityCellular)?.desc}',
|
||||
onTap: (setState) async {
|
||||
int? result = await showDialog(
|
||||
context: Get.context!,
|
||||
builder: (context) {
|
||||
return SelectDialog<int>(
|
||||
title: '直播默认画质',
|
||||
title: '蜂窝网络直播默认画质',
|
||||
value: Pref.liveQualityCellular,
|
||||
values: LiveQuality.values
|
||||
.map((e) => (e.code, e.description))
|
||||
.toList(),
|
||||
values: LiveQuality.values.map((e) => (e.code, e.desc)).toList(),
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -201,18 +201,18 @@ class HeaderControlState extends TripleState<HeaderControl> {
|
||||
const SizedBox(width: 10),
|
||||
Builder(
|
||||
builder: (context) => PopupMenuButton(
|
||||
initialValue: SuperResolutionType
|
||||
.values[widget.controller.superResolutionType],
|
||||
initialValue:
|
||||
widget.controller.superResolutionType.value,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(4),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
SuperResolutionType
|
||||
.values[widget
|
||||
.controller
|
||||
.superResolutionType]
|
||||
widget
|
||||
.controller
|
||||
.superResolutionType
|
||||
.value
|
||||
.title,
|
||||
strutStyle: const StrutStyle(
|
||||
leading: 0,
|
||||
@@ -235,7 +235,7 @@ class HeaderControlState extends TripleState<HeaderControl> {
|
||||
),
|
||||
),
|
||||
onSelected: (value) {
|
||||
widget.controller.setShader(value.index);
|
||||
widget.controller.setShader(value);
|
||||
if (context.mounted) {
|
||||
(context as Element).markNeedsBuild();
|
||||
}
|
||||
|
||||
@@ -121,15 +121,15 @@ class _WebDavSettingPageState extends State<WebDavSettingPage> {
|
||||
floatingActionButton: FloatingActionButton(
|
||||
child: const Icon(Icons.save),
|
||||
onPressed: () async {
|
||||
await GStorage.setting.putAll({
|
||||
SettingBoxKey.webdavUri: _uriCtr.text,
|
||||
SettingBoxKey.webdavUsername: _usernameCtr.text,
|
||||
SettingBoxKey.webdavPassword: _passwordCtr.text,
|
||||
SettingBoxKey.webdavDirectory: _directoryCtr.text,
|
||||
});
|
||||
if (_uriCtr.text.isEmpty) {
|
||||
SmartDialog.showToast('地址不能为空');
|
||||
return;
|
||||
}
|
||||
final setting = GStorage.setting;
|
||||
await setting.put(SettingBoxKey.webdavUri, _uriCtr.text);
|
||||
await setting.put(SettingBoxKey.webdavUsername, _usernameCtr.text);
|
||||
await setting.put(SettingBoxKey.webdavPassword, _passwordCtr.text);
|
||||
await setting.put(SettingBoxKey.webdavDirectory, _directoryCtr.text);
|
||||
try {
|
||||
final res = await WebDav().init();
|
||||
if (res.first) {
|
||||
|
||||
Reference in New Issue
Block a user