diff --git a/lib/common/widgets/save_panel.dart b/lib/common/widgets/save_panel.dart index d9922395..73ec4941 100644 --- a/lib/common/widgets/save_panel.dart +++ b/lib/common/widgets/save_panel.dart @@ -56,6 +56,8 @@ class SavePanel extends StatefulWidget { class _SavePanelState extends State { final boundaryKey = GlobalKey(); + bool showBottom = true; + // item dynamic get _item => widget.item; late String viewType = '查看'; @@ -222,7 +224,7 @@ class _SavePanelState extends State { ByteData? byteData = await image.toByteData(format: ImageByteFormat.png); Uint8List pngBytes = byteData!.buffer.asUint8List(); String picName = - "plpl_reply_${DateTime.now().toString().replaceAll(RegExp(r'[- :]'), '').split('.').first}"; + "plpl_reply_${DateTime.now().toString().substring(0, 19).replaceAll(RegExp(r'[- :]'), '')}"; if (isShare) { Get.back(); SmartDialog.dismiss(); @@ -263,9 +265,7 @@ class _SavePanelState extends State { Widget build(BuildContext context) { return GestureDetector( behavior: HitTestBehavior.opaque, - onTap: () { - Get.back(); - }, + onTap: Get.back, child: Stack( clipBehavior: Clip.none, alignment: Alignment.center, @@ -297,6 +297,7 @@ class _SavePanelState extends State { replyLevel: '', needDivider: false, upMid: widget.upMid, + isSave: true, ), ) else if (_item is DynamicItemModel) @@ -348,10 +349,10 @@ class _SavePanelState extends State { if (pubdate != null) ...[ const Spacer(), Text( - Utils.dateFormat( - pubdate, - formatType: 'detail', - ), + DateTime.fromMillisecondsSinceEpoch( + pubdate! * 1000) + .toString() + .substring(0, 19), style: TextStyle( color: Theme.of(context) .colorScheme @@ -365,96 +366,103 @@ class _SavePanelState extends State { ], ), ), - Stack( - clipBehavior: Clip.none, - children: [ - if (uri.isNotEmpty) - Align( - alignment: Alignment.centerRight, - child: Row( - children: [ - Expanded( - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: - CrossAxisAlignment.end, + showBottom + ? Stack( + clipBehavior: Clip.none, + children: [ + if (uri.isNotEmpty) + Align( + alignment: Alignment.centerRight, + child: Row( children: [ - if (uname?.isNotEmpty == true) ...[ - Text( - '@$uname', - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: Theme.of(context) - .colorScheme - .primary, - ), - ), - const SizedBox(height: 4), - ], - Text( - '识别二维码,$viewType$itemType', - textAlign: TextAlign.end, - style: TextStyle( - color: Theme.of(context) - .colorScheme - .onSurfaceVariant, + Expanded( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: + CrossAxisAlignment.end, + children: [ + if (uname?.isNotEmpty == + true) ...[ + Text( + '@$uname', + maxLines: 1, + overflow: + TextOverflow.ellipsis, + style: TextStyle( + color: Theme.of(context) + .colorScheme + .primary, + ), + ), + const SizedBox(height: 4), + ], + Text( + '识别二维码,$viewType$itemType', + textAlign: TextAlign.end, + style: TextStyle( + color: Theme.of(context) + .colorScheme + .onSurfaceVariant, + ), + ), + const SizedBox(height: 4), + Text( + DateTime.now() + .toString() + .split('.') + .first, + textAlign: TextAlign.end, + style: TextStyle( + fontSize: 13, + color: Theme.of(context) + .colorScheme + .outline, + ), + ), + ], ), ), - const SizedBox(height: 4), - Text( - DateTime.now() - .toString() - .split('.') - .first, - textAlign: TextAlign.end, - style: TextStyle( - fontSize: 13, - color: Theme.of(context) - .colorScheme - .outline, + Container( + width: 100, + height: 100, + padding: const EdgeInsets.all(12), + child: Container( + color: Get.isDarkMode + ? Colors.white + : Theme.of(context) + .colorScheme + .surface, + padding: + const EdgeInsets.all(3), + child: PrettyQrView.data( + data: uri, + decoration: + const PrettyQrDecoration( + shape: + PrettyQrRoundedSymbol( + borderRadius: + BorderRadius.zero, + ), + ), + ), ), ), ], ), ), - Container( + Align( + alignment: Alignment.centerLeft, + child: Image.asset( + 'assets/images/logo/logo_2.png', width: 100, - height: 100, - padding: const EdgeInsets.all(12), - child: Container( - color: Get.isDarkMode - ? Colors.white - : Theme.of(context) - .colorScheme - .surface, - padding: const EdgeInsets.all(3), - child: PrettyQrView.data( - data: uri, - decoration: - const PrettyQrDecoration( - shape: PrettyQrRoundedSymbol( - borderRadius: BorderRadius.zero, - ), - ), - ), - ), + color: Theme.of(context) + .colorScheme + .onSurfaceVariant, ), - ], - ), - ), - Align( - alignment: Alignment.centerLeft, - child: Image.asset( - 'assets/images/logo/logo_2.png', - width: 100, - color: Theme.of(context) - .colorScheme - .onSurfaceVariant, - ), - ), - ], - ), + ), + ], + ) + : const SizedBox(height: 12), ], ), ), @@ -468,7 +476,7 @@ class _SavePanelState extends State { right: 0, bottom: 0, child: Container( - decoration: BoxDecoration( + decoration: const BoxDecoration( gradient: LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, @@ -494,6 +502,17 @@ class _SavePanelState extends State { iconColor: Theme.of(context).colorScheme.onSurfaceVariant, ), const SizedBox(width: 40), + iconButton( + size: 42, + tooltip: showBottom ? '隐藏' : '显示', + context: context, + icon: showBottom + ? Icons.visibility_off + : Icons.visibility, + onPressed: () => setState(() { + showBottom = !showBottom; + })), + const SizedBox(width: 40), iconButton( size: 42, tooltip: '分享', @@ -507,7 +526,7 @@ class _SavePanelState extends State { tooltip: '保存', context: context, icon: Icons.save_alt, - onPressed: () => _onSaveOrSharePic(), + onPressed: _onSaveOrSharePic, ), ], ), diff --git a/lib/pages/dynamics/widgets/author_panel.dart b/lib/pages/dynamics/widgets/author_panel.dart index da2a0cb2..66a3bb78 100644 --- a/lib/pages/dynamics/widgets/author_panel.dart +++ b/lib/pages/dynamics/widgets/author_panel.dart @@ -24,6 +24,7 @@ class AuthorPanel extends StatelessWidget { final Function? addBannedList; final String? source; final Function? onRemove; + final bool isSave; const AuthorPanel({ super.key, @@ -31,6 +32,7 @@ class AuthorPanel extends StatelessWidget { this.addBannedList, this.source, this.onRemove, + this.isSave = false, }); Widget _buildAvatar(double size) => NetworkImgLayer( @@ -43,7 +45,12 @@ class AuthorPanel extends StatelessWidget { @override Widget build(BuildContext context) { String? pubTime = item.modules.moduleAuthor.pubTs != null - ? Utils.dateFormat(item.modules.moduleAuthor.pubTs) + ? isSave + ? DateTime.fromMillisecondsSinceEpoch( + item.modules.moduleAuthor.pubTs * 1000) + .toString() + .substring(0, 19) + : Utils.dateFormat(item.modules.moduleAuthor.pubTs) : item.modules.moduleAuthor.pubTime; return Stack( alignment: Alignment.center, @@ -210,30 +217,32 @@ class AuthorPanel extends StatelessWidget { ); } - Widget _moreWidget(context) => SizedBox( - width: 32, - height: 32, - child: IconButton( - tooltip: '更多', - style: ButtonStyle( - padding: WidgetStateProperty.all(EdgeInsets.zero), + Widget _moreWidget(BuildContext context) => isSave + ? const SizedBox.shrink() + : SizedBox( + width: 32, + height: 32, + child: IconButton( + tooltip: '更多', + style: ButtonStyle( + padding: WidgetStateProperty.all(EdgeInsets.zero), + ), + onPressed: () { + showModalBottomSheet( + context: context, + useSafeArea: true, + isScrollControlled: true, + constraints: BoxConstraints( + maxWidth: min(640, min(Get.width, Get.height)), + ), + builder: (context) { + return morePanel(context); + }, + ); + }, + icon: const Icon(Icons.more_vert_outlined, size: 18), ), - onPressed: () { - showModalBottomSheet( - context: context, - useSafeArea: true, - isScrollControlled: true, - constraints: BoxConstraints( - maxWidth: min(640, min(Get.width, Get.height)), - ), - builder: (context) { - return morePanel(context); - }, - ); - }, - icon: const Icon(Icons.more_vert_outlined, size: 18), - ), - ); + ); Widget morePanel(context) { return Padding( diff --git a/lib/pages/dynamics/widgets/content_panel.dart b/lib/pages/dynamics/widgets/content_panel.dart index b2aff21e..f47e8762 100644 --- a/lib/pages/dynamics/widgets/content_panel.dart +++ b/lib/pages/dynamics/widgets/content_panel.dart @@ -4,7 +4,7 @@ import 'package:flutter/material.dart'; import 'rich_node_panel.dart'; -Widget content(isSave, context, item, source, callback) { +Widget content(bool isSave, BuildContext context, item, source, callback) { InlineSpan picsNodes() { return WidgetSpan( child: LayoutBuilder( @@ -55,7 +55,7 @@ Widget content(isSave, context, item, source, callback) { child: Text.rich( /// fix 默认20px高度 style: TextStyle( - fontSize: source == 'detail' && isSave != true ? 16 : 15, + fontSize: source == 'detail' && !isSave ? 16 : 15, ), richNodes, maxLines: source == 'detail' ? null : 6, diff --git a/lib/pages/dynamics/widgets/dynamic_panel.dart b/lib/pages/dynamics/widgets/dynamic_panel.dart index 7641fc5a..5139eea9 100644 --- a/lib/pages/dynamics/widgets/dynamic_panel.dart +++ b/lib/pages/dynamics/widgets/dynamic_panel.dart @@ -14,14 +14,14 @@ class DynamicPanel extends StatelessWidget { final String? source; final Function? onRemove; final Function(List, int)? callback; - final bool? isSave; + final bool isSave; const DynamicPanel({ required this.item, this.source, this.onRemove, this.callback, - this.isSave, + this.isSave = false, super.key, }); @@ -31,7 +31,7 @@ class DynamicPanel extends StatelessWidget { // padding: source == 'detail' // ? const EdgeInsets.only(bottom: 12) // : EdgeInsets.zero, - decoration: isSave == true || + decoration: isSave || (source == 'detail' && Get.context!.orientation == Orientation.landscape) ? null @@ -133,6 +133,7 @@ class DynamicPanel extends StatelessWidget { item: item, source: source, onRemove: onRemove, + isSave: isSave, ), ), if (item!.modules!.moduleDynamic!.desc != null || @@ -141,7 +142,7 @@ class DynamicPanel extends StatelessWidget { forWard(isSave, item, context, source, callback), const SizedBox(height: 2), if (source == null) ActionPanel(item: item), - if (source == 'detail' && isSave != true) const SizedBox(height: 12), + if (source == 'detail' && !isSave) const SizedBox(height: 12), ], ); } diff --git a/lib/pages/dynamics/widgets/forward_panel.dart b/lib/pages/dynamics/widgets/forward_panel.dart index 70db5270..830b0359 100644 --- a/lib/pages/dynamics/widgets/forward_panel.dart +++ b/lib/pages/dynamics/widgets/forward_panel.dart @@ -68,7 +68,7 @@ Widget _blockedItem(BuildContext context, item, source) { ); } -Widget forWard(isSave, item, BuildContext context, source, callback, +Widget forWard(bool isSave, item, BuildContext context, source, callback, {floor = 1}) { switch (item.type) { // 图文 @@ -125,12 +125,12 @@ Widget forWard(isSave, item, BuildContext context, source, callback, Text.rich( richNodes, // 被转发状态(floor=2) 隐藏 - maxLines: isSave == true + maxLines: isSave ? null : source == 'detail' && floor != 2 ? null : 4, - overflow: isSave == true + overflow: isSave ? null : source == 'detail' && floor != 2 ? null @@ -307,12 +307,12 @@ Widget forWard(isSave, item, BuildContext context, source, callback, Text.rich( richNodes, // 被转发状态(floor=2) 隐藏 - maxLines: isSave == true + maxLines: isSave ? null : source == 'detail' && floor != 2 ? null : 4, - overflow: isSave == true + overflow: isSave ? null : source == 'detail' && floor != 2 ? null diff --git a/lib/pages/video/detail/reply/widgets/reply_item_grpc.dart b/lib/pages/video/detail/reply/widgets/reply_item_grpc.dart index 79722874..a7a74a46 100644 --- a/lib/pages/video/detail/reply/widgets/reply_item_grpc.dart +++ b/lib/pages/video/detail/reply/widgets/reply_item_grpc.dart @@ -43,6 +43,7 @@ class ReplyItemGrpc extends StatelessWidget { this.callback, this.onCheckReply, this.onToggleTop, + this.isSave = false, }); final ReplyInfo replyItem; final String replyLevel; @@ -58,6 +59,7 @@ class ReplyItemGrpc extends StatelessWidget { final Function(List, int)? callback; final ValueChanged? onCheckReply; final Function(bool isUpTop, int rpid)? onToggleTop; + final bool isSave; @override Widget build(BuildContext context) { @@ -320,7 +322,12 @@ class ReplyItemGrpc extends StatelessWidget { mainAxisSize: MainAxisSize.min, children: [ Text( - Utils.dateFormat(replyItem.ctime.toInt()), + isSave + ? DateTime.fromMillisecondsSinceEpoch( + replyItem.ctime.toInt() * 1000) + .toString() + .substring(0, 19) + : Utils.dateFormat(replyItem.ctime.toInt()), style: TextStyle( fontSize: Theme.of(context).textTheme.labelSmall!.fontSize, @@ -554,15 +561,12 @@ class ReplyItemGrpc extends StatelessWidget { }, child: Container( width: double.infinity, - padding: EdgeInsets.fromLTRB( - 8, - i == 0 && (extraRow || replyItem.replies.length > 1) - ? 8 - : 4, - 8, - i == 0 && (extraRow || replyItem.replies.length > 1) - ? 4 - : 6, + padding: EdgeInsets.symmetric( + horizontal: 8, + vertical: + i == 0 && (extraRow || replyItem.replies.length > 1) + ? 8 + : 4, ), child: Semantics( label: