From 3dad24e7b48d2a1bd749e3b18fae17b927d6c393 Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Sun, 27 Apr 2025 10:10:22 +0800 Subject: [PATCH] mod: article: show code Closes #759 Signed-off-by: bggRGjQaUbCoE --- lib/common/constants.dart | 2 +- .../widgets/video_card_h_member_video.dart | 2 +- .../widgets/video_progress_indicator.dart | 5 ++- lib/http/video.dart | 2 +- .../dynamics/opus_detail/paragraph.dart | 13 ++++++ lib/models/home/rcmd/result.dart | 2 +- lib/pages/article/widgets/opus_content.dart | 42 +++++++++++++++---- lib/pages/fav/note/widget/item.dart | 2 +- lib/pages/fav_detail/view.dart | 2 +- lib/pages/history/widgets/item.dart | 2 +- lib/pages/home/view.dart | 3 +- lib/pages/later/child_view.dart | 2 +- lib/pages/member/widget/user_info_card.dart | 6 ++- .../video/detail/post_panel/post_panel.dart | 2 +- lib/pages/webdav/view.dart | 5 ++- lib/utils/url_utils.dart | 2 +- pubspec.lock | 8 ++++ pubspec.yaml | 1 + 18 files changed, 78 insertions(+), 25 deletions(-) diff --git a/lib/common/constants.dart b/lib/common/constants.dart index 81712295..a17917cf 100644 --- a/lib/common/constants.dart +++ b/lib/common/constants.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; class StyleString { static const double cardSpace = 8; static const double safeSpace = 12; - static const BorderRadius mdRadius = BorderRadius.all(Radius.circular(10)); + static const BorderRadius mdRadius = BorderRadius.all(imgRadius); static const Radius imgRadius = Radius.circular(10); static const double aspectRatio = 16 / 10; } diff --git a/lib/common/widgets/video_card_h_member_video.dart b/lib/common/widgets/video_card_h_member_video.dart index 7d7a6d4f..19b336d6 100644 --- a/lib/common/widgets/video_card_h_member_video.dart +++ b/lib/common/widgets/video_card_h_member_video.dart @@ -88,7 +88,7 @@ class VideoCardHMemberVideo extends StatelessWidget { Positioned.fill( child: DecoratedBox( decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), + borderRadius: StyleString.mdRadius, color: Colors.black54, ), child: Center( diff --git a/lib/common/widgets/video_progress_indicator.dart b/lib/common/widgets/video_progress_indicator.dart index 4066443c..4fe85200 100644 --- a/lib/common/widgets/video_progress_indicator.dart +++ b/lib/common/widgets/video_progress_indicator.dart @@ -1,11 +1,12 @@ +import 'package:PiliPlus/common/constants.dart'; import 'package:flutter/material.dart'; Widget videoProgressIndicator(double progress) => ClipRect( clipper: ProgressClipper(), child: ClipRRect( borderRadius: BorderRadius.only( - bottomLeft: Radius.circular(10), - bottomRight: Radius.circular(10), + bottomLeft: StyleString.imgRadius, + bottomRight: StyleString.imgRadius, ), child: LinearProgressIndicator( minHeight: 10, diff --git a/lib/http/video.dart b/lib/http/video.dart index b51080f7..6dfefeed 100644 --- a/lib/http/video.dart +++ b/lib/http/video.dart @@ -1114,7 +1114,7 @@ class VideoHttp { 'csrf': Accounts.main.csrf, }); if (res.data['code'] == 0) { - if (res.data['data']['noteIds'] != null) { + if (res.data['data']?['noteIds'] != null) { noteId = res.data['data']['noteIds'].first; } } diff --git a/lib/models/dynamics/opus_detail/paragraph.dart b/lib/models/dynamics/opus_detail/paragraph.dart index 8ea2e1f6..e69ce5e2 100644 --- a/lib/models/dynamics/opus_detail/paragraph.dart +++ b/lib/models/dynamics/opus_detail/paragraph.dart @@ -8,6 +8,7 @@ class Paragraph { Pic? pic; Line? line; LinkCard? linkCard; + Code? code; Paragraph({ this.align, @@ -16,6 +17,7 @@ class Paragraph { this.pic, this.line, this.linkCard, + this.code, }); factory Paragraph.fromJson(Map json) => Paragraph( @@ -31,6 +33,7 @@ class Paragraph { linkCard: json['link_card'] == null ? null : LinkCard.fromJson(json['link_card']), + code: json['code'] == null ? null : Code.fromJson(json['code']), ); Map toJson() => { @@ -41,6 +44,16 @@ class Paragraph { }; } +class Code { + String? content; + String? lang; + + Code.fromJson(Map json) { + content = json['content']; + lang = json['lang']; + } +} + class Ugc { String? cover; String? descSecond; diff --git a/lib/models/home/rcmd/result.dart b/lib/models/home/rcmd/result.dart index 0b5f3bef..6f6141c7 100644 --- a/lib/models/home/rcmd/result.dart +++ b/lib/models/home/rcmd/result.dart @@ -85,7 +85,7 @@ class RcmdStat implements BaseStat { class RcmdOwner extends BaseOwner { RcmdOwner.fromJson(Map json) { name = json['goto'] == 'av' - ? (json['args']?['up_name']) + ? (json['args']?['up_name'] ?? '') : (json['desc_button']?['text'] ?? ''); mid = json['args']?['up_id'] ?? 0; } diff --git a/lib/pages/article/widgets/opus_content.dart b/lib/pages/article/widgets/opus_content.dart index 908256df..1b4db190 100644 --- a/lib/pages/article/widgets/opus_content.dart +++ b/lib/pages/article/widgets/opus_content.dart @@ -1,3 +1,4 @@ +import 'package:PiliPlus/common/constants.dart'; import 'package:PiliPlus/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart' show SourceModel; import 'package:PiliPlus/common/widgets/network_img_layer.dart'; @@ -9,6 +10,9 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; +import 'package:re_highlight/languages/all.dart'; +import 'package:re_highlight/re_highlight.dart'; +import 'package:re_highlight/styles/all.dart'; Widget opusContent({ required BuildContext context, @@ -95,7 +99,7 @@ Widget opusContent({ return SelectableText.rich( textAlign: element.align == 1 ? TextAlign.center : null, TextSpan( - children: element.text?.nodes!.map((item) { + children: element.text?.nodes?.map((item) { if (item.rich != null) { return TextSpan( text: '\u{1F517}${item.rich?.text}', @@ -149,10 +153,7 @@ Widget opusContent({ child: GestureDetector( onTap: () { if (callback != null) { - callback( - [element.pic!.pics!.first.url!], - 0, - ); + callback([element.pic!.pics!.first.url!], 0); } else { context.imageView( initialPage: 0, @@ -183,8 +184,7 @@ Widget opusContent({ if (element.paraType == 6) { if (element.linkCard?.card?.ugc != null) { - return Card( - margin: EdgeInsets.zero, + return Material( shape: RoundedRectangleBorder( borderRadius: const BorderRadius.all(Radius.circular(8)), @@ -207,7 +207,7 @@ Widget opusContent({ children: [ NetworkImgLayer( radius: 6, - width: 65 * 16 / 10, + width: 65 * StyleString.aspectRatio, height: 65, src: element.linkCard!.card!.ugc!.cover, ), @@ -237,6 +237,32 @@ Widget opusContent({ } } + if (element.paraType == 7) { + final Highlight highlight = Highlight() + ..registerLanguages(builtinAllLanguages); + final HighlightResult result = highlight.highlightAuto( + element.code!.content!, + element.code!.lang == 'language-clike' + ? ['c', 'java'] + : [ + element.code!.lang! + .replaceAll('language-', '') + .replaceAll('like', ''), + ]); + final TextSpanRenderer renderer = TextSpanRenderer( + const TextStyle(), builtinAllThemes['github']!); + result.render(renderer); + return Container( + padding: const EdgeInsets.all(12), + decoration: BoxDecoration( + borderRadius: const BorderRadius.all(Radius.circular(8)), + color: Theme.of(context).colorScheme.onInverseSurface, + ), + width: double.infinity, + child: SelectableText.rich(renderer.span!), + ); + } + return const SizedBox.shrink(); }, separatorBuilder: (BuildContext context, int index) => diff --git a/lib/pages/fav/note/widget/item.dart b/lib/pages/fav/note/widget/item.dart index 848572b4..655c367d 100644 --- a/lib/pages/fav/note/widget/item.dart +++ b/lib/pages/fav/note/widget/item.dart @@ -118,7 +118,7 @@ class FavNoteItem extends StatelessWidget { width: constraints.maxHeight * StyleString.aspectRatio, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), + borderRadius: StyleString.mdRadius, color: Colors.black.withOpacity(0.6), ), child: SizedBox( diff --git a/lib/pages/fav_detail/view.dart b/lib/pages/fav_detail/view.dart index c3125164..e0e9e7ec 100644 --- a/lib/pages/fav_detail/view.dart +++ b/lib/pages/fav_detail/view.dart @@ -534,7 +534,7 @@ class _FavDetailPageState extends State { width: constraints.maxHeight * StyleString.aspectRatio, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), + borderRadius: StyleString.mdRadius, color: Colors.black.withOpacity(0.6), ), child: SizedBox( diff --git a/lib/pages/history/widgets/item.dart b/lib/pages/history/widgets/item.dart index bc48f0ec..534f27d1 100644 --- a/lib/pages/history/widgets/item.dart +++ b/lib/pages/history/widgets/item.dart @@ -182,7 +182,7 @@ class HistoryItem extends StatelessWidget { child: Container( alignment: Alignment.center, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), + borderRadius: StyleString.mdRadius, color: Colors.black.withOpacity(0.6), ), child: SizedBox( diff --git a/lib/pages/home/view.dart b/lib/pages/home/view.dart index 5a74f631..f64fd68e 100644 --- a/lib/pages/home/view.dart +++ b/lib/pages/home/view.dart @@ -1,3 +1,4 @@ +import 'package:PiliPlus/common/constants.dart'; import 'package:PiliPlus/models/common/dynamic_badge_mode.dart'; import 'package:PiliPlus/pages/main/index.dart'; import 'package:PiliPlus/pages/mine/controller.dart'; @@ -52,7 +53,7 @@ class _HomePageState extends State dividerColor: Colors.transparent, dividerHeight: 0, enableFeedback: true, - splashBorderRadius: BorderRadius.circular(10), + splashBorderRadius: StyleString.mdRadius, tabAlignment: TabAlignment.center, onTap: (value) { feedBack(); diff --git a/lib/pages/later/child_view.dart b/lib/pages/later/child_view.dart index dcbf3d38..1202a40b 100644 --- a/lib/pages/later/child_view.dart +++ b/lib/pages/later/child_view.dart @@ -132,7 +132,7 @@ class _LaterViewChildPageState extends State width: constraints.maxHeight * StyleString.aspectRatio, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10), + borderRadius: StyleString.mdRadius, color: Colors.black.withOpacity(0.6), ), child: SizedBox( diff --git a/lib/pages/member/widget/user_info_card.dart b/lib/pages/member/widget/user_info_card.dart index 06411309..3896edad 100644 --- a/lib/pages/member/widget/user_info_card.dart +++ b/lib/pages/member/widget/user_info_card.dart @@ -1,3 +1,4 @@ +import 'package:PiliPlus/common/constants.dart'; import 'package:PiliPlus/common/widgets/avatar.dart'; import 'package:PiliPlus/common/widgets/interactiveviewer_gallery/interactiveviewer_gallery.dart' show SourceModel; @@ -145,8 +146,9 @@ class UserInfoCard extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 3), decoration: BoxDecoration( - borderRadius: const BorderRadius.all(Radius.circular(10)), - color: context.vipColor), + borderRadius: StyleString.mdRadius, + color: context.vipColor, + ), child: Text( card.vip?.label?.text ?? '大会员', strutStyle: const StrutStyle( diff --git a/lib/pages/video/detail/post_panel/post_panel.dart b/lib/pages/video/detail/post_panel/post_panel.dart index 88d377a9..45bee52e 100644 --- a/lib/pages/video/detail/post_panel/post_panel.dart +++ b/lib/pages/video/detail/post_panel/post_panel.dart @@ -564,7 +564,7 @@ class _PostPanelState extends CommonCollapseSlidePageState { } } else { if (const [301, 302, 303, 307, 308].contains(res.statusCode)) { - String? redirectUrl = res.headers['location']?.first; + String? redirectUrl = res.headers['location']?.firstOrNull; if (redirectUrl != null) { _onPost(url: redirectUrl); return; diff --git a/lib/pages/webdav/view.dart b/lib/pages/webdav/view.dart index 7e7753d4..6eaebba5 100644 --- a/lib/pages/webdav/view.dart +++ b/lib/pages/webdav/view.dart @@ -1,3 +1,4 @@ +import 'package:PiliPlus/common/constants.dart'; import 'package:PiliPlus/pages/webdav/webdav.dart'; import 'package:PiliPlus/utils/storage.dart'; import 'package:flutter/material.dart'; @@ -83,7 +84,7 @@ class _WebDavSettingPageState extends State { child: FilledButton.tonal( style: FilledButton.styleFrom( shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), + borderRadius: StyleString.mdRadius, ), ), onPressed: WebDav().backup, @@ -95,7 +96,7 @@ class _WebDavSettingPageState extends State { child: FilledButton.tonal( style: FilledButton.styleFrom( shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(10), + borderRadius: StyleString.mdRadius, ), ), onPressed: WebDav().restore, diff --git a/lib/utils/url_utils.dart b/lib/utils/url_utils.dart index 104f8a3d..c1a1f201 100644 --- a/lib/utils/url_utils.dart +++ b/lib/utils/url_utils.dart @@ -25,7 +25,7 @@ class UrlUtils { ), ); if (response.statusCode == 302 || response.statusCode == 301) { - String? redirectUrl = response.headers['location']?.first; + String? redirectUrl = response.headers['location']?.firstOrNull; debugPrint('redirectUrl: $redirectUrl'); if (redirectUrl != null) { if (redirectUrl.startsWith('/')) { diff --git a/pubspec.lock b/pubspec.lock index 9e5a2602..47c46ebe 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1480,6 +1480,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.2" + re_highlight: + dependency: "direct main" + description: + name: re_highlight + sha256: "6c4ac3f76f939fb7ca9df013df98526634e17d8f7460e028bd23a035870024f2" + url: "https://pub.dev" + source: hosted + version: "0.0.3" rxdart: dependency: "direct overridden" description: diff --git a/pubspec.yaml b/pubspec.yaml index b0696790..83434765 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -190,6 +190,7 @@ dependencies: synchronized: ^3.3.0 document_file_save_plus: ^2.0.0 webdav_client: ^1.2.2 + re_highlight: ^0.0.3 dependency_overrides: screen_brightness: ^2.0.1