mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-07-19 01:56:53 +08:00
@@ -35,8 +35,9 @@ class LiveRoomController extends GetxController {
|
||||
double volume = 0.0;
|
||||
// 静音状态
|
||||
RxBool volumeOff = false.obs;
|
||||
PlPlayerController plPlayerController =
|
||||
PlPlayerController.getInstance(videoType: 'live');
|
||||
PlPlayerController plPlayerController = PlPlayerController.getInstance(
|
||||
videoType: 'live',
|
||||
);
|
||||
Rx<RoomInfoH5Data?> roomInfoH5 = Rx<RoomInfoH5Data?>(null);
|
||||
|
||||
RxList<dynamic> messages = [].obs;
|
||||
@@ -75,7 +76,7 @@ class LiveRoomController extends GetxController {
|
||||
httpHeaders: {
|
||||
'user-agent':
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 13_3_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.4 Safari/605.1.15',
|
||||
'referer': HttpString.baseUrl
|
||||
'referer': HttpString.baseUrl,
|
||||
},
|
||||
),
|
||||
autoplay: true,
|
||||
@@ -193,8 +194,10 @@ class LiveRoomController extends GetxController {
|
||||
if (v['status']) {
|
||||
if ((v['data'] as List?)?.isNotEmpty == true) {
|
||||
try {
|
||||
messages.addAll((v['data'] as List)
|
||||
.map((obj) => {
|
||||
messages.addAll(
|
||||
(v['data'] as List)
|
||||
.map(
|
||||
(obj) => {
|
||||
'name': obj['user']['base']['name'],
|
||||
'uid': obj['user']['uid'],
|
||||
'text': obj['text'],
|
||||
@@ -202,8 +205,10 @@ class LiveRoomController extends GetxController {
|
||||
'uemote': obj['emoticon']['emoticon_unique'] != ""
|
||||
? obj['emoticon']
|
||||
: null,
|
||||
})
|
||||
.toList());
|
||||
},
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
WidgetsBinding.instance.addPostFrameCallback(
|
||||
(_) => scrollToBottom(),
|
||||
);
|
||||
@@ -266,46 +271,48 @@ class LiveRoomController extends GetxController {
|
||||
if (info.hostList.isNullOrEmpty) {
|
||||
return;
|
||||
}
|
||||
msgStream = LiveMessageStream(
|
||||
streamToken: info.token!,
|
||||
roomId: roomId,
|
||||
uid: Accounts.main.mid,
|
||||
servers: info.hostList!
|
||||
.map((host) => 'wss://${host.host}:${host.wssPort}/sub')
|
||||
.toList(),
|
||||
)
|
||||
..addEventListener((obj) {
|
||||
try {
|
||||
if (obj['cmd'] == 'DANMU_MSG') {
|
||||
// logger.i(' 原始弹幕消息 ======> ${jsonEncode(obj)}');
|
||||
final info = obj['info'];
|
||||
final first = info[0];
|
||||
final content = first[15];
|
||||
final extra = jsonDecode(content['extra']);
|
||||
final user = content['user'];
|
||||
final uid = user['uid'];
|
||||
messages.add({
|
||||
'name': user['base']['name'],
|
||||
'uid': uid,
|
||||
'text': info[1],
|
||||
'emots': extra['emots'],
|
||||
'uemote': first[13],
|
||||
});
|
||||
if (showDanmaku) {
|
||||
controller?.addDanmaku(
|
||||
DanmakuContentItem(
|
||||
extra['content'],
|
||||
color: DmUtils.decimalToColor(extra['color']),
|
||||
type: DmUtils.getPosition(extra['mode']),
|
||||
selfSend: isLogin && uid == accountService.mid,
|
||||
),
|
||||
);
|
||||
WidgetsBinding.instance
|
||||
.addPostFrameCallback((_) => scrollToBottom());
|
||||
}
|
||||
}
|
||||
} catch (_) {}
|
||||
})
|
||||
..init();
|
||||
msgStream =
|
||||
LiveMessageStream(
|
||||
streamToken: info.token!,
|
||||
roomId: roomId,
|
||||
uid: Accounts.main.mid,
|
||||
servers: info.hostList!
|
||||
.map((host) => 'wss://${host.host}:${host.wssPort}/sub')
|
||||
.toList(),
|
||||
)
|
||||
..addEventListener((obj) {
|
||||
try {
|
||||
if (obj['cmd'] == 'DANMU_MSG') {
|
||||
// logger.i(' 原始弹幕消息 ======> ${jsonEncode(obj)}');
|
||||
final info = obj['info'];
|
||||
final first = info[0];
|
||||
final content = first[15];
|
||||
final extra = jsonDecode(content['extra']);
|
||||
final user = content['user'];
|
||||
final uid = user['uid'];
|
||||
messages.add({
|
||||
'name': user['base']['name'],
|
||||
'uid': uid,
|
||||
'text': info[1],
|
||||
'emots': extra['emots'],
|
||||
'uemote': first[13],
|
||||
});
|
||||
if (showDanmaku) {
|
||||
controller?.addDanmaku(
|
||||
DanmakuContentItem(
|
||||
extra['content'],
|
||||
color: DmUtils.decimalToColor(extra['color']),
|
||||
type: DmUtils.getPosition(extra['mode']),
|
||||
selfSend: isLogin && uid == accountService.mid,
|
||||
),
|
||||
);
|
||||
WidgetsBinding.instance.addPostFrameCallback(
|
||||
(_) => scrollToBottom(),
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (_) {}
|
||||
})
|
||||
..init();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,8 @@ class _ReplyPageState extends CommonRichTextPubPageState<LiveSendDmPanel> {
|
||||
@override
|
||||
void dispose() {
|
||||
Get.delete<LiveEmotePanelController>(
|
||||
tag: liveRoomController.roomId.toString());
|
||||
tag: liveRoomController.roomId.toString(),
|
||||
);
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -75,22 +76,26 @@ class _ReplyPageState extends CommonRichTextPubPageState<LiveSendDmPanel> {
|
||||
|
||||
@override
|
||||
Widget? get customPanel => LiveEmotePanel(
|
||||
onChoose: onChooseEmote,
|
||||
roomId: liveRoomController.roomId,
|
||||
onSendEmoticonUnique: (emote) {
|
||||
onCustomPublish(
|
||||
message: emote.emoticonUnique!,
|
||||
dmType: 1,
|
||||
emoticonOptions: '[object Object]',
|
||||
);
|
||||
},
|
||||
onChoose: onChooseEmote,
|
||||
roomId: liveRoomController.roomId,
|
||||
onSendEmoticonUnique: (emote) {
|
||||
onCustomPublish(
|
||||
message: emote.emoticonUnique!,
|
||||
dmType: 1,
|
||||
emoticonOptions: '[object Object]',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
List<Widget> buildInputView(ThemeData theme) {
|
||||
return [
|
||||
Container(
|
||||
padding:
|
||||
const EdgeInsets.only(top: 12, right: 15, left: 15, bottom: 10),
|
||||
padding: const EdgeInsets.only(
|
||||
top: 12,
|
||||
right: 15,
|
||||
left: 15,
|
||||
bottom: 10,
|
||||
),
|
||||
child: Form(
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
child: Listener(
|
||||
@@ -137,8 +142,10 @@ class _ReplyPageState extends CommonRichTextPubPageState<LiveSendDmPanel> {
|
||||
() => FilledButton.tonal(
|
||||
onPressed: enablePublish.value ? onPublish : null,
|
||||
style: FilledButton.styleFrom(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 20, vertical: 10),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 20,
|
||||
vertical: 10,
|
||||
),
|
||||
visualDensity: VisualDensity.compact,
|
||||
),
|
||||
child: const Text('发送'),
|
||||
|
||||
@@ -96,8 +96,9 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
|
||||
Future<void> _updateFontSize() async {
|
||||
if (Platform.isAndroid) {
|
||||
_isPipMode =
|
||||
await const MethodChannel("floating").invokeMethod('inPipAlready');
|
||||
_isPipMode = await const MethodChannel(
|
||||
"floating",
|
||||
).invokeMethod('inPipAlready');
|
||||
}
|
||||
if (_liveRoomController.controller != null) {
|
||||
_liveRoomController.controller!.updateOption(
|
||||
@@ -197,9 +198,11 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
hideTop: plPlayerController.blockTypes.contains(5),
|
||||
hideScroll: plPlayerController.blockTypes.contains(2),
|
||||
hideBottom: plPlayerController.blockTypes.contains(4),
|
||||
duration: plPlayerController.danmakuDuration /
|
||||
duration:
|
||||
plPlayerController.danmakuDuration /
|
||||
plPlayerController.playbackSpeed,
|
||||
staticDuration: plPlayerController.danmakuStaticDuration /
|
||||
staticDuration:
|
||||
plPlayerController.danmakuStaticDuration /
|
||||
plPlayerController.playbackSpeed,
|
||||
strokeWidth: plPlayerController.strokeWidth,
|
||||
lineHeight: plPlayerController.danmakuLineHeight,
|
||||
@@ -249,7 +252,10 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
final appBackground = _liveRoomController
|
||||
.roomInfoH5.value?.roomInfo?.appBackground;
|
||||
.roomInfoH5
|
||||
.value
|
||||
?.roomInfo
|
||||
?.appBackground;
|
||||
return Positioned.fill(
|
||||
child: Opacity(
|
||||
opacity: 0.6,
|
||||
@@ -296,55 +302,54 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
}
|
||||
|
||||
Widget get _buildPH => Column(
|
||||
children: [
|
||||
_buildAppBar,
|
||||
..._buildBodyP,
|
||||
],
|
||||
);
|
||||
children: [
|
||||
_buildAppBar,
|
||||
..._buildBodyP,
|
||||
],
|
||||
);
|
||||
|
||||
Widget get _buildPP => Stack(
|
||||
clipBehavior: Clip.none,
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
_buildAppBar,
|
||||
Column(
|
||||
children: [
|
||||
_buildAppBar,
|
||||
Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
Obx(
|
||||
() => Container(
|
||||
margin: isFullScreen
|
||||
? null
|
||||
: const EdgeInsets.only(top: 56),
|
||||
color: Colors.black,
|
||||
child: videoPlayerPanel(
|
||||
alignment: isFullScreen ? null : Alignment.topCenter,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
Obx(
|
||||
() => Container(
|
||||
margin: isFullScreen
|
||||
? null
|
||||
: const EdgeInsets.only(top: 56),
|
||||
color: Colors.black,
|
||||
child: videoPlayerPanel(
|
||||
alignment: isFullScreen ? null : Alignment.topCenter,
|
||||
),
|
||||
Obx(
|
||||
() => isFullScreen
|
||||
? const SizedBox.shrink()
|
||||
: Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 55,
|
||||
child: SizedBox(
|
||||
height: 125,
|
||||
child: _buildChatWidget(true),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Obx(() =>
|
||||
isFullScreen ? const SizedBox.shrink() : _buildInputWidget),
|
||||
],
|
||||
Obx(
|
||||
() => isFullScreen
|
||||
? const SizedBox.shrink()
|
||||
: Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 55,
|
||||
child: SizedBox(
|
||||
height: 125,
|
||||
child: _buildChatWidget(true),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Obx(() => isFullScreen ? const SizedBox.shrink() : _buildInputWidget),
|
||||
],
|
||||
);
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -487,14 +492,15 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
Widget get _buildBodyH {
|
||||
double videoWidth =
|
||||
clampDouble(context.height / context.width * 1.08, 0.58, 0.75) *
|
||||
context.width;
|
||||
context.width;
|
||||
return Expanded(
|
||||
child: Row(
|
||||
children: [
|
||||
Obx(
|
||||
() => Container(
|
||||
margin:
|
||||
EdgeInsets.only(bottom: MediaQuery.paddingOf(context).bottom),
|
||||
margin: EdgeInsets.only(
|
||||
bottom: MediaQuery.paddingOf(context).bottom,
|
||||
),
|
||||
color: isFullScreen ? Colors.black : null,
|
||||
width: isFullScreen ? Get.size.width : videoWidth,
|
||||
height: isFullScreen ? Get.size.height : Get.size.width * 9 / 16,
|
||||
@@ -513,93 +519,95 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
}
|
||||
|
||||
List<Widget> get _buildBodyP => [
|
||||
Obx(
|
||||
() => Container(
|
||||
color: Colors.black,
|
||||
width: Get.size.width,
|
||||
height: isFullScreen ? Get.size.height : Get.size.width * 9 / 16,
|
||||
child: videoPlayerPanel(),
|
||||
),
|
||||
),
|
||||
..._buildBottomWidget,
|
||||
];
|
||||
Obx(
|
||||
() => Container(
|
||||
color: Colors.black,
|
||||
width: Get.size.width,
|
||||
height: isFullScreen ? Get.size.height : Get.size.width * 9 / 16,
|
||||
child: videoPlayerPanel(),
|
||||
),
|
||||
),
|
||||
..._buildBottomWidget,
|
||||
];
|
||||
|
||||
final GlobalKey chatKey = GlobalKey();
|
||||
|
||||
List<Widget> get _buildBottomWidget => [
|
||||
Expanded(child: _buildChatWidget()),
|
||||
_buildInputWidget,
|
||||
];
|
||||
Expanded(child: _buildChatWidget()),
|
||||
_buildInputWidget,
|
||||
];
|
||||
|
||||
Widget _buildChatWidget([bool? isPP]) => Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
child: LiveRoomChat(
|
||||
key: chatKey,
|
||||
isPP: isPP,
|
||||
roomId: _roomId,
|
||||
liveRoomController: _liveRoomController,
|
||||
),
|
||||
);
|
||||
padding: const EdgeInsets.symmetric(vertical: 16),
|
||||
child: LiveRoomChat(
|
||||
key: chatKey,
|
||||
isPP: isPP,
|
||||
roomId: _roomId,
|
||||
liveRoomController: _liveRoomController,
|
||||
),
|
||||
);
|
||||
|
||||
Widget get _buildInputWidget => Container(
|
||||
padding: EdgeInsets.only(
|
||||
top: 5,
|
||||
left: 10,
|
||||
right: 10,
|
||||
bottom: 15 + MediaQuery.paddingOf(context).bottom,
|
||||
),
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(20),
|
||||
topRight: Radius.circular(20),
|
||||
),
|
||||
border: Border(
|
||||
top: BorderSide(color: Color(0x1AFFFFFF)),
|
||||
),
|
||||
color: Color(0x1AFFFFFF),
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: onSendDanmaku,
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 5, bottom: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
Obx(
|
||||
() {
|
||||
final enableShowDanmaku =
|
||||
plPlayerController.enableShowDanmaku.value;
|
||||
return IconButton(
|
||||
onPressed: () {
|
||||
final newVal = !enableShowDanmaku;
|
||||
plPlayerController.enableShowDanmaku.value = newVal;
|
||||
GStorage.setting
|
||||
.put(SettingBoxKey.enableShowDanmaku, newVal);
|
||||
},
|
||||
icon: Icon(
|
||||
enableShowDanmaku
|
||||
? Icons.subtitles_outlined
|
||||
: Icons.subtitles_off_outlined,
|
||||
color: _color,
|
||||
),
|
||||
padding: EdgeInsets.only(
|
||||
top: 5,
|
||||
left: 10,
|
||||
right: 10,
|
||||
bottom: 15 + MediaQuery.paddingOf(context).bottom,
|
||||
),
|
||||
decoration: const BoxDecoration(
|
||||
borderRadius: BorderRadius.only(
|
||||
topLeft: Radius.circular(20),
|
||||
topRight: Radius.circular(20),
|
||||
),
|
||||
border: Border(
|
||||
top: BorderSide(color: Color(0x1AFFFFFF)),
|
||||
),
|
||||
color: Color(0x1AFFFFFF),
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: onSendDanmaku,
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(top: 5, bottom: 10),
|
||||
child: Row(
|
||||
children: [
|
||||
Obx(
|
||||
() {
|
||||
final enableShowDanmaku =
|
||||
plPlayerController.enableShowDanmaku.value;
|
||||
return IconButton(
|
||||
onPressed: () {
|
||||
final newVal = !enableShowDanmaku;
|
||||
plPlayerController.enableShowDanmaku.value = newVal;
|
||||
GStorage.setting.put(
|
||||
SettingBoxKey.enableShowDanmaku,
|
||||
newVal,
|
||||
);
|
||||
},
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'发送弹幕',
|
||||
style: TextStyle(color: _color),
|
||||
icon: Icon(
|
||||
enableShowDanmaku
|
||||
? Icons.subtitles_outlined
|
||||
: Icons.subtitles_off_outlined,
|
||||
color: _color,
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => onSendDanmaku(true),
|
||||
icon: Icon(Icons.emoji_emotions_outlined, color: _color),
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
'发送弹幕',
|
||||
style: TextStyle(color: _color),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () => onSendDanmaku(true),
|
||||
icon: Icon(Icons.emoji_emotions_outlined, color: _color),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
void onSendDanmaku([bool fromEmote = false]) {
|
||||
if (!_liveRoomController.accountService.isLogin.value) {
|
||||
@@ -627,8 +635,10 @@ class _LiveRoomPageState extends State<LiveRoomPage>
|
||||
},
|
||||
transitionDuration: const Duration(milliseconds: 500),
|
||||
transitionBuilder: (context, animation, secondaryAnimation, child) {
|
||||
var tween = Tween(begin: const Offset(0.0, 1.0), end: Offset.zero)
|
||||
.chain(CurveTween(curve: Curves.linear));
|
||||
var tween = Tween(
|
||||
begin: const Offset(0.0, 1.0),
|
||||
end: Offset.zero,
|
||||
).chain(CurveTween(curve: Curves.linear));
|
||||
return SlideTransition(
|
||||
position: animation.drive(tween),
|
||||
child: child,
|
||||
|
||||
@@ -91,8 +91,10 @@ class BottomControl extends StatelessWidget {
|
||||
onPressed: () {
|
||||
final newVal = !enableShowDanmaku;
|
||||
plPlayerController.enableShowDanmaku.value = newVal;
|
||||
GStorage.setting
|
||||
.put(SettingBoxKey.enableShowDanmaku, newVal);
|
||||
GStorage.setting.put(
|
||||
SettingBoxKey.enableShowDanmaku,
|
||||
newVal,
|
||||
);
|
||||
},
|
||||
icon: Icon(
|
||||
size: 18,
|
||||
@@ -122,8 +124,10 @@ class BottomControl extends StatelessWidget {
|
||||
onTap: () => plPlayerController.toggleVideoFit(boxFit),
|
||||
child: Text(
|
||||
boxFit.desc,
|
||||
style:
|
||||
const TextStyle(color: Colors.white, fontSize: 13),
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList();
|
||||
@@ -156,8 +160,10 @@ class BottomControl extends StatelessWidget {
|
||||
onTap: () => liveRoomCtr.changeQn(e.code),
|
||||
child: Text(
|
||||
e.desc,
|
||||
style:
|
||||
const TextStyle(color: Colors.white, fontSize: 13),
|
||||
style: const TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 13,
|
||||
),
|
||||
),
|
||||
);
|
||||
}).toList();
|
||||
@@ -174,7 +180,8 @@ class BottomControl extends StatelessWidget {
|
||||
color: Colors.white,
|
||||
),
|
||||
onTap: () => plPlayerController.triggerFullScreen(
|
||||
status: !plPlayerController.isFullScreen.value),
|
||||
status: !plPlayerController.isFullScreen.value,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -37,8 +37,10 @@ class LiveRoomChat extends StatelessWidget {
|
||||
alignment: Alignment.centerLeft,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||
child: Container(
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 10, vertical: 5),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 10,
|
||||
vertical: 5,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: isPP == true
|
||||
? Colors.black.withValues(alpha: 0.3)
|
||||
@@ -89,7 +91,7 @@ class LiveRoomChat extends StatelessWidget {
|
||||
),
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
)
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
@@ -99,7 +101,7 @@ class LiveRoomChat extends StatelessWidget {
|
||||
dynamic uemote = obj['uemote'];
|
||||
List<String> list = [
|
||||
if (emots != null) ...emots.keys,
|
||||
if (uemote is Map) uemote['emoticon_unique'].replaceFirst('upower_', '')
|
||||
if (uemote is Map) uemote['emoticon_unique'].replaceFirst('upower_', ''),
|
||||
];
|
||||
if (list.isNotEmpty) {
|
||||
RegExp regExp = RegExp(list.map(RegExp.escape).join('|'));
|
||||
@@ -109,16 +111,19 @@ class LiveRoomChat extends StatelessWidget {
|
||||
onMatch: (Match match) {
|
||||
String key = match[0]!;
|
||||
dynamic emote = emots?[key] ?? uemote;
|
||||
spanChildren.add(WidgetSpan(
|
||||
child: ExcludeSemantics(
|
||||
spanChildren.add(
|
||||
WidgetSpan(
|
||||
child: ExcludeSemantics(
|
||||
child: NetworkImgLayer(
|
||||
src: emote['url'],
|
||||
type: ImageType.emote,
|
||||
width: emote['width'].toDouble(),
|
||||
height: emote['height'].toDouble(),
|
||||
semanticsLabel: key,
|
||||
)),
|
||||
));
|
||||
src: emote['url'],
|
||||
type: ImageType.emote,
|
||||
width: emote['width'].toDouble(),
|
||||
height: emote['height'].toDouble(),
|
||||
semanticsLabel: key,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
return '';
|
||||
},
|
||||
onNonMatch: (String nonMatchStr) {
|
||||
|
||||
@@ -63,14 +63,20 @@ class LiveHeaderControl extends StatelessWidget {
|
||||
title!,
|
||||
maxLines: 1,
|
||||
style: const TextStyle(
|
||||
fontSize: 15, height: 1, color: Colors.white),
|
||||
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),
|
||||
fontSize: 12,
|
||||
height: 1,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -139,7 +145,8 @@ class LiveHeaderControl extends StatelessWidget {
|
||||
floating.enable(
|
||||
plPlayerController.direction.value == 'vertical'
|
||||
? const EnableManual(
|
||||
aspectRatio: Rational.vertical())
|
||||
aspectRatio: Rational.vertical(),
|
||||
)
|
||||
: const EnableManual(),
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user