Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-06-19 14:44:49 +08:00
parent 9b8d4a62fa
commit 3bfb0db307
11 changed files with 85 additions and 67 deletions

View File

@@ -1220,6 +1220,7 @@ class RichTextNodeItem {
String? type;
String? rid;
List<OpusPicModel>? pics;
List<OpusPicModel>? dynPic;
String? jumpUrl;
RichTextNodeItem.fromJson(Map<String, dynamic> json) {

View File

@@ -281,12 +281,18 @@ TextSpan? richNode(
onView(i.pics!);
return;
}
if (i.dynPic?.isNotEmpty == true) {
onView(i.dynPic!);
return;
}
DynamicsHttp.dynPic(i.rid).then((res) {
if (res.isSuccess) {
var list = res.data;
if (Platform.isAndroid) {
i.pics = list;
} else {
i.dynPic = list;
}
if (list?.isNotEmpty == true) {
onView(list!);

View File

@@ -7,6 +7,7 @@ import 'package:PiliPlus/models/dynamics/vote_model.dart';
import 'package:PiliPlus/utils/date_util.dart';
import 'package:PiliPlus/utils/num_util.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class VotePanel extends StatefulWidget {
final VoteInfo voteInfo;
@@ -26,7 +27,7 @@ class _VotePanelState extends State<VotePanel> {
bool anonymity = false;
late VoteInfo _voteInfo;
late final groupValue = _voteInfo.myVotes?.toSet() ?? {};
late final RxSet<int> groupValue = (_voteInfo.myVotes?.toSet() ?? {}).obs;
late var _percentage = _cnt2Percentage(_voteInfo.options);
late bool _enabled = groupValue.isEmpty &&
_voteInfo.endTime! * 1000 > DateTime.now().millisecondsSinceEpoch;
@@ -83,7 +84,7 @@ class _VotePanelState extends State<VotePanel> {
? '已结束'
: '已完成',
),
if (_enabled) Text('${groupValue.length} / $_maxCnt'),
if (_enabled) Obx(() => Text('${groupValue.length} / $_maxCnt'))
],
),
Flexible(fit: FlexFit.loose, child: _buildContext()),

View File

@@ -52,10 +52,9 @@ class _HomePageState extends State<HomePage>
isScrollable: true,
dividerColor: Colors.transparent,
dividerHeight: 0,
enableFeedback: true,
splashBorderRadius: StyleString.mdRadius,
tabAlignment: TabAlignment.center,
onTap: (value) {
onTap: (_) {
feedBack();
if (!_homeController.tabController.indexIsChanging) {
_homeController.animateToTop();

View File

@@ -51,6 +51,8 @@ class LiveRoomController extends GetxController {
AccountService accountService = Get.find<AccountService>();
LiveDmInfoData? dmInfo;
@override
void onInit() {
super.onInit();
@@ -163,7 +165,8 @@ class LiveRoomController extends GetxController {
}
LiveMessageStream? msgStream;
final ScrollController scrollController = ScrollController();
late final ScrollController scrollController = ScrollController()
..addListener(listener);
void scrollToBottom() {
if (disableAutoScroll.value) return;
@@ -199,53 +202,17 @@ class LiveRoomController extends GetxController {
}
});
}
if (msgStream != null) {
return;
}
if (dmInfo != null) {
initDm(dmInfo!);
return;
}
LiveHttp.liveRoomGetDanmakuToken(roomId: roomId).then((res) {
if (res['status']) {
LiveDmInfoData info = res['data'];
// logger.d("info => $info");
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(),
);
msgStream?.addEventListener((obj) {
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: uid == accountService.mid,
),
);
WidgetsBinding.instance
.addPostFrameCallback((_) => scrollToBottom());
}
}
});
msgStream?.init();
scrollController.addListener(listener);
dmInfo = res['data'];
initDm(dmInfo!);
}
});
}
@@ -282,4 +249,49 @@ class LiveRoomController extends GetxController {
.description;
return queryLiveInfo();
}
void initDm(LiveDmInfoData info) {
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) {
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: uid == accountService.mid,
),
);
WidgetsBinding.instance
.addPostFrameCallback((_) => scrollToBottom());
}
}
})
..init();
}
}

View File

@@ -84,7 +84,9 @@ class _LiveRoomPageState extends State<LiveRoomPage>
void playerListener(PlayerStatus? status) {
if (status != PlayerStatus.playing) {
plPlayerController.danmakuController?.pause();
_liveRoomController.msgStream?.close();
_liveRoomController
..msgStream?.close()
..msgStream = null;
} else {
plPlayerController.danmakuController?.resume();
_liveRoomController.liveMsg();
@@ -122,7 +124,9 @@ class _LiveRoomPageState extends State<LiveRoomPage>
WidgetsBinding.instance.removeObserver(this);
ScreenBrightness().resetApplicationScreenBrightness();
PlPlayerController.setPlayCallBack(null);
_liveRoomController.msgStream?.close();
_liveRoomController
..msgStream?.close()
..msgStream = null;
plPlayerController
..removeStatusLister(playerListener)
..dispose();

View File

@@ -35,8 +35,10 @@ class LoginPageController extends GetxController
RxInt qrCodeLeftTime = 180.obs;
RxString statusQRCode = ''.obs;
Map<String, dynamic> selectedCountryCodeId =
Constants.internationalDialingPrefix.first;
late final List<Map<String, dynamic>> internationalDialingPrefix =
Constants.internationalDialingPrefix;
late Map<String, dynamic> selectedCountryCodeId =
internationalDialingPrefix.first;
String captchaKey = '';
RxInt smsSendCooldown = 0.obs;
int smsSendTimestamp = 0;

View File

@@ -1,6 +1,5 @@
import 'dart:ui';
import 'package:PiliPlus/common/constants.dart';
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
import 'package:PiliPlus/pages/login/controller.dart';
import 'package:PiliPlus/utils/image_util.dart';
@@ -332,9 +331,6 @@ class _LoginPageState extends State<LoginPage> {
);
}
late final List<Map<String, dynamic>> internationalDialingPrefix =
Constants.internationalDialingPrefix;
Widget loginBySmS(ThemeData theme) {
return Column(
children: [
@@ -360,7 +356,9 @@ class _LoginPageState extends State<LoginPage> {
'当前为${_loginPageCtr.selectedCountryCodeId['cname']}'
'+${_loginPageCtr.selectedCountryCodeId['country_id']}',
onSelected: (Map<String, dynamic> type) {},
itemBuilder: (_) => internationalDialingPrefix
initialValue: _loginPageCtr.selectedCountryCodeId,
itemBuilder: (_) => _loginPageCtr
.internationalDialingPrefix
.map((Map<String, dynamic> item) {
return PopupMenuItem<Map<String, dynamic>>(
onTap: () {

View File

@@ -107,7 +107,6 @@ class SettingsModel {
final Function? onTap;
final EdgeInsetsGeometry? contentPadding;
final TextStyle? titleStyle;
final bool? enableFeedback;
SettingsModel({
required this.settingsType,
@@ -124,7 +123,6 @@ class SettingsModel {
this.onTap,
this.contentPadding,
this.titleStyle,
this.enableFeedback,
});
}
@@ -2210,7 +2208,6 @@ List<SettingsModel> get extraSettings => [
),
SettingsModel(
settingsType: SettingsType.sw1tch,
enableFeedback: true,
setKey: SettingBoxKey.feedBackEnable,
onChanged: (value) {
enableFeedback = value;

View File

@@ -122,7 +122,6 @@ class _SetSwitchItemState extends State<SetSwitchItem> {
return ListTile(
contentPadding: widget.contentPadding,
enabled: widget.onTap != null ? val : true,
enableFeedback: true,
onTap: () => widget.onTap != null
? widget.onTap?.call()
: switchChange(theme, null),

View File

@@ -21,8 +21,8 @@ import 'package:PiliPlus/pages/video/introduction/ugc/widgets/menu_row.dart';
import 'package:PiliPlus/plugin/pl_player/controller.dart';
import 'package:PiliPlus/plugin/pl_player/models/play_repeat.dart';
import 'package:PiliPlus/plugin/pl_player/utils/fullscreen.dart';
import 'package:PiliPlus/utils/image_util.dart';
import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/image_util.dart';
import 'package:PiliPlus/utils/page_utils.dart';
import 'package:PiliPlus/utils/storage.dart';
import 'package:PiliPlus/utils/utils.dart';
@@ -398,9 +398,8 @@ class HeaderControlState extends State<HeaderControl> {
builder: (context) {
return AlertDialog(
title: const Text('播放信息'),
content: SizedBox(
width: double.infinity,
child: ListView(
content: SingleChildScrollView(
child: Column(
children: [
ListTile(
dense: true,