From a66bb08ca85fe8a0480e7ac124625216e1bddf26 Mon Sep 17 00:00:00 2001 From: guozhigq Date: Sun, 7 May 2023 17:36:06 +0800 Subject: [PATCH] =?UTF-8?q?mod:=20=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/fonts/ArchivoNarrow-BoldItalic.ttf | Bin 0 -> 60736 bytes lib/common/skeleton/video_card_h.dart | 2 +- lib/common/skeleton/video_card_v.dart | 6 - lib/common/skeleton/video_reply.dart | 18 +- lib/main.dart | 6 +- lib/models/video/reply/content.dart | 3 + lib/pages/home/widgets/app_bar.dart | 14 +- lib/pages/main/view.dart | 2 +- lib/pages/mine/view.dart | 184 +++++++++++- lib/pages/video/detail/introduction/view.dart | 253 ++++++++--------- lib/pages/video/detail/related/view.dart | 1 + .../detail/reply/widgets/reply_item.dart | 268 +++++++++++------- pubspec.lock | 8 + pubspec.yaml | 4 + 14 files changed, 509 insertions(+), 260 deletions(-) create mode 100644 assets/fonts/ArchivoNarrow-BoldItalic.ttf diff --git a/assets/fonts/ArchivoNarrow-BoldItalic.ttf b/assets/fonts/ArchivoNarrow-BoldItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e69fb6a58e756296e3a733f9acccec7f1bc98c03 GIT binary patch literal 60736 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 D*#@&= literal 0 HcmV?d00001 diff --git a/lib/common/skeleton/video_card_h.dart b/lib/common/skeleton/video_card_h.dart index dc5e9c32..46b858d3 100644 --- a/lib/common/skeleton/video_card_h.dart +++ b/lib/common/skeleton/video_card_h.dart @@ -59,7 +59,7 @@ class _VideoCardHSkeletonState extends State { .colorScheme .onInverseSurface, width: 200, - height: 13, + height: 11, margin: const EdgeInsets.only(bottom: 5), ), Container( diff --git a/lib/common/skeleton/video_card_v.dart b/lib/common/skeleton/video_card_v.dart index 4f83501e..aeff595f 100644 --- a/lib/common/skeleton/video_card_v.dart +++ b/lib/common/skeleton/video_card_v.dart @@ -25,12 +25,6 @@ class VideoCardVSkeleton extends StatelessWidget { decoration: BoxDecoration( color: Theme.of(context).colorScheme.background, borderRadius: BorderRadius.circular(6), - border: Border.all( - color: Theme.of(context) - .colorScheme - .outline - .withOpacity(0.1), - ), ), ); }, diff --git a/lib/common/skeleton/video_reply.dart b/lib/common/skeleton/video_reply.dart index 09efa8ce..219540eb 100644 --- a/lib/common/skeleton/video_reply.dart +++ b/lib/common/skeleton/video_reply.dart @@ -23,8 +23,8 @@ class VideoReplySkeleton extends StatelessWidget { ), const SizedBox(width: 12), Container( - width: 120, - height: 16, + width: 80, + height: 13, color: bgColor, ) ], @@ -40,28 +40,28 @@ class VideoReplySkeleton extends StatelessWidget { children: [ Container( width: 300, - height: 16, + height: 14, margin: const EdgeInsets.only(bottom: 4), color: bgColor, ), Container( width: 180, - height: 16, - margin: const EdgeInsets.only(bottom: 6), + height: 14, + margin: const EdgeInsets.only(bottom: 10), color: bgColor, ), Row( children: [ Container( - width: 60, - height: 16, + width: 40, + height: 14, margin: const EdgeInsets.only(bottom: 4), color: bgColor, ), const Spacer(), Container( - width: 60, - height: 16, + width: 40, + height: 14, margin: const EdgeInsets.only(bottom: 4), color: bgColor, ), diff --git a/lib/main.dart b/lib/main.dart index b3eb8796..08059adf 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -27,7 +27,11 @@ class MyApp extends StatelessWidget { ColorScheme.fromSeed( seedColor: Colors.green, brightness: Brightness.light), useMaterial3: true), - darkTheme: ThemeData(colorScheme: darkDynamic, useMaterial3: true), + darkTheme: ThemeData( + colorScheme: darkDynamic ?? + ColorScheme.fromSeed( + seedColor: Colors.green, brightness: Brightness.dark), + useMaterial3: true), getPages: Routes.getPages, home: const MainApp(), // home: const Scaffold(), diff --git a/lib/models/video/reply/content.dart b/lib/models/video/reply/content.dart index 42ccaded..97897f75 100644 --- a/lib/models/video/reply/content.dart +++ b/lib/models/video/reply/content.dart @@ -6,6 +6,7 @@ class ReplyContent { this.emote, // 表情包 如果有的话 null this.jumpUrl, // {} this.pictures, // {} + this.vote, }); String? message; @@ -14,6 +15,7 @@ class ReplyContent { Map? emote; Map? jumpUrl; List? pictures; + Map? vote; ReplyContent.fromJson(Map json) { message = json['message']; @@ -22,5 +24,6 @@ class ReplyContent { emote = json['emote'] ?? {}; jumpUrl = json['jump_url'] ?? {}; pictures = json['pictures'] ?? []; + vote = json['vote'] ?? {}; } } diff --git a/lib/pages/home/widgets/app_bar.dart b/lib/pages/home/widgets/app_bar.dart index 56a53861..eb62ece2 100644 --- a/lib/pages/home/widgets/app_bar.dart +++ b/lib/pages/home/widgets/app_bar.dart @@ -1,5 +1,6 @@ import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; class HomeAppBar extends StatelessWidget { const HomeAppBar({super.key}); @@ -29,19 +30,26 @@ class HomeAppBar extends StatelessWidget { title: const Text( 'PiLiPaLa', style: TextStyle( - fontSize: 18, + fontSize: 19, fontWeight: FontWeight.bold, letterSpacing: 1, + fontFamily: 'ArchivoNarrow', ), ), actions: [ IconButton( onPressed: () {}, - icon: const Icon(Icons.notifications_none_rounded), + icon: const FaIcon( + FontAwesomeIcons.magnifyingGlass, + size: 18, + ), ), IconButton( onPressed: () {}, - icon: const Icon(Icons.search_rounded), + icon: const FaIcon( + FontAwesomeIcons.envelope, + size: 20, + ), ), const SizedBox(width: 10) ], diff --git a/lib/pages/main/view.dart b/lib/pages/main/view.dart index 0b7556f4..89b952c0 100644 --- a/lib/pages/main/view.dart +++ b/lib/pages/main/view.dart @@ -19,7 +19,7 @@ class _MainAppState extends State with SingleTickerProviderStateMixin { late AnimationController? _animationController; late Animation? _fadeAnimation; late Animation? _slideAnimation; - int selectedIndex = 0; + int selectedIndex = 2; int? _lastSelectTime; //上次点击时间 @override diff --git a/lib/pages/mine/view.dart b/lib/pages/mine/view.dart index fd455db0..c2ae6532 100644 --- a/lib/pages/mine/view.dart +++ b/lib/pages/mine/view.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:pilipala/common/constants.dart'; class MinePage extends StatefulWidget { const MinePage({super.key}); @@ -12,7 +14,187 @@ class _MinePageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: const Text('我的'), + title: null, + actions: [ + IconButton( + onPressed: () {}, + icon: const Icon(Icons.light_mode_rounded), + ), + IconButton( + onPressed: () {}, + icon: const FaIcon( + FontAwesomeIcons.sliders, + size: 18, + ), + ), + const SizedBox(width: 10), + ], + ), + body: Padding( + padding: const EdgeInsets.only(left: 12, right: 12), + child: Column( + children: [ + Row( + children: [ + const SizedBox(width: 20), + ClipOval( + child: Container( + width: 75, + height: 75, + color: Theme.of(context).colorScheme.onInverseSurface, + child: Center( + child: Image.asset('assets/images/loading.png'), + ), + ), + ), + const SizedBox(width: 14), + Text( + '点击登录', + style: Theme.of(context).textTheme.titleMedium, + ), + ], + ), + const SizedBox(height: 20), + LayoutBuilder( + builder: (context, constraints) { + TextStyle style = TextStyle( + fontSize: Theme.of(context).textTheme.titleMedium!.fontSize, + color: Theme.of(context).colorScheme.primary, + fontWeight: FontWeight.bold); + return SizedBox( + height: constraints.maxWidth / 3 * 0.6, + child: GridView.count( + primary: false, + padding: const EdgeInsets.all(0), + crossAxisCount: 3, + childAspectRatio: 1.67, + children: [ + InkWell( + onTap: () {}, + borderRadius: StyleString.mdRadius, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text('-', style: style), + const SizedBox(height: 8), + Text( + '动态', + style: Theme.of(context).textTheme.labelMedium, + ), + ], + ), + ), + InkWell( + onTap: () {}, + borderRadius: StyleString.mdRadius, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '50', + style: style, + ), + const SizedBox(height: 8), + Text( + '关注', + style: Theme.of(context).textTheme.labelMedium, + ), + ], + ), + ), + InkWell( + onTap: () {}, + borderRadius: StyleString.mdRadius, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + '-', + style: style, + ), + const SizedBox(height: 8), + Text( + '粉丝', + style: Theme.of(context).textTheme.labelMedium, + ), + ], + ), + ), + ], + ), + ); + }, + ), + const SizedBox(height: 20), + LayoutBuilder( + builder: (context, constraints) { + return SizedBox( + height: constraints.maxWidth / 4 * 0.8, + child: GridView.count( + primary: false, + padding: const EdgeInsets.all(0), + crossAxisCount: 4, + childAspectRatio: 1.25, + children: [ + ActionItem( + icon: const Icon(FontAwesomeIcons.download), + onTap: () => {}, + text: '离线缓存', + ), + ActionItem( + icon: const Icon(FontAwesomeIcons.clockRotateLeft), + onTap: () => {}, + text: '历史记录', + ), + ActionItem( + icon: const Icon(FontAwesomeIcons.star), + onTap: () => {}, + text: '我的收藏', + ), + ActionItem( + icon: const Icon(FontAwesomeIcons.film), + onTap: () => {}, + text: '稍后再看', + ), + ], + ), + ); + }, + ), + ], + ), + ), + ); + } +} + +class ActionItem extends StatelessWidget { + Icon? icon; + Function? onTap; + String? text; + + ActionItem({ + Key? key, + this.icon, + this.onTap, + this.text, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () {}, + borderRadius: StyleString.mdRadius, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(icon!.icon!), + const SizedBox(height: 8), + Text( + text!, + style: Theme.of(context).textTheme.labelMedium, + ), + ], ), ); } diff --git a/lib/pages/video/detail/introduction/view.dart b/lib/pages/video/detail/introduction/view.dart index 52a6efb0..8aa0d570 100644 --- a/lib/pages/video/detail/introduction/view.dart +++ b/lib/pages/video/detail/introduction/view.dart @@ -1,3 +1,4 @@ +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:get/get.dart'; import 'package:flutter/material.dart'; import 'package:pilipala/common/constants.dart'; @@ -114,116 +115,29 @@ class _VideoInfoState extends State with TickerProviderStateMixin { @override Widget build(BuildContext context) { return SliverPadding( - padding: const EdgeInsets.only(left: 12, right: 12, top: 25), + padding: const EdgeInsets.only(left: 12, right: 12, top: 20), sliver: SliverToBoxAdapter( child: !widget.loadingStatus || videoItem.isNotEmpty ? Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - children: [ - NetworkImgLayer( - type: 'avatar', - src: !widget.loadingStatus - ? widget.videoDetail!.owner!.face - : videoItem['owner'].face, - width: 38, - height: 38, - fadeInDuration: Duration.zero, - fadeOutDuration: Duration.zero, - ), - const SizedBox(width: 14), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text(!widget.loadingStatus - ? widget.videoDetail!.owner!.name - : videoItem['owner'].name), - const SizedBox(height: 2), - Text( - widget.loadingStatus - ? '- 粉丝' - : '${Utils.numFormat(widget.videoIntroController!.userStat['follower'])}粉丝', - style: TextStyle( - fontSize: Theme.of(context) - .textTheme - .labelSmall! - .fontSize, - color: Theme.of(context).colorScheme.outline), - ) - ]), - const Spacer(), - AnimatedOpacity( - opacity: widget.loadingStatus ? 0 : 1, - duration: const Duration(milliseconds: 150), - child: SizedBox( - height: 35, - child: ElevatedButton( - onPressed: () {}, child: const Text('+ 关注')), - ), - ), - const SizedBox(width: 4), - ], + SelectableRegion( + magnifierConfiguration: const TextMagnifierConfiguration(), + focusNode: FocusNode(), + selectionControls: MaterialTextSelectionControls(), + child: Text( + !widget.loadingStatus + ? widget.videoDetail!.title + : videoItem['title'], + style: Theme.of(context).textTheme.titleMedium!.copyWith( + letterSpacing: 0.5, + ), + ), ), - const SizedBox(height: 13), - // 标题 超过两行收起 - // Container( - // color: Colors.blue[50], - // child: SizedOverflowBox( - // size: const Size(50.0, 50.0), - // alignment: AlignmentDirectional.bottomStart, - // child: Container(height: 150.0, width: 150.0, color: Colors.blue,), - // ), - // ), - // Row( - // children: [ - // Expanded( - // child: ExpandedSection( - // expand: false, - // begin: 1, - // end: 1, - // child: Text( - // !widget.loadingStatus - // ? widget.videoDetail!.title - // : videoItem['title'], - // overflow: TextOverflow.ellipsis, - // maxLines: 1, - // ), - // ), - // ), - // const SizedBox(width: 10), - // RotationTransition( - // turns: _manualAnimation!, - // child: IconButton( - // onPressed: () { - // /// 获取动画当前的值 - // var value = _manualController!.value; - - // /// 0.5代表 180弧度 - // if (value == 0) { - // _manualController!.animateTo(0.5); - // } else { - // _manualController!.animateTo(0); - // } - // setState(() { - // isExpand = !isExpand; - // }); - // }, - // icon: const Icon(Icons.expand_less)), - // ), - // ], - // ), - - Text( - !widget.loadingStatus - ? widget.videoDetail!.title - : videoItem['title'], - ), - // const SizedBox(height: 5), - // 播放量、评论、日期 - InkWell( splashColor: Colors.transparent, + hoverColor: Colors.transparent, + highlightColor: Colors.transparent, onTap: () { _manualController!.animateTo(isExpand ? 0 : 0.5); setState(() { @@ -276,8 +190,8 @@ class _VideoInfoState extends State with TickerProviderStateMixin { }); }, icon: Icon( - Icons.expand_less, - size: 22, + FontAwesomeIcons.angleUp, + size: 15, color: Theme.of(context).colorScheme.outline, ), ), @@ -287,8 +201,65 @@ class _VideoInfoState extends State with TickerProviderStateMixin { ], ), ), - - // const SizedBox(height: 5), + const SizedBox(height: 12), + Row( + children: [ + NetworkImgLayer( + type: 'avatar', + src: !widget.loadingStatus + ? widget.videoDetail!.owner!.face + : videoItem['owner'].face, + width: 38, + height: 38, + fadeInDuration: Duration.zero, + fadeOutDuration: Duration.zero, + ), + const SizedBox(width: 14), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text(!widget.loadingStatus + ? widget.videoDetail!.owner!.name + : videoItem['owner'].name), + // const SizedBox(width: 10), + Text( + widget.loadingStatus + ? '- 粉丝' + : '${Utils.numFormat(widget.videoIntroController!.userStat['follower'])}粉丝', + style: TextStyle( + fontSize: Theme.of(context) + .textTheme + .labelSmall! + .fontSize, + color: Theme.of(context).colorScheme.outline), + ), + ], + ), + const Spacer(), + AnimatedOpacity( + opacity: widget.loadingStatus ? 0 : 1, + duration: const Duration(milliseconds: 150), + child: SizedBox( + height: 36, + child: ElevatedButton( + onPressed: () {}, + child: Row( + children: const [ + Icon( + FontAwesomeIcons.lemon, + size: 17, + ), + SizedBox(width: 4), + Text('关注'), + ], + ), + ), + ), + ), + const SizedBox(width: 4), + ], + ), + const SizedBox(height: 10), // 简介 默认收起 if (!widget.loadingStatus) ExpandedSection( @@ -320,8 +291,8 @@ class _VideoInfoState extends State with TickerProviderStateMixin { ), ), ), + const SizedBox(height: 5), _actionGrid(context), - // const SizedBox(height: 5), ], ) : const Center(child: CircularProgressIndicator()), @@ -333,14 +304,15 @@ class _VideoInfoState extends State with TickerProviderStateMixin { Widget _actionGrid(BuildContext context) { return LayoutBuilder(builder: (context, constraints) { return SizedBox( - height: constraints.maxWidth / 5, + height: constraints.maxWidth / 5 * 0.8, child: GridView.count( primary: false, padding: const EdgeInsets.all(0), crossAxisCount: 5, + childAspectRatio: 1.25, children: [ ActionItem( - icon: const Icon(Icons.thumb_up), + icon: const Icon(FontAwesomeIcons.thumbsUp), onTap: () => {}, selectStatus: false, loadingStatus: widget.loadingStatus, @@ -348,13 +320,13 @@ class _VideoInfoState extends State with TickerProviderStateMixin { ? widget.videoDetail!.stat!.like!.toString() : '-'), ActionItem( - icon: const Icon(Icons.thumb_down), + icon: const Icon(FontAwesomeIcons.thumbsDown), onTap: () => {}, selectStatus: false, loadingStatus: widget.loadingStatus, text: '不喜欢'), ActionItem( - icon: const Icon(Icons.generating_tokens), + icon: const Icon(FontAwesomeIcons.b), onTap: () => {}, selectStatus: false, loadingStatus: widget.loadingStatus, @@ -362,7 +334,10 @@ class _VideoInfoState extends State with TickerProviderStateMixin { ? widget.videoDetail!.stat!.coin!.toString() : '-'), ActionItem( - icon: const Icon(Icons.star), + icon: const Icon( + FontAwesomeIcons.heart, + size: 17, + ), onTap: () => {}, selectStatus: false, loadingStatus: widget.loadingStatus, @@ -370,7 +345,7 @@ class _VideoInfoState extends State with TickerProviderStateMixin { ? widget.videoDetail!.stat!.favorite!.toString() : '-'), ActionItem( - icon: const Icon(Icons.share), + icon: const Icon(FontAwesomeIcons.shareFromSquare), onTap: () => {}, selectStatus: false, loadingStatus: widget.loadingStatus, @@ -403,33 +378,35 @@ class ActionItem extends StatelessWidget { @override Widget build(BuildContext context) { return Material( - child: Ink( - child: InkWell( - onTap: () {}, - borderRadius: StyleString.mdRadius, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(icon!.icon!, - color: selectStatus - ? Theme.of(context).primaryColor - : Theme.of(context).colorScheme.outline), - const SizedBox(height: 2), - AnimatedOpacity( - opacity: loadingStatus! ? 0 : 1, - duration: const Duration(milliseconds: 200), - child: Text( - text!, - style: TextStyle( - color: selectStatus - ? Theme.of(context).primaryColor - : Theme.of(context).colorScheme.outline, - fontSize: Theme.of(context).textTheme.labelSmall?.fontSize), + child: Ink( + child: InkWell( + onTap: () {}, + borderRadius: StyleString.mdRadius, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(icon!.icon!, + color: selectStatus + ? Theme.of(context).primaryColor + : Theme.of(context).colorScheme.outline), + const SizedBox(height: 2), + AnimatedOpacity( + opacity: loadingStatus! ? 0 : 1, + duration: const Duration(milliseconds: 200), + child: Text( + text!, + style: TextStyle( + color: selectStatus + ? Theme.of(context).primaryColor + : Theme.of(context).colorScheme.outline, + fontSize: + Theme.of(context).textTheme.labelSmall?.fontSize), + ), ), - ), - ], + ], + ), ), ), - )); + ); } } diff --git a/lib/pages/video/detail/related/view.dart b/lib/pages/video/detail/related/view.dart index 4034cdfb..3c79ee50 100644 --- a/lib/pages/video/detail/related/view.dart +++ b/lib/pages/video/detail/related/view.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:pilipala/common/skeleton/video_card_h.dart'; import 'package:pilipala/common/widgets/video_card_h.dart'; +import 'package:pilipala/common/widgets/video_card_v.dart'; import './controller.dart'; class RelatedVideoPanel extends StatefulWidget { diff --git a/lib/pages/video/detail/reply/widgets/reply_item.dart b/lib/pages/video/detail/reply/widgets/reply_item.dart index 73bafe2f..3885d8f1 100644 --- a/lib/pages/video/detail/reply/widgets/reply_item.dart +++ b/lib/pages/video/detail/reply/widgets/reply_item.dart @@ -1,5 +1,6 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; +import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:get/get.dart'; import 'package:pilipala/common/widgets/network_img_layer.dart'; import 'package:pilipala/models/video/reply/item.dart'; @@ -289,45 +290,46 @@ class ReplyItemRow extends StatelessWidget { ); } else { return InkWell( - onTap: () {}, - child: Padding( - padding: EdgeInsets.fromLTRB( - 8, - index == 0 && (extraRow == 1 || replies!.length > 1) - ? 8 - : 5, - 8, - 5), - child: Text.rich( - overflow: extraRow == 1 - ? TextOverflow.ellipsis - : TextOverflow.visible, - maxLines: extraRow == 1 ? 2 : null, - TextSpan( - children: [ - if (replies![index].isUp) - WidgetSpan( - child: UpTag(), - ), - TextSpan( - text: replies![index].member.uname + ' ', - style: TextStyle( - fontSize: Theme.of(context) - .textTheme - .titleSmall! - .fontSize, - color: Theme.of(context).colorScheme.primary, - ), - recognizer: TapGestureRecognizer() - ..onTap = () => { - print('跳转至用户主页'), - }, + onTap: () {}, + child: Padding( + padding: EdgeInsets.fromLTRB( + 8, + index == 0 && (extraRow == 1 || replies!.length > 1) + ? 8 + : 5, + 8, + 5), + child: Text.rich( + overflow: extraRow == 1 + ? TextOverflow.ellipsis + : TextOverflow.visible, + maxLines: extraRow == 1 ? 2 : null, + TextSpan( + children: [ + if (replies![index].isUp) + WidgetSpan( + child: UpTag(), ), - buildContent(context, replies![index].content), - ], - ), + TextSpan( + text: replies![index].member.uname + ' ', + style: TextStyle( + fontSize: Theme.of(context) + .textTheme + .titleSmall! + .fontSize, + color: Theme.of(context).colorScheme.primary, + ), + recognizer: TapGestureRecognizer() + ..onTap = () => { + print('跳转至用户主页'), + }, + ), + buildContent(context, replies![index].content), + ], ), - )); + ), + ), + ); } }, ), @@ -382,6 +384,7 @@ InlineSpan buildContent(BuildContext context, content) { if (content.emote.isEmpty && content.atNameToMid.isEmpty && content.jumpUrl.isEmpty && + content.vote.isEmpty && content.pictures.isEmpty) { return TextSpan(text: content.message); } @@ -416,7 +419,7 @@ InlineSpan buildContent(BuildContext context, content) { String matchMember = str; if (content.atNameToMid.isNotEmpty) { matchMember = str.splitMapJoin( - RegExp(r"@.*:"), + RegExp(r"@.*( |:)"), onMatch: (Match match) { if (match[0] != null) { content.atNameToMid.forEach((key, value) { @@ -455,7 +458,6 @@ InlineSpan buildContent(BuildContext context, content) { RegExp("(?:${urlKeys.join("|")})"), onMatch: (Match match) { String matchStr = match[0]!; - // spanChilds.add(TextSpan(text: matchStr)); spanChilds.add( TextSpan( text: content.jumpUrl[matchStr]['title'], @@ -468,6 +470,16 @@ InlineSpan buildContent(BuildContext context, content) { }, ), ); + spanChilds.add( + WidgetSpan( + child: Icon( + FontAwesomeIcons.magnifyingGlass, + size: 9, + color: Theme.of(context).colorScheme.primary, + ), + alignment: PlaceholderAlignment.top, + ), + ); return ''; }, onNonMatch: (String str) { @@ -477,6 +489,29 @@ InlineSpan buildContent(BuildContext context, content) { ); } + str = matchUrl.splitMapJoin( + RegExp(r"\d{1,2}:\d{1,2}"), + onMatch: (Match match) { + String matchStr = match[0]!; + spanChilds.add( + TextSpan( + text: ' $matchStr ', + style: TextStyle( + color: Theme.of(context).colorScheme.primary, + ), + recognizer: TapGestureRecognizer() + ..onTap = () => { + print('time 点击'), + }, + ), + ); + return ''; + }, + onNonMatch: (str) { + return str; + }, + ); + if (content.atNameToMid.isEmpty && content.jumpUrl.isEmpty) { spanChilds.add(TextSpan(text: str)); } @@ -486,66 +521,98 @@ InlineSpan buildContent(BuildContext context, content) { // 图片渲染 if (content.pictures.isNotEmpty) { - List list = []; List picList = []; int len = content.pictures.length; - for (var i = 0; i < len; i++) { - picList.add(content.pictures[i]['img_src']); - list.add( - LayoutBuilder( - builder: (context, BoxConstraints box) { - return GestureDetector( - onTap: () { - Get.toNamed('/preview', - arguments: {'initialPage': i, 'imgList': picList}); - }, - child: NetworkImgLayer( - src: content.pictures[i]['img_src'], - width: box.maxWidth, - height: box.maxWidth, - ), - ); - }, + if (len == 1) { + Map pictureItem = content.pictures.first; + picList.add(pictureItem['img_src']); + spanChilds.add(const TextSpan(text: '\n')); + spanChilds.add( + WidgetSpan( + child: LayoutBuilder( + builder: (context, BoxConstraints box) { + return GestureDetector( + onTap: () { + Get.toNamed('/preview', + arguments: {'initialPage': 0, 'imgList': picList}); + }, + child: Padding( + padding: EdgeInsets.only(top: 4), + child: NetworkImgLayer( + src: pictureItem['img_src'], + width: box.maxWidth / 2, + height: box.maxWidth * + 0.5 * + pictureItem['img_height'] / + pictureItem['img_width'], + ), + ), + ); + }, + ), ), ); } - spanChilds.add( - WidgetSpan( - child: LayoutBuilder( - builder: (context, BoxConstraints box) { - double maxWidth = box.maxWidth; - double crossCount = len < 3 ? 2 : 3; - double height = maxWidth / - crossCount * - (len % crossCount == 0 - ? len ~/ crossCount - : len ~/ crossCount + 1) + - 6; - return Container( - padding: const EdgeInsets.only(top: 6), - height: height, - child: GridView( - padding: EdgeInsets.zero, - physics: const NeverScrollableScrollPhysics(), - // 子Item排列规则 - gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( - //横轴元素个数 - crossAxisCount: crossCount.toInt(), - //纵轴间距 - mainAxisSpacing: 4.0, - //横轴间距 - crossAxisSpacing: 4.0, - //子组件宽高长度比例 - // childAspectRatio: 1, + if (len > 1) { + List list = []; + for (var i = 0; i < len; i++) { + picList.add(content.pictures[i]['img_src']); + list.add( + LayoutBuilder( + builder: (context, BoxConstraints box) { + return GestureDetector( + onTap: () { + Get.toNamed('/preview', + arguments: {'initialPage': i, 'imgList': picList}); + }, + child: NetworkImgLayer( + src: content.pictures[i]['img_src'], + width: box.maxWidth, + height: box.maxWidth, ), - //GridView中使用的子Widegt - children: list, - ), - ); - }, + ); + }, + ), + ); + } + spanChilds.add( + WidgetSpan( + child: LayoutBuilder( + builder: (context, BoxConstraints box) { + double maxWidth = box.maxWidth; + double crossCount = len < 3 ? 2 : 3; + double height = maxWidth / + crossCount * + (len % crossCount == 0 + ? len ~/ crossCount + : len ~/ crossCount + 1) + + 6; + return Container( + padding: const EdgeInsets.only(top: 6), + height: height, + child: GridView( + padding: EdgeInsets.zero, + physics: const NeverScrollableScrollPhysics(), + // 子Item排列规则 + gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( + //横轴元素个数 + crossAxisCount: crossCount.toInt(), + //纵轴间距 + mainAxisSpacing: 4.0, + //横轴间距 + crossAxisSpacing: 4.0, + //子组件宽高长度比例 + // childAspectRatio: 1, + ), + //GridView中使用的子Widegt + children: list, + ), + ); + }, + ), ), - ), - ); + ); + } } // spanChilds.add(TextSpan(text: matchMember)); return TextSpan(children: spanChilds); @@ -554,24 +621,25 @@ InlineSpan buildContent(BuildContext context, content) { class UpTag extends StatelessWidget { String? tagText; UpTag({super.key, this.tagText = 'UP'}); - @override Widget build(BuildContext context) { + Color primary = Theme.of(context).colorScheme.primary; return Container( - width: tagText == 'UP' ? 28 : 38, - height: tagText == 'UP' ? 17 : 19, + width: tagText == 'UP' ? 25 : 32, + height: tagText == 'UP' ? 16 : 18, decoration: BoxDecoration( borderRadius: BorderRadius.circular(3), - // color: Theme.of(context).colorScheme.primary, - border: Border.all(color: Theme.of(context).colorScheme.primary)), + color: tagText == 'UP' ? primary : null, + border: Border.all(color: primary)), margin: const EdgeInsets.only(right: 4), - // padding: const EdgeInsets.symmetric(vertical: 0.5, horizontal: 4), child: Center( child: Text( tagText!, style: TextStyle( - fontSize: Theme.of(context).textTheme.labelSmall!.fontSize, - color: Theme.of(context).colorScheme.primary, + fontSize: 10, + color: tagText == 'UP' + ? Theme.of(context).colorScheme.onPrimary + : primary, ), ), ), diff --git a/pubspec.lock b/pubspec.lock index 9f021f27..36af3acf 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -272,6 +272,14 @@ packages: description: flutter source: sdk version: "0.0.0" + font_awesome_flutter: + dependency: "direct main" + description: + name: font_awesome_flutter + sha256: "959ef4add147753f990b4a7c6cccb746d5792dbdc81b1cde99e62e7edb31b206" + url: "https://pub.dev" + source: hosted + version: "10.4.0" get: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 7b78fe6a..8251e578 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -65,6 +65,7 @@ dependencies: flutter_inappwebview: 5.4.4 extended_nested_scroll_view: ^6.0.0 + font_awesome_flutter: ^10.4.0 dev_dependencies: flutter_test: @@ -106,6 +107,9 @@ flutter: - family: fansCard fonts: - asset: assets/fonts/fansCard.ttf + - family: ArchivoNarrow + fonts: + - asset: assets/fonts/ArchivoNarrow-BoldItalic.ttf # For details regarding fonts from package dependencies,