🐛 Optimize content render
This commit is contained in:
		| @@ -348,7 +348,7 @@ class _AccountProfilePageState extends State<AccountProfilePage> { | |||||||
|                       detail: _userinfo, |                       detail: _userinfo, | ||||||
|                       profile: _userinfo!.profile, |                       profile: _userinfo!.profile, | ||||||
|                       extraWidgets: [ |                       extraWidgets: [ | ||||||
|                         if (_dailySignRecords.isNotEmpty) |                         if (_dailySignRecords.length > 1) | ||||||
|                           Card( |                           Card( | ||||||
|                             child: SizedBox( |                             child: SizedBox( | ||||||
|                               height: 180, |                               height: 180, | ||||||
|   | |||||||
| @@ -198,7 +198,7 @@ class _CallScreenState extends State<CallScreen> with TickerProviderStateMixin { | |||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|     final ChatCallProvider ctrl = Get.find(); |     final ChatCallProvider ctrl = Get.find(); | ||||||
|  |  | ||||||
|     return RootContainer( |     return ResponsiveRootContainer( | ||||||
|       child: Scaffold( |       child: Scaffold( | ||||||
|         appBar: widget.hideAppBar |         appBar: widget.hideAppBar | ||||||
|             ? null |             ? null | ||||||
|   | |||||||
| @@ -229,7 +229,10 @@ class _AttachmentEditorPopupState extends State<AttachmentEditorPopup> { | |||||||
|         .listMetadata(widget.initialAttachments ?? List.empty()) |         .listMetadata(widget.initialAttachments ?? List.empty()) | ||||||
|         .then((result) { |         .then((result) { | ||||||
|       setState(() { |       setState(() { | ||||||
|         _attachments = List.from(result, growable: true); |         _attachments = List.from( | ||||||
|  |           result.where((x) => x != null), | ||||||
|  |           growable: true, | ||||||
|  |         ); | ||||||
|         _isBusy = false; |         _isBusy = false; | ||||||
|         _isFirstTimeBusy = false; |         _isFirstTimeBusy = false; | ||||||
|       }); |       }); | ||||||
|   | |||||||
| @@ -265,8 +265,15 @@ class _AttachmentFullScreenState extends State<AttachmentFullScreen> { | |||||||
|                               'ISO${widget.item.metadata?['exif']?['ISO']}', |                               'ISO${widget.item.metadata?['exif']?['ISO']}', | ||||||
|                               style: metaTextStyle, |                               style: metaTextStyle, | ||||||
|                             ).paddingOnly(right: 2), |                             ).paddingOnly(right: 2), | ||||||
|                           if (widget.item.metadata?['exif']?['Megapixels'] != |                           if (widget.item.metadata?['exif']?['Aperture'] != | ||||||
|                               null) |                               null) | ||||||
|  |                             Text( | ||||||
|  |                               'f/${widget.item.metadata?['exif']?['Aperture']}', | ||||||
|  |                               style: metaTextStyle, | ||||||
|  |                             ).paddingOnly(right: 2), | ||||||
|  |                           if (widget.item.metadata?['exif']?['Megapixels'] != | ||||||
|  |                                   null && | ||||||
|  |                               widget.item.metadata?['exif']?['Model'] != null) | ||||||
|                             Text( |                             Text( | ||||||
|                               '${widget.item.metadata?['exif']?['Megapixels']}MP', |                               '${widget.item.metadata?['exif']?['Megapixels']}MP', | ||||||
|                               style: metaTextStyle, |                               style: metaTextStyle, | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
|  | import 'dart:developer'; | ||||||
| import 'dart:ui'; | import 'dart:ui'; | ||||||
|  |  | ||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
| import 'package:flutter_markdown/flutter_markdown.dart'; | import 'package:flutter_markdown/flutter_markdown.dart'; | ||||||
| import 'package:gap/gap.dart'; |  | ||||||
| import 'package:get/get.dart'; | import 'package:get/get.dart'; | ||||||
| import 'package:google_fonts/google_fonts.dart'; | import 'package:google_fonts/google_fonts.dart'; | ||||||
| import 'package:markdown/markdown.dart' as markdown; | import 'package:markdown/markdown.dart' as markdown; | ||||||
| @@ -15,7 +15,7 @@ import 'package:url_launcher/url_launcher_string.dart'; | |||||||
|  |  | ||||||
| import 'account/account_profile_popup.dart'; | import 'account/account_profile_popup.dart'; | ||||||
|  |  | ||||||
| class MarkdownTextContent extends StatelessWidget { | class MarkdownTextContent extends StatefulWidget { | ||||||
|   final String content; |   final String content; | ||||||
|   final String parentId; |   final String parentId; | ||||||
|   final bool isSelectable; |   final bool isSelectable; | ||||||
| @@ -31,33 +31,51 @@ class MarkdownTextContent extends StatelessWidget { | |||||||
|     this.isAutoWarp = false, |     this.isAutoWarp = false, | ||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   Widget _buildContent(BuildContext context) { |   @override | ||||||
|  |   State<MarkdownTextContent> createState() => _MarkdownTextContentState(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class _MarkdownTextContentState extends State<MarkdownTextContent> { | ||||||
|  |   final List<int> _stickerSizes = []; | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   initState() { | ||||||
|  |     super.initState(); | ||||||
|     final stickerRegex = RegExp(r':([-\w]+):'); |     final stickerRegex = RegExp(r':([-\w]+):'); | ||||||
|  |  | ||||||
|     // Split the content into paragraphs |     // Split the content into paragraphs | ||||||
|     final paragraphs = content.split(RegExp(r'\n\s*\n')); |     final paragraphs = widget.content.split(RegExp(r'\n\s*\n')); | ||||||
|  |  | ||||||
|     // Iterate over each paragraph to process stickers individually |     // Iterate over each paragraph to process stickers individually | ||||||
|     List<Widget> contentWidgets = []; |  | ||||||
|     for (var idx = 0; idx < paragraphs.length; idx++) { |     for (var idx = 0; idx < paragraphs.length; idx++) { | ||||||
|       // Getting paragraph |       // Getting paragraph | ||||||
|       var paragraph = paragraphs[idx]; |       var paragraph = paragraphs[idx]; | ||||||
|  |  | ||||||
|       // Matching stickers |       // Matching stickers | ||||||
|       final stickerMatch = stickerRegex.allMatches(paragraph); |       final stickerMatch = stickerRegex.allMatches(paragraph); | ||||||
|       final isOnlySticker = |       if (stickerMatch.length > 3) { | ||||||
|           paragraph.replaceAll(stickerRegex, '').trim().isEmpty; |         _stickerSizes.addAll(List.filled(stickerMatch.length, 16)); | ||||||
|  |       } else if (stickerMatch.length > 1) { | ||||||
|  |         _stickerSizes.addAll(List.filled(stickerMatch.length, 32)); | ||||||
|  |       } else { | ||||||
|  |         _stickerSizes.addAll(List.filled(stickerMatch.length, 128)); | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|       contentWidgets.add( |   Widget _buildContent(BuildContext context) { | ||||||
|         Markdown( |     var stickerIdx = 0; | ||||||
|  |  | ||||||
|  |     return Markdown( | ||||||
|       shrinkWrap: true, |       shrinkWrap: true, | ||||||
|       physics: const NeverScrollableScrollPhysics(), |       physics: const NeverScrollableScrollPhysics(), | ||||||
|           data: paragraph, |       data: widget.content, | ||||||
|       padding: EdgeInsets.zero, |       padding: EdgeInsets.zero, | ||||||
|       styleSheet: MarkdownStyleSheet.fromTheme( |       styleSheet: MarkdownStyleSheet.fromTheme( | ||||||
|         Theme.of(context), |         Theme.of(context), | ||||||
|       ).copyWith( |       ).copyWith( | ||||||
|               textScaler: TextScaler.linear(isLargeText ? 1.1 : 1), |           textScaler: TextScaler.linear(widget.isLargeText ? 1.1 : 1), | ||||||
|           blockquote: TextStyle( |           blockquote: TextStyle( | ||||||
|             color: Theme.of(context).colorScheme.onSurfaceVariant, |             color: Theme.of(context).colorScheme.onSurfaceVariant, | ||||||
|           ), |           ), | ||||||
| @@ -92,7 +110,7 @@ class MarkdownTextContent extends StatelessWidget { | |||||||
|           ...markdown.ExtensionSet.gitHubFlavored.blockSyntaxes, |           ...markdown.ExtensionSet.gitHubFlavored.blockSyntaxes, | ||||||
|         ], |         ], | ||||||
|         <markdown.InlineSyntax>[ |         <markdown.InlineSyntax>[ | ||||||
|               if (isAutoWarp) markdown.LineBreakSyntax(), |           if (widget.isAutoWarp) markdown.LineBreakSyntax(), | ||||||
|           _UserNameCardInlineSyntax(), |           _UserNameCardInlineSyntax(), | ||||||
|           _CustomEmoteInlineSyntax(), |           _CustomEmoteInlineSyntax(), | ||||||
|           markdown.AutolinkSyntax(), |           markdown.AutolinkSyntax(), | ||||||
| @@ -134,21 +152,18 @@ class MarkdownTextContent extends StatelessWidget { | |||||||
|           final segments = url.replaceFirst('solink://', '').split('/'); |           final segments = url.replaceFirst('solink://', '').split('/'); | ||||||
|           switch (segments[0]) { |           switch (segments[0]) { | ||||||
|             case 'stickers': |             case 'stickers': | ||||||
|                   double radius = 8; |               double radius = 4; | ||||||
|               final StickerProvider sticker = Get.find(); |               final StickerProvider sticker = Get.find(); | ||||||
|  |  | ||||||
|               // Adjust sticker size based on the sticker count in this paragraph |               // Adjust sticker size based on the sticker count in this paragraph | ||||||
|                   if (stickerMatch.length <= 1 && isOnlySticker) { |               width = | ||||||
|                     width = 128; |                   _stickerSizes.elementAtOrNull(stickerIdx)?.toDouble() ?? 16; | ||||||
|                     height = 128; |               height = | ||||||
|                   } else if (stickerMatch.length <= 3 && isOnlySticker) { |                   _stickerSizes.elementAtOrNull(stickerIdx)?.toDouble() ?? 16; | ||||||
|                     width = 32; |               if (width > 16) { | ||||||
|                     height = 32; |                 radius = 8; | ||||||
|                   } else { |  | ||||||
|                     radius = 4; |  | ||||||
|                     width = 16; |  | ||||||
|                     height = 16; |  | ||||||
|               } |               } | ||||||
|  |               stickerIdx++; | ||||||
|               fit = BoxFit.contain; |               fit = BoxFit.contain; | ||||||
|               return ClipRRect( |               return ClipRRect( | ||||||
|                 borderRadius: BorderRadius.all(Radius.circular(radius)), |                 borderRadius: BorderRadius.all(Radius.circular(radius)), | ||||||
| @@ -160,8 +175,7 @@ class MarkdownTextContent extends StatelessWidget { | |||||||
|                     future: sticker.getStickerByAlias(segments[1]), |                     future: sticker.getStickerByAlias(segments[1]), | ||||||
|                     builder: (context, snapshot) { |                     builder: (context, snapshot) { | ||||||
|                       if (!snapshot.hasData) { |                       if (!snapshot.hasData) { | ||||||
|                             return const Center( |                         return const Center(child: CircularProgressIndicator()); | ||||||
|                                 child: CircularProgressIndicator()); |  | ||||||
|                       } |                       } | ||||||
|                       return AutoCacheImage( |                       return AutoCacheImage( | ||||||
|                         snapshot.data!.imageUrl, |                         snapshot.data!.imageUrl, | ||||||
| @@ -182,7 +196,7 @@ class MarkdownTextContent extends StatelessWidget { | |||||||
|                   borderRadius: radius, |                   borderRadius: radius, | ||||||
|                   child: AttachmentSelfContainedEntry( |                   child: AttachmentSelfContainedEntry( | ||||||
|                     isDense: true, |                     isDense: true, | ||||||
|                         parentId: parentId, |                     parentId: widget.parentId, | ||||||
|                     rid: segments[1], |                     rid: segments[1], | ||||||
|                   ), |                   ), | ||||||
|                 ), |                 ), | ||||||
| @@ -196,25 +210,12 @@ class MarkdownTextContent extends StatelessWidget { | |||||||
|           fit: fit, |           fit: fit, | ||||||
|         ); |         ); | ||||||
|       }, |       }, | ||||||
|         ), |  | ||||||
|       ); |  | ||||||
|  |  | ||||||
|       if (idx < paragraphs.length - 1) { |  | ||||||
|         contentWidgets.add(isAutoWarp ? const Gap(4) : const Gap(8)); |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     // Return the list of widgets for the paragraphs |  | ||||||
|     return Column( |  | ||||||
|       mainAxisSize: MainAxisSize.min, |  | ||||||
|       crossAxisAlignment: CrossAxisAlignment.start, |  | ||||||
|       children: contentWidgets, |  | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|     if (isSelectable) { |     if (widget.isSelectable) { | ||||||
|       return SelectionArea(child: _buildContent(context)); |       return SelectionArea(child: _buildContent(context)); | ||||||
|     } |     } | ||||||
|     return _buildContent(context); |     return _buildContent(context); | ||||||
|   | |||||||
| @@ -526,7 +526,7 @@ class _PostHeaderDividerWidget extends StatelessWidget { | |||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|     if (item.body['description'] != null || item.body['title'] != null) { |     if (item.body['description'] != null || item.body['title'] != null) { | ||||||
|       return const Gap(8); |       return const SizedBox(height: 8); | ||||||
|     } |     } | ||||||
|     return const SizedBox.shrink(); |     return const SizedBox.shrink(); | ||||||
|   } |   } | ||||||
|   | |||||||
| @@ -2214,10 +2214,10 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: url_launcher_windows |       name: url_launcher_windows | ||||||
|       sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185" |       sha256: "44cf3aabcedde30f2dba119a9dea3b0f2672fbe6fa96e85536251d678216b3c4" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "3.1.2" |     version: "3.1.3" | ||||||
|   uuid: |   uuid: | ||||||
|     dependency: "direct main" |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
| @@ -2350,10 +2350,10 @@ packages: | |||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|       name: win32 |       name: win32 | ||||||
|       sha256: e5c39a90447e7c81cfec14b041cdbd0d0916bd9ebbc7fe02ab69568be703b9bd |       sha256: "2294c64768987ea280b43a3d8357d42d5679f3e2b5b69b602be45b2abbd165b0" | ||||||
|       url: "https://pub.dev" |       url: "https://pub.dev" | ||||||
|     source: hosted |     source: hosted | ||||||
|     version: "5.6.0" |     version: "5.6.1" | ||||||
|   win32_registry: |   win32_registry: | ||||||
|     dependency: transitive |     dependency: transitive | ||||||
|     description: |     description: | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ name: solian | |||||||
| description: "The Solar Network App" | description: "The Solar Network App" | ||||||
| publish_to: "none" | publish_to: "none" | ||||||
|  |  | ||||||
| version: 1.4.0+16 | version: 1.4.0+17 | ||||||
|  |  | ||||||
| environment: | environment: | ||||||
|   sdk: ">=3.3.4 <4.0.0" |   sdk: ">=3.3.4 <4.0.0" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user