✨ Post alias
This commit is contained in:
		| @@ -17,6 +17,7 @@ import 'package:shared_preferences/shared_preferences.dart'; | |||||||
| class PostEditorController extends GetxController { | class PostEditorController extends GetxController { | ||||||
|   late final SharedPreferences _prefs; |   late final SharedPreferences _prefs; | ||||||
|  |  | ||||||
|  |   final aliasController = TextEditingController(); | ||||||
|   final titleController = TextEditingController(); |   final titleController = TextEditingController(); | ||||||
|   final descriptionController = TextEditingController(); |   final descriptionController = TextEditingController(); | ||||||
|   final contentController = TextEditingController(); |   final contentController = TextEditingController(); | ||||||
| @@ -197,16 +198,23 @@ class PostEditorController extends GetxController { | |||||||
|  |  | ||||||
|     type = value.type; |     type = value.type; | ||||||
|     editTo.value = value; |     editTo.value = value; | ||||||
|  |     realmZone.value = value.realm; | ||||||
|     isDraft.value = value.isDraft ?? false; |     isDraft.value = value.isDraft ?? false; | ||||||
|  |     aliasController.text = value.alias ?? ''; | ||||||
|     titleController.text = value.body['title'] ?? ''; |     titleController.text = value.body['title'] ?? ''; | ||||||
|     descriptionController.text = value.body['description'] ?? ''; |     descriptionController.text = value.body['description'] ?? ''; | ||||||
|     contentController.text = value.body['content'] ?? ''; |     contentController.text = value.body['content'] ?? ''; | ||||||
|     publishedAt.value = value.publishedAt; |     publishedAt.value = value.publishedAt; | ||||||
|     publishedUntil.value = value.publishedUntil; |     publishedUntil.value = value.publishedUntil; | ||||||
|     tags.value = |     tags.value = List.from( | ||||||
|         value.body['tags']?.map((x) => x['alias']).toList() ?? List.empty(); |       value.body['tags']?.map((x) => x['alias']).toList() ?? List.empty(), | ||||||
|  |       growable: true, | ||||||
|  |     ); | ||||||
|     tags.refresh(); |     tags.refresh(); | ||||||
|     attachments.value = value.body['attachments']?.cast<int>() ?? List.empty(); |     attachments.value = List.from( | ||||||
|  |       value.body['attachments'] ?? List.empty(), | ||||||
|  |       growable: true, | ||||||
|  |     ); | ||||||
|     attachments.refresh(); |     attachments.refresh(); | ||||||
|     thumbnail.value = value.body['thumbnail']; |     thumbnail.value = value.body['thumbnail']; | ||||||
|  |  | ||||||
| @@ -256,6 +264,7 @@ class PostEditorController extends GetxController { | |||||||
|  |  | ||||||
|   Map<String, dynamic> get payload { |   Map<String, dynamic> get payload { | ||||||
|     return { |     return { | ||||||
|  |       'alias': aliasController.text, | ||||||
|       'title': title, |       'title': title, | ||||||
|       'description': description, |       'description': description, | ||||||
|       'content': contentController.text, |       'content': contentController.text, | ||||||
| @@ -277,20 +286,33 @@ class PostEditorController extends GetxController { | |||||||
|  |  | ||||||
|   set payload(Map<String, dynamic> value) { |   set payload(Map<String, dynamic> value) { | ||||||
|     type = value['type']; |     type = value['type']; | ||||||
|     tags.value = value['tags'].map((x) => x['alias']).toList().cast<String>(); |     tags.value = List.from( | ||||||
|  |       value['tags'].map((x) => x['alias']).toList(), | ||||||
|  |       growable: true, | ||||||
|  |     ); | ||||||
|  |     aliasController.text = value['alias'] ?? ''; | ||||||
|     titleController.text = value['title'] ?? ''; |     titleController.text = value['title'] ?? ''; | ||||||
|     descriptionController.text = value['description'] ?? ''; |     descriptionController.text = value['description'] ?? ''; | ||||||
|     contentController.text = value['content'] ?? ''; |     contentController.text = value['content'] ?? ''; | ||||||
|     attachments.value = value['attachments'].cast<int>() ?? List.empty(); |     attachments.value = List.from( | ||||||
|  |       value['attachments'] ?? List.empty(), | ||||||
|  |       growable: true, | ||||||
|  |     ); | ||||||
|     attachments.refresh(); |     attachments.refresh(); | ||||||
|     thumbnail.value = value['thumbnail']; |     thumbnail.value = value['thumbnail']; | ||||||
|     visibility.value = value['visibility']; |     visibility.value = value['visibility']; | ||||||
|     isDraft.value = value['is_draft']; |     isDraft.value = value['is_draft']; | ||||||
|     if (value['visible_users'] != null) { |     if (value['visible_users'] != null) { | ||||||
|       visibleUsers.value = value['visible_users'].cast<int>(); |       visibleUsers.value = List.from( | ||||||
|  |         value['visible_users'], | ||||||
|  |         growable: true, | ||||||
|  |       ); | ||||||
|     } |     } | ||||||
|     if (value['invisible_users'] != null) { |     if (value['invisible_users'] != null) { | ||||||
|       invisibleUsers.value = value['invisible_users'].cast<int>(); |       invisibleUsers.value = List.from( | ||||||
|  |         value['invisible_users'], | ||||||
|  |         growable: true, | ||||||
|  |       ); | ||||||
|     } |     } | ||||||
|     if (value['published_at'] != null) { |     if (value['published_at'] != null) { | ||||||
|       publishedAt.value = DateTime.parse(value['published_at']).toLocal(); |       publishedAt.value = DateTime.parse(value['published_at']).toLocal(); | ||||||
| @@ -319,6 +341,7 @@ class PostEditorController extends GetxController { | |||||||
|  |  | ||||||
|   bool get isNotEmpty { |   bool get isNotEmpty { | ||||||
|     return [ |     return [ | ||||||
|  |       aliasController.text.isNotEmpty, | ||||||
|       titleController.text.isNotEmpty, |       titleController.text.isNotEmpty, | ||||||
|       descriptionController.text.isNotEmpty, |       descriptionController.text.isNotEmpty, | ||||||
|       contentController.text.isNotEmpty, |       contentController.text.isNotEmpty, | ||||||
|   | |||||||
| @@ -8,6 +8,8 @@ class Post { | |||||||
|   DateTime updatedAt; |   DateTime updatedAt; | ||||||
|   DateTime? editedAt; |   DateTime? editedAt; | ||||||
|   DateTime? deletedAt; |   DateTime? deletedAt; | ||||||
|  |   String? alias; | ||||||
|  |   String? areaAlias; | ||||||
|   dynamic body; |   dynamic body; | ||||||
|   List<Tag>? tags; |   List<Tag>? tags; | ||||||
|   List<Category>? categories; |   List<Category>? categories; | ||||||
| @@ -33,6 +35,8 @@ class Post { | |||||||
|     required this.updatedAt, |     required this.updatedAt, | ||||||
|     required this.editedAt, |     required this.editedAt, | ||||||
|     required this.deletedAt, |     required this.deletedAt, | ||||||
|  |     required this.alias, | ||||||
|  |     required this.areaAlias, | ||||||
|     required this.type, |     required this.type, | ||||||
|     required this.body, |     required this.body, | ||||||
|     required this.tags, |     required this.tags, | ||||||
| @@ -60,6 +64,8 @@ class Post { | |||||||
|         deletedAt: json['deleted_at'] != null |         deletedAt: json['deleted_at'] != null | ||||||
|             ? DateTime.parse(json['deleted_at']) |             ? DateTime.parse(json['deleted_at']) | ||||||
|             : null, |             : null, | ||||||
|  |         alias: json['alias'], | ||||||
|  |         areaAlias: json['area_alias'], | ||||||
|         type: json['type'], |         type: json['type'], | ||||||
|         body: json['body'], |         body: json['body'], | ||||||
|         tags: json['tags']?.map((x) => Tag.fromJson(x)).toList().cast<Tag>(), |         tags: json['tags']?.map((x) => Tag.fromJson(x)).toList().cast<Tag>(), | ||||||
| @@ -101,6 +107,8 @@ class Post { | |||||||
|         'updated_at': updatedAt.toIso8601String(), |         'updated_at': updatedAt.toIso8601String(), | ||||||
|         'edited_at': editedAt?.toIso8601String(), |         'edited_at': editedAt?.toIso8601String(), | ||||||
|         'deleted_at': deletedAt?.toIso8601String(), |         'deleted_at': deletedAt?.toIso8601String(), | ||||||
|  |         'alias': alias, | ||||||
|  |         'area_alias': areaAlias, | ||||||
|         'type': type, |         'type': type, | ||||||
|         'body': body, |         'body': body, | ||||||
|         'tags': tags, |         'tags': tags, | ||||||
|   | |||||||
| @@ -176,11 +176,20 @@ class _PostPublishScreenState extends State<PostPublishScreen> { | |||||||
|           children: [ |           children: [ | ||||||
|             ListTile( |             ListTile( | ||||||
|               tileColor: Theme.of(context).colorScheme.surfaceContainerLow, |               tileColor: Theme.of(context).colorScheme.surfaceContainerLow, | ||||||
|               title: Text( |               title: Row( | ||||||
|  |                 children: [ | ||||||
|  |                   Text( | ||||||
|                     _editorController.title ?? 'title'.tr, |                     _editorController.title ?? 'title'.tr, | ||||||
|                     maxLines: 1, |                     maxLines: 1, | ||||||
|                     overflow: TextOverflow.ellipsis, |                     overflow: TextOverflow.ellipsis, | ||||||
|                   ), |                   ), | ||||||
|  |                   const SizedBox(width: 6), | ||||||
|  |                   if (_editorController.aliasController.text.isNotEmpty) | ||||||
|  |                     Badge( | ||||||
|  |                       label: Text('#${_editorController.aliasController.text}'), | ||||||
|  |                     ), | ||||||
|  |                 ], | ||||||
|  |               ), | ||||||
|               subtitle: Text( |               subtitle: Text( | ||||||
|                 _editorController.description ?? 'description'.tr, |                 _editorController.description ?? 'description'.tr, | ||||||
|                 maxLines: 2, |                 maxLines: 2, | ||||||
| @@ -255,6 +264,7 @@ class _PostPublishScreenState extends State<PostPublishScreen> { | |||||||
|                   ), |                   ), | ||||||
|                 ], |                 ], | ||||||
|               ), |               ), | ||||||
|  |             if (_isBusy) const LinearProgressIndicator().animate().scaleX(), | ||||||
|             Expanded( |             Expanded( | ||||||
|               child: Row( |               child: Row( | ||||||
|                 crossAxisAlignment: CrossAxisAlignment.start, |                 crossAxisAlignment: CrossAxisAlignment.start, | ||||||
| @@ -265,10 +275,6 @@ class _PostPublishScreenState extends State<PostPublishScreen> { | |||||||
|                         Expanded( |                         Expanded( | ||||||
|                           child: ListView( |                           child: ListView( | ||||||
|                             children: [ |                             children: [ | ||||||
|                               if (_isBusy) |  | ||||||
|                                 const LinearProgressIndicator() |  | ||||||
|                                     .animate() |  | ||||||
|                                     .scaleX(), |  | ||||||
|                               Container( |                               Container( | ||||||
|                                 padding: const EdgeInsets.symmetric( |                                 padding: const EdgeInsets.symmetric( | ||||||
|                                   horizontal: 16, |                                   horizontal: 16, | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ const i18nEnglish = { | |||||||
|   'more': 'More', |   'more': 'More', | ||||||
|   'share': 'Share', |   'share': 'Share', | ||||||
|   'shareNoUri': 'Share text content', |   'shareNoUri': 'Share text content', | ||||||
|  |   'alias': 'Alias', | ||||||
|   'feed': 'Feed', |   'feed': 'Feed', | ||||||
|   'unlink': 'Unlink', |   'unlink': 'Unlink', | ||||||
|   'feedSearch': 'Search Feed', |   'feedSearch': 'Search Feed', | ||||||
|   | |||||||
| @@ -21,6 +21,7 @@ const i18nSimplifiedChinese = { | |||||||
|   'more': '更多', |   'more': '更多', | ||||||
|   'share': '分享', |   'share': '分享', | ||||||
|   'shareNoUri': '分享文字内容', |   'shareNoUri': '分享文字内容', | ||||||
|  |   'alias': '别名', | ||||||
|   'feed': '资讯', |   'feed': '资讯', | ||||||
|   'unlink': '移除链接', |   'unlink': '移除链接', | ||||||
|   'feedSearch': '搜索资讯', |   'feedSearch': '搜索资讯', | ||||||
|   | |||||||
| @@ -238,8 +238,8 @@ class _AttachmentItemVideoState extends State<_AttachmentItemVideo> { | |||||||
|  |  | ||||||
|   bool _showContent = false; |   bool _showContent = false; | ||||||
|  |  | ||||||
|   void _startLoad() { |   Future<void> _startLoad() async { | ||||||
|     _player.open( |     await _player.open( | ||||||
|       Media(ServiceFinder.buildUrl('files', '/attachments/${widget.item.id}')), |       Media(ServiceFinder.buildUrl('files', '/attachments/${widget.item.id}')), | ||||||
|       play: false, |       play: false, | ||||||
|     ); |     ); | ||||||
| @@ -249,7 +249,9 @@ class _AttachmentItemVideoState extends State<_AttachmentItemVideo> { | |||||||
|   @override |   @override | ||||||
|   void initState() { |   void initState() { | ||||||
|     super.initState(); |     super.initState(); | ||||||
|     _showContent = widget.autoload; |     if (widget.autoload) { | ||||||
|  |       _startLoad(); | ||||||
|  |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   | |||||||
| @@ -57,10 +57,12 @@ class _AttachmentListState extends State<AttachmentList> { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     attach.listMetadata(widget.attachmentsId).then((result) { |     attach.listMetadata(widget.attachmentsId).then((result) { | ||||||
|  |       if (mounted) { | ||||||
|         setState(() { |         setState(() { | ||||||
|           _attachmentsMeta = result; |           _attachmentsMeta = result; | ||||||
|           _isLoading = false; |           _isLoading = false; | ||||||
|         }); |         }); | ||||||
|  |       } | ||||||
|       _calculateAspectRatio(); |       _calculateAspectRatio(); | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| @@ -111,6 +113,7 @@ class _AttachmentListState extends State<AttachmentList> { | |||||||
|       showBadge: _attachmentsMeta.length > 1 && !widget.isGrid, |       showBadge: _attachmentsMeta.length > 1 && !widget.isGrid, | ||||||
|       showBorder: widget.attachmentsId.length > 1, |       showBorder: widget.attachmentsId.length > 1, | ||||||
|       showMature: _showMature, |       showMature: _showMature, | ||||||
|  |       autoload: widget.autoload, | ||||||
|       onReveal: (value) { |       onReveal: (value) { | ||||||
|         setState(() => _showMature = value); |         setState(() => _showMature = value); | ||||||
|       }, |       }, | ||||||
| @@ -138,8 +141,9 @@ class _AttachmentListState extends State<AttachmentList> { | |||||||
|       ); |       ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     final isNotPureImage = _attachmentsMeta |     final isNotPureImage = _attachmentsMeta.any( | ||||||
|         .any((x) => x?.mimetype.split('/').firstOrNull != 'image'); |       (x) => x?.mimetype.split('/').firstOrNull != 'image', | ||||||
|  |     ); | ||||||
|     if (widget.isGrid && (widget.isForceGrid || !isNotPureImage)) { |     if (widget.isGrid && (widget.isForceGrid || !isNotPureImage)) { | ||||||
|       const radius = BorderRadius.all(Radius.circular(8)); |       const radius = BorderRadius.all(Radius.circular(8)); | ||||||
|       return GridView.builder( |       return GridView.builder( | ||||||
| @@ -157,8 +161,10 @@ class _AttachmentListState extends State<AttachmentList> { | |||||||
|           final element = _attachmentsMeta[idx]; |           final element = _attachmentsMeta[idx]; | ||||||
|           return Container( |           return Container( | ||||||
|             decoration: BoxDecoration( |             decoration: BoxDecoration( | ||||||
|               border: |               border: Border.all( | ||||||
|                   Border.all(color: Theme.of(context).dividerColor, width: 1), |                 color: Theme.of(context).dividerColor, | ||||||
|  |                 width: 1, | ||||||
|  |               ), | ||||||
|               borderRadius: radius, |               borderRadius: radius, | ||||||
|             ), |             ), | ||||||
|             child: ClipRRect( |             child: ClipRRect( | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ class PostEditorCategoriesDialog extends StatelessWidget { | |||||||
|             initialTags: controller.tags, |             initialTags: controller.tags, | ||||||
|             hintText: 'postTagsPlaceholder'.tr, |             hintText: 'postTagsPlaceholder'.tr, | ||||||
|             onUpdate: (value) { |             onUpdate: (value) { | ||||||
|               controller.tags.value = value; |               controller.tags.value = List.from(value, growable: true); | ||||||
|               controller.tags.refresh(); |               controller.tags.refresh(); | ||||||
|             }, |             }, | ||||||
|           ), |           ), | ||||||
|   | |||||||
| @@ -14,12 +14,25 @@ class PostEditorOverviewDialog extends StatelessWidget { | |||||||
|       content: Column( |       content: Column( | ||||||
|         mainAxisSize: MainAxisSize.min, |         mainAxisSize: MainAxisSize.min, | ||||||
|         children: [ |         children: [ | ||||||
|  |           TextField( | ||||||
|  |             autofocus: true, | ||||||
|  |             autocorrect: true, | ||||||
|  |             controller: controller.aliasController, | ||||||
|  |             decoration: InputDecoration( | ||||||
|  |               isDense: true, | ||||||
|  |               border: const OutlineInputBorder(), | ||||||
|  |               hintText: 'alias'.tr, | ||||||
|  |             ), | ||||||
|  |             onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(), | ||||||
|  |           ), | ||||||
|  |           const SizedBox(height: 16), | ||||||
|           TextField( |           TextField( | ||||||
|             autofocus: true, |             autofocus: true, | ||||||
|             autocorrect: true, |             autocorrect: true, | ||||||
|             controller: controller.titleController, |             controller: controller.titleController, | ||||||
|             decoration: InputDecoration( |             decoration: InputDecoration( | ||||||
|               border: const UnderlineInputBorder(), |               isDense: true, | ||||||
|  |               border: const OutlineInputBorder(), | ||||||
|               hintText: 'title'.tr, |               hintText: 'title'.tr, | ||||||
|             ), |             ), | ||||||
|             onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(), |             onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(), | ||||||
| @@ -33,7 +46,8 @@ class PostEditorOverviewDialog extends StatelessWidget { | |||||||
|             keyboardType: TextInputType.multiline, |             keyboardType: TextInputType.multiline, | ||||||
|             controller: controller.descriptionController, |             controller: controller.descriptionController, | ||||||
|             decoration: InputDecoration( |             decoration: InputDecoration( | ||||||
|               border: const UnderlineInputBorder(), |               isDense: true, | ||||||
|  |               border: const OutlineInputBorder(), | ||||||
|               hintText: 'description'.tr, |               hintText: 'description'.tr, | ||||||
|             ), |             ), | ||||||
|             onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(), |             onTapOutside: (_) => FocusManager.instance.primaryFocus?.unfocus(), | ||||||
|   | |||||||
| @@ -42,10 +42,16 @@ class _PostActionState extends State<PostAction> { | |||||||
|  |  | ||||||
|   Future<void> _doShare({bool noUri = false}) async { |   Future<void> _doShare({bool noUri = false}) async { | ||||||
|     ShareResult result; |     ShareResult result; | ||||||
|  |     String id; | ||||||
|     final box = context.findRenderObject() as RenderBox?; |     final box = context.findRenderObject() as RenderBox?; | ||||||
|  |     if (widget.item.alias?.isNotEmpty ?? false) { | ||||||
|  |       id = '${widget.item.areaAlias}:${widget.item.alias}'; | ||||||
|  |     } else { | ||||||
|  |       id = '${widget.item.id}'; | ||||||
|  |     } | ||||||
|     if ((PlatformInfo.isAndroid || PlatformInfo.isIOS) && !noUri) { |     if ((PlatformInfo.isAndroid || PlatformInfo.isIOS) && !noUri) { | ||||||
|       result = await Share.shareUri( |       result = await Share.shareUri( | ||||||
|         Uri.parse('https://solsynth.dev/posts/${widget.item.id}'), |         Uri.parse('https://solsynth.dev/posts/$id'), | ||||||
|         sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size, |         sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size, | ||||||
|       ); |       ); | ||||||
|     } else { |     } else { | ||||||
| @@ -59,7 +65,7 @@ class _PostActionState extends State<PostAction> { | |||||||
|           'username': widget.item.author.nick, |           'username': widget.item.author.nick, | ||||||
|           'content': |           'content': | ||||||
|               '${extraContent.join('\n')}${isExtraNotEmpty ? '\n\n' : ''}${widget.item.body['content'] ?? 'no content'}', |               '${extraContent.join('\n')}${isExtraNotEmpty ? '\n\n' : ''}${widget.item.body['content'] ?? 'no content'}', | ||||||
|           'link': 'https://solsynth.dev/posts/${widget.item.id}', |           'link': 'https://solsynth.dev/posts/$id', | ||||||
|         }), |         }), | ||||||
|         subject: 'postShareSubject'.trParams({ |         subject: 'postShareSubject'.trParams({ | ||||||
|           'username': widget.item.author.nick, |           'username': widget.item.author.nick, | ||||||
| @@ -96,10 +102,28 @@ class _PostActionState extends State<PostAction> { | |||||||
|                 'postActionList'.tr, |                 'postActionList'.tr, | ||||||
|                 style: Theme.of(context).textTheme.headlineSmall, |                 style: Theme.of(context).textTheme.headlineSmall, | ||||||
|               ), |               ), | ||||||
|  |               Row( | ||||||
|  |                 children: [ | ||||||
|                   Text( |                   Text( | ||||||
|                     '#${widget.item.id.toString().padLeft(8, '0')}', |                     '#${widget.item.id.toString().padLeft(8, '0')}', | ||||||
|                     style: Theme.of(context).textTheme.bodySmall, |                     style: Theme.of(context).textTheme.bodySmall, | ||||||
|                   ), |                   ), | ||||||
|  |                   if (widget.item.alias?.isNotEmpty ?? false) | ||||||
|  |                     Text( | ||||||
|  |                       '·', | ||||||
|  |                       style: Theme.of(context).textTheme.bodySmall, | ||||||
|  |                     ).paddingSymmetric(horizontal: 6), | ||||||
|  |                   if (widget.item.alias?.isNotEmpty ?? false) | ||||||
|  |                     Expanded( | ||||||
|  |                       child: Text( | ||||||
|  |                         '${widget.item.areaAlias}:${widget.item.alias}', | ||||||
|  |                         style: Theme.of(context).textTheme.bodySmall, | ||||||
|  |                         maxLines: 1, | ||||||
|  |                         overflow: TextOverflow.ellipsis, | ||||||
|  |                       ), | ||||||
|  |                     ), | ||||||
|  |                 ], | ||||||
|  |               ), | ||||||
|             ], |             ], | ||||||
|           ).paddingOnly(left: 24, right: 24, top: 32, bottom: 16), |           ).paddingOnly(left: 24, right: 24, top: 32, bottom: 16), | ||||||
|           if (_isBusy) const LinearProgressIndicator().animate().scaleX(), |           if (_isBusy) const LinearProgressIndicator().animate().scaleX(), | ||||||
|   | |||||||
| @@ -78,25 +78,19 @@ class _PostItemState extends State<PostItem> { | |||||||
|  |  | ||||||
|   Widget _buildThumbnail() { |   Widget _buildThumbnail() { | ||||||
|     if (widget.item.body['thumbnail'] == null) return const SizedBox(); |     if (widget.item.body['thumbnail'] == null) return const SizedBox(); | ||||||
|     const radius = BorderRadius.all(Radius.circular(8)); |     final border = BorderSide( | ||||||
|     return AspectRatio( |  | ||||||
|       aspectRatio: 16 / 9, |  | ||||||
|       child: Container( |  | ||||||
|         decoration: BoxDecoration( |  | ||||||
|           border: Border.all( |  | ||||||
|       color: Theme.of(context).dividerColor, |       color: Theme.of(context).dividerColor, | ||||||
|       width: 0.3, |       width: 0.3, | ||||||
|           ), |     ); | ||||||
|           borderRadius: radius, |     return Container( | ||||||
|         ), |       decoration: BoxDecoration(border: Border(top: border, bottom: border)), | ||||||
|         child: ClipRRect( |       child: AspectRatio( | ||||||
|           borderRadius: radius, |         aspectRatio: 16 / 9, | ||||||
|         child: AttachmentSelfContainedEntry( |         child: AttachmentSelfContainedEntry( | ||||||
|           id: widget.item.body['thumbnail'], |           id: widget.item.body['thumbnail'], | ||||||
|           parentId: 'p${item.id}-thumbnail', |           parentId: 'p${item.id}-thumbnail', | ||||||
|         ), |         ), | ||||||
|       ), |       ), | ||||||
|       ), |  | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -307,7 +301,7 @@ class _PostItemState extends State<PostItem> { | |||||||
|       return Column( |       return Column( | ||||||
|         crossAxisAlignment: CrossAxisAlignment.start, |         crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|         children: [ |         children: [ | ||||||
|           _buildThumbnail().paddingSymmetric(horizontal: 12, vertical: 4), |           _buildThumbnail(), | ||||||
|           _buildHeader().paddingSymmetric(horizontal: 12), |           _buildHeader().paddingSymmetric(horizontal: 12), | ||||||
|           _buildHeaderDivider().paddingSymmetric(horizontal: 12), |           _buildHeaderDivider().paddingSymmetric(horizontal: 12), | ||||||
|           Stack( |           Stack( | ||||||
| @@ -381,7 +375,7 @@ class _PostItemState extends State<PostItem> { | |||||||
|       closedBuilder: (_, openContainer) => Column( |       closedBuilder: (_, openContainer) => Column( | ||||||
|         crossAxisAlignment: CrossAxisAlignment.start, |         crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|         children: [ |         children: [ | ||||||
|           _buildThumbnail().paddingSymmetric(horizontal: 12, vertical: 4), |           _buildThumbnail().paddingOnly(bottom: 4), | ||||||
|           Row( |           Row( | ||||||
|             crossAxisAlignment: CrossAxisAlignment.start, |             crossAxisAlignment: CrossAxisAlignment.start, | ||||||
|             children: [ |             children: [ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user