Compare commits

..

6 Commits

Author SHA1 Message Date
bggRGjQaUbCoE
288d554de9 opt check reply note
Closes #1095

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
2025-08-24 09:41:39 +08:00
bggRGjQaUbCoE
a274f5ae8b opt live
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
2025-08-24 09:41:19 +08:00
bggRGjQaUbCoE
ad0d9ecee0 fix #1098
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
2025-08-23 22:07:26 +08:00
bggRGjQaUbCoE
ee819bb260 Revert "opt: non null (#1091)"
This reverts commit 3c34e43827.
2025-08-23 22:05:35 +08:00
My-Responsitories
b77403f03f fix: latex (#1094) 2025-08-23 12:45:19 +00:00
My-Responsitories
3c34e43827 opt: non null (#1091)
* opt: type

* opt: type 2

* opt: type 3
2025-08-23 10:25:41 +00:00
4 changed files with 62 additions and 32 deletions

View File

@@ -2,6 +2,7 @@ import 'dart:math';
import 'package:PiliPlus/common/widgets/image/image_view.dart'; import 'package:PiliPlus/common/widgets/image/image_view.dart';
import 'package:PiliPlus/common/widgets/image/network_img_layer.dart'; import 'package:PiliPlus/common/widgets/image/network_img_layer.dart';
import 'package:PiliPlus/http/constants.dart';
import 'package:PiliPlus/models/common/image_preview_type.dart'; import 'package:PiliPlus/models/common/image_preview_type.dart';
import 'package:PiliPlus/models/common/image_type.dart'; import 'package:PiliPlus/models/common/image_type.dart';
import 'package:PiliPlus/models/dynamics/article_content_model.dart' import 'package:PiliPlus/models/dynamics/article_content_model.dart'
@@ -9,6 +10,7 @@ import 'package:PiliPlus/models/dynamics/article_content_model.dart'
import 'package:PiliPlus/models/dynamics/result.dart'; import 'package:PiliPlus/models/dynamics/result.dart';
import 'package:PiliPlus/pages/dynamics/widgets/vote.dart'; import 'package:PiliPlus/pages/dynamics/widgets/vote.dart';
import 'package:PiliPlus/utils/app_scheme.dart'; import 'package:PiliPlus/utils/app_scheme.dart';
import 'package:PiliPlus/utils/context_ext.dart';
import 'package:PiliPlus/utils/extension.dart'; import 'package:PiliPlus/utils/extension.dart';
import 'package:PiliPlus/utils/image_util.dart'; import 'package:PiliPlus/utils/image_util.dart';
import 'package:PiliPlus/utils/page_utils.dart'; import 'package:PiliPlus/utils/page_utils.dart';
@@ -17,7 +19,7 @@ import 'package:cached_network_svg_image/cached_network_svg_image.dart';
import 'package:flutter/foundation.dart' show kDebugMode; import 'package:flutter/foundation.dart' show kDebugMode;
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart' hide ContextExtensionss;
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:re_highlight/languages/all.dart'; import 'package:re_highlight/languages/all.dart';
import 'package:re_highlight/re_highlight.dart'; import 'package:re_highlight/re_highlight.dart';
@@ -64,6 +66,10 @@ class OpusContent extends StatelessWidget {
if (opus.isEmpty) { if (opus.isEmpty) {
return const SliverToBoxAdapter(); return const SliverToBoxAdapter();
} }
late final highlight = Highlight()..registerLanguages(builtinAllLanguages);
late final isDarkMode = context.isDarkMode;
final colorScheme = Theme.of(context).colorScheme; final colorScheme = Theme.of(context).colorScheme;
return SliverList.separated( return SliverList.separated(
itemCount: opus.length, itemCount: opus.length,
@@ -119,16 +125,19 @@ class OpusContent extends StatelessWidget {
); );
} }
case 'TEXT_NODE_TYPE_FORMULA' when (item.formula != null): case 'TEXT_NODE_TYPE_FORMULA' when (item.formula != null):
final latex = item.formula!.latexContent!;
return WidgetSpan( return WidgetSpan(
child: CachedNetworkSVGImage( child: CachedNetworkSVGImage(
cacheKey: latex,
semanticsLabel: latex,
height: 65, height: 65,
'https://api.bilibili.com/x/web-frontend/mathjax/tex?formula=${Uri.encodeComponent(item.formula!.latexContent!)}', '${HttpString.apiBaseUrl}/x/web-frontend/mathjax/tex?formula=${Uri.encodeComponent(latex)}',
colorFilter: ColorFilter.mode( colorFilter: ColorFilter.mode(
colorScheme.onSurfaceVariant, colorScheme.onSurfaceVariant,
BlendMode.srcIn, BlendMode.srcIn,
), ),
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
placeholderBuilder: (_) => const SizedBox.shrink(), placeholderBuilder: (_) => Text(latex),
), ),
); );
default: default:
@@ -559,23 +568,22 @@ class OpusContent extends StatelessWidget {
), ),
); );
case 7 when (element.code != null): case 7 when (element.code != null):
final Highlight highlight = Highlight() final renderer = TextSpanRenderer(
..registerLanguages(builtinAllLanguages);
final HighlightResult result = highlight.highlightAuto(
element.code!.content!,
element.code!.lang == 'language-clike'
? const ['c', 'java']
: [
element.code!.lang!
.replaceAll('language-', '')
.replaceAll('like', ''),
],
);
final TextSpanRenderer renderer = TextSpanRenderer(
const TextStyle(), const TextStyle(),
context.isDarkMode ? githubDarkTheme : githubTheme, isDarkMode ? githubDarkTheme : githubTheme,
); );
result.render(renderer); highlight
.highlightAuto(
element.code!.content!,
element.code!.lang == 'language-clike'
? const ['c', 'java']
: [
element.code!.lang!
.replaceAll('language-', '')
.replaceAll('like', ''),
],
)
.render(renderer);
return Container( return Container(
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
decoration: BoxDecoration( decoration: BoxDecoration(

View File

@@ -581,20 +581,7 @@ class ReplyItemGrpc extends StatelessWidget {
) { ) {
final Content content = replyItem.content; final Content content = replyItem.content;
final List<InlineSpan> spanChildren = <InlineSpan>[]; final List<InlineSpan> spanChildren = <InlineSpan>[];
bool hasNote = false;
if (content.richText.hasNote()) {
spanChildren.add(
TextSpan(
text: '[笔记] ',
style: TextStyle(
color: theme.colorScheme.primary,
),
recognizer: TapGestureRecognizer()
..onTap = () =>
PageUtils.handleWebview(content.richText.note.clickUrl),
),
);
}
final urlKeys = content.urls.keys; final urlKeys = content.urls.keys;
// 构建正则表达式 // 构建正则表达式
@@ -626,6 +613,9 @@ class ReplyItemGrpc extends StatelessWidget {
return; return;
} }
final isCv = url.clickReport.startsWith('{"cvid'); final isCv = url.clickReport.startsWith('{"cvid');
if (isCv) {
hasNote = true;
}
final children = [ final children = [
if (!isCv && url.hasPrefixIcon()) if (!isCv && url.hasPrefixIcon())
WidgetSpan( WidgetSpan(
@@ -825,6 +815,28 @@ class ReplyItemGrpc extends StatelessWidget {
} }
} }
if (!hasNote &&
(content.richText.hasNote() ||
replyItem.replyControl.bizScene == 'note')) {
final hasClickUrl = content.richText.note.hasClickUrl();
spanChildren.insert(
0,
TextSpan(
text: '[笔记] ',
style: TextStyle(
color: hasClickUrl
? theme.colorScheme.primary
: theme.colorScheme.secondary,
),
recognizer: hasClickUrl
? (TapGestureRecognizer()
..onTap = () =>
PageUtils.handleWebview(content.richText.note.clickUrl))
: null,
),
);
}
return TextSpan(children: spanChildren); return TextSpan(children: spanChildren);
} }

View File

@@ -616,6 +616,9 @@ class _PLVideoPlayerState extends State<PLVideoPlayer>
final VideoQuality currentVideoQa = final VideoQuality currentVideoQa =
videoDetailCtr.currentVideoQa.value; videoDetailCtr.currentVideoQa.value;
final PlayUrlModel videoInfo = videoDetailCtr.data; final PlayUrlModel videoInfo = videoDetailCtr.data;
if (videoInfo.dash == null) {
return const SizedBox.shrink();
}
final List<FormatItem> videoFormat = videoInfo.supportFormats!; final List<FormatItem> videoFormat = videoInfo.supportFormats!;
final int totalQaSam = videoFormat.length; final int totalQaSam = videoFormat.length;
int userfulQaSam = 0; int userfulQaSam = 0;

View File

@@ -244,6 +244,8 @@ class LiveMessageStream {
} }
} }
}, },
onDone: close,
onError: (_) => close(),
); );
_channel?.sink.add(authPackage.marshal()); _channel?.sink.add(authPackage.marshal());
} catch (e) { } catch (e) {
@@ -276,6 +278,7 @@ class LiveMessageStream {
Future<void> _heartBeat() async { Future<void> _heartBeat() async {
if (!_active) { if (!_active) {
if (kDebugMode) logger.i("$logTag init heartBeat inactive $hashCode"); if (kDebugMode) logger.i("$logTag init heartBeat inactive $hashCode");
close();
return; return;
} }
if (kDebugMode) logger.i("$logTag 直播间信息流认证成功 $hashCode"); if (kDebugMode) logger.i("$logTag 直播间信息流认证成功 $hashCode");
@@ -284,6 +287,7 @@ class LiveMessageStream {
if (!_active) { if (!_active) {
if (kDebugMode) logger.i("$logTag heartBeat inactive $hashCode"); if (kDebugMode) logger.i("$logTag heartBeat inactive $hashCode");
timer.cancel(); timer.cancel();
close();
return; return;
} }
if (kDebugMode) logger.i("$logTag heartBeat $hashCode"); if (kDebugMode) logger.i("$logTag heartBeat $hashCode");
@@ -313,8 +317,11 @@ class LiveMessageStream {
_active = false; _active = false;
if (kDebugMode) logger.i("$logTag close $hashCode"); if (kDebugMode) logger.i("$logTag close $hashCode");
_timer?.cancel(); _timer?.cancel();
_timer = null;
_eventListeners.clear(); _eventListeners.clear();
_socketSubscription?.cancel(); _socketSubscription?.cancel();
_socketSubscription = null;
_channel?.sink.close(); _channel?.sink.close();
_channel = null;
} }
} }