✨ Post details
💄 Somewhere optimization
			
			
This commit is contained in:
		| @@ -3,6 +3,7 @@ import 'package:solaragent/models/feed.dart'; | |||||||
| import 'package:solaragent/screens/account.dart'; | import 'package:solaragent/screens/account.dart'; | ||||||
| import 'package:solaragent/screens/explore.dart'; | import 'package:solaragent/screens/explore.dart'; | ||||||
| import 'package:solaragent/screens/notifications.dart'; | import 'package:solaragent/screens/notifications.dart'; | ||||||
|  | import 'package:solaragent/screens/posts/screen.dart'; | ||||||
| import 'package:solaragent/screens/publish/comment_editor.dart'; | import 'package:solaragent/screens/publish/comment_editor.dart'; | ||||||
| import 'package:solaragent/screens/publish/moment_editor.dart'; | import 'package:solaragent/screens/publish/moment_editor.dart'; | ||||||
|  |  | ||||||
| @@ -20,14 +21,23 @@ final router = GoRouter( | |||||||
|       path: '/account', |       path: '/account', | ||||||
|       builder: (context, state) => const AccountScreen(), |       builder: (context, state) => const AccountScreen(), | ||||||
|     ), |     ), | ||||||
|  |  | ||||||
|     GoRoute( |     GoRoute( | ||||||
|       path: '/post/moments', |       path: '/post/new/moments', | ||||||
|       builder: (context, state) => const MomentEditorScreen(), |       builder: (context, state) => const MomentEditorScreen(), | ||||||
|     ), |     ), | ||||||
|     GoRoute( |     GoRoute( | ||||||
|       path: '/post/comments', |       path: '/post/new/comments', | ||||||
|       builder: (context, state) => |       builder: (context, state) => | ||||||
|           CommentEditorScreen(parent: state.extra as Feed), |           CommentEditorScreen(parent: state.extra as Feed), | ||||||
|     ), |     ), | ||||||
|  |  | ||||||
|  |     GoRoute( | ||||||
|  |       path: '/post/:modelType/:alias', | ||||||
|  |       builder: (context, state) => PostScreen( | ||||||
|  |         modelType: state.pathParameters['modelType'] as String, | ||||||
|  |         alias: state.pathParameters['alias'] as String, | ||||||
|  |       ), | ||||||
|  |     ), | ||||||
|   ], |   ], | ||||||
| ); | ); | ||||||
|   | |||||||
| @@ -83,7 +83,7 @@ class _ExploreScreenState extends State<ExploreScreen> { | |||||||
|               return FloatingActionButton( |               return FloatingActionButton( | ||||||
|                 child: const Icon(Icons.edit), |                 child: const Icon(Icons.edit), | ||||||
|                 onPressed: () { |                 onPressed: () { | ||||||
|                   router.push("/post/moments").then((value) { |                   router.push("/post/new/moments").then((value) { | ||||||
|                     if (value == true) paginationController.refresh(); |                     if (value == true) paginationController.refresh(); | ||||||
|                   }); |                   }); | ||||||
|                 }, |                 }, | ||||||
|   | |||||||
							
								
								
									
										64
									
								
								lib/screens/posts/screen.dart
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								lib/screens/posts/screen.dart
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,64 @@ | |||||||
|  | import 'dart:convert'; | ||||||
|  |  | ||||||
|  | import 'package:flutter/material.dart'; | ||||||
|  | import 'package:http/http.dart'; | ||||||
|  | import 'package:solaragent/models/feed.dart'; | ||||||
|  | import 'package:solaragent/widgets/feed.dart'; | ||||||
|  |  | ||||||
|  | class PostScreen extends StatefulWidget { | ||||||
|  |   final Client client = Client(); | ||||||
|  |  | ||||||
|  |   final String modelType; | ||||||
|  |   final String alias; | ||||||
|  |  | ||||||
|  |   PostScreen({super.key, required this.modelType, required this.alias}); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   State<PostScreen> createState() => _PostScreenState(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class _PostScreenState extends State<PostScreen> { | ||||||
|  |   Future<Feed?> pullPost(BuildContext context) async { | ||||||
|  |     var uri = Uri.parse( | ||||||
|  |       "https://co.solsynth.dev/api/p/${widget.modelType}s/${widget.alias}", | ||||||
|  |     ); | ||||||
|  |     var res = await widget.client.get(uri); | ||||||
|  |     if (res.statusCode != 200) { | ||||||
|  |       var err = utf8.decode(res.bodyBytes); | ||||||
|  |       ScaffoldMessenger.of(context).showSnackBar( | ||||||
|  |         SnackBar(content: Text("Something went wrong... $err")), | ||||||
|  |       ); | ||||||
|  |       return null; | ||||||
|  |     } else { | ||||||
|  |       return Feed.fromJson(jsonDecode(utf8.decode(res.bodyBytes))); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   Widget buildItem(BuildContext context, Feed item) { | ||||||
|  |     return FeedItem( | ||||||
|  |       item: item, | ||||||
|  |       brief: false, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     return Scaffold( | ||||||
|  |       appBar: AppBar(title: const Text("Post")), | ||||||
|  |       body: FutureBuilder( | ||||||
|  |         future: pullPost(context), | ||||||
|  |         builder: (context, snapshot) { | ||||||
|  |           if (snapshot.hasData && snapshot.data != null) { | ||||||
|  |             return SingleChildScrollView( | ||||||
|  |               child: buildItem(context, snapshot.data!), | ||||||
|  |             ); | ||||||
|  |           } else { | ||||||
|  |             return const Center( | ||||||
|  |               child: CircularProgressIndicator(), | ||||||
|  |             ); | ||||||
|  |           } | ||||||
|  |         }, | ||||||
|  |       ), | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
| @@ -132,7 +132,9 @@ class _CommentEditorScreenState extends State<CommentEditorScreen> { | |||||||
|                             child: const Text('OPEN'), |                             child: const Text('OPEN'), | ||||||
|                             onPressed: () async { |                             onPressed: () async { | ||||||
|                               await launchUrl( |                               await launchUrl( | ||||||
|                                   Uri.parse("https://co.solsynth.dev")); |                                 Uri.parse("https://co.solsynth.dev"), | ||||||
|  |                                 mode: LaunchMode.externalApplication, | ||||||
|  |                               ); | ||||||
|                             }, |                             }, | ||||||
|                           ), |                           ), | ||||||
|                           TextButton( |                           TextButton( | ||||||
|   | |||||||
| @@ -154,7 +154,9 @@ class _MomentEditorScreenState extends State<MomentEditorScreen> { | |||||||
|                             child: const Text('OPEN'), |                             child: const Text('OPEN'), | ||||||
|                             onPressed: () async { |                             onPressed: () async { | ||||||
|                               await launchUrl( |                               await launchUrl( | ||||||
|                                   Uri.parse("https://co.solsynth.dev")); |                                 Uri.parse("https://co.solsynth.dev"), | ||||||
|  |                                 mode: LaunchMode.externalApplication, | ||||||
|  |                               ); | ||||||
|                             }, |                             }, | ||||||
|                           ), |                           ), | ||||||
|                           TextButton( |                           TextButton( | ||||||
|   | |||||||
| @@ -1,7 +1,9 @@ | |||||||
| import 'package:flutter/material.dart'; | import 'package:flutter/material.dart'; | ||||||
| import 'package:flutter_carousel_widget/flutter_carousel_widget.dart'; | import 'package:flutter_carousel_widget/flutter_carousel_widget.dart'; | ||||||
| import 'package:flutter_markdown/flutter_markdown.dart'; | import 'package:flutter_markdown/flutter_markdown.dart'; | ||||||
|  | import 'package:go_router/go_router.dart'; | ||||||
| import 'package:solaragent/models/feed.dart'; | import 'package:solaragent/models/feed.dart'; | ||||||
|  | import 'package:solaragent/router.dart'; | ||||||
| import 'package:solaragent/widgets/image.dart'; | import 'package:solaragent/widgets/image.dart'; | ||||||
| import 'package:solaragent/widgets/posts/comments.dart'; | import 'package:solaragent/widgets/posts/comments.dart'; | ||||||
| import 'package:solaragent/widgets/posts/content/article.dart'; | import 'package:solaragent/widgets/posts/content/article.dart'; | ||||||
| @@ -65,19 +67,11 @@ class _FeedItemState extends State<FeedItem> { | |||||||
|       case "article": |       case "article": | ||||||
|         return ArticleContent(item: widget.item, brief: widget.brief ?? false); |         return ArticleContent(item: widget.item, brief: widget.brief ?? false); | ||||||
|       default: |       default: | ||||||
|         return MomentContent(item: widget.item); |         return MomentContent(item: widget.item, brief: widget.brief ?? false); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @override |   Widget buildItem(BuildContext context) { | ||||||
|   void initState() { |  | ||||||
|     reactionCount = widget.item.reactionCount; |  | ||||||
|     reactionList = widget.item.reactionList ?? <String, dynamic>{}; |  | ||||||
|     super.initState(); |  | ||||||
|   } |  | ||||||
|  |  | ||||||
|   @override |  | ||||||
|   Widget build(BuildContext context) { |  | ||||||
|     return Column( |     return Column( | ||||||
|       children: [ |       children: [ | ||||||
|         Container( |         Container( | ||||||
| @@ -161,4 +155,23 @@ class _FeedItemState extends State<FeedItem> { | |||||||
|       ], |       ], | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   void initState() { | ||||||
|  |     reactionCount = widget.item.reactionCount; | ||||||
|  |     reactionList = widget.item.reactionList ?? <String, dynamic>{}; | ||||||
|  |     super.initState(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     return (widget.brief ?? false) | ||||||
|  |         ? GestureDetector( | ||||||
|  |             child: buildItem(context), | ||||||
|  |             onTap: () => router.push( | ||||||
|  |               "/post/${widget.item.modelType}/${widget.item.alias}", | ||||||
|  |             ), | ||||||
|  |           ) | ||||||
|  |         : buildItem(context); | ||||||
|  |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -93,7 +93,7 @@ class _CommentListState extends State<CommentList> { | |||||||
|                       label: const Text("LEAVE COMMENT"), |                       label: const Text("LEAVE COMMENT"), | ||||||
|                       onPressed: () { |                       onPressed: () { | ||||||
|                         router |                         router | ||||||
|                             .push("/post/comments", extra: widget.parent) |                             .push("/post/new/comments", extra: widget.parent) | ||||||
|                             .then((value) { |                             .then((value) { | ||||||
|                           if (value == true) paginationController.refresh(); |                           if (value == true) paginationController.refresh(); | ||||||
|                         }); |                         }); | ||||||
|   | |||||||
| @@ -1,6 +1,9 @@ | |||||||
| 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:solaragent/models/feed.dart'; | import 'package:solaragent/models/feed.dart'; | ||||||
|  | import 'package:markdown/markdown.dart' as md; | ||||||
|  | import 'package:url_launcher/url_launcher.dart'; | ||||||
|  | import 'package:url_launcher/url_launcher_string.dart'; | ||||||
|  |  | ||||||
| class ArticleContent extends StatelessWidget { | class ArticleContent extends StatelessWidget { | ||||||
|   final Feed item; |   final Feed item; | ||||||
| @@ -15,10 +18,30 @@ class ArticleContent extends StatelessWidget { | |||||||
|             title: Text(item.title), |             title: Text(item.title), | ||||||
|             subtitle: Text(item.description), |             subtitle: Text(item.description), | ||||||
|           ) |           ) | ||||||
|         : Markdown( |         : Column( | ||||||
|             data: item.content, |             children: [ | ||||||
|             shrinkWrap: true, |               ListTile( | ||||||
|             physics: const NeverScrollableScrollPhysics(), |                 title: Text(item.title), | ||||||
|  |                 subtitle: Text(item.description), | ||||||
|  |               ), | ||||||
|  |               const Divider(color: Color(0xffefefef)), | ||||||
|  |               Markdown( | ||||||
|  |                   selectable: !brief, | ||||||
|  |                   data: item.content, | ||||||
|  |                   shrinkWrap: true, | ||||||
|  |                   physics: const NeverScrollableScrollPhysics(), | ||||||
|  |                   extensionSet: md.ExtensionSet( | ||||||
|  |                     md.ExtensionSet.gitHubFlavored.blockSyntaxes, | ||||||
|  |                     md.ExtensionSet.gitHubFlavored.inlineSyntaxes, | ||||||
|  |                   ), | ||||||
|  |                   onTapLink: (text, href, title) async { | ||||||
|  |                     if (href == null) return; | ||||||
|  |                     await launchUrlString( | ||||||
|  |                       href, | ||||||
|  |                       mode: LaunchMode.externalApplication, | ||||||
|  |                     ); | ||||||
|  |                   }), | ||||||
|  |             ], | ||||||
|           ); |           ); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -4,12 +4,14 @@ import 'package:solaragent/models/feed.dart'; | |||||||
|  |  | ||||||
| class MomentContent extends StatelessWidget { | class MomentContent extends StatelessWidget { | ||||||
|   final Feed item; |   final Feed item; | ||||||
|  |   final bool brief; | ||||||
|  |  | ||||||
|   const MomentContent({super.key, required this.item}); |   const MomentContent({super.key, required this.brief, required this.item}); | ||||||
|  |  | ||||||
|   @override |   @override | ||||||
|   Widget build(BuildContext context) { |   Widget build(BuildContext context) { | ||||||
|     return Markdown( |     return Markdown( | ||||||
|  |       selectable: !brief, | ||||||
|       data: item.content, |       data: item.content, | ||||||
|       shrinkWrap: true, |       shrinkWrap: true, | ||||||
|       physics: const NeverScrollableScrollPhysics(), |       physics: const NeverScrollableScrollPhysics(), | ||||||
|   | |||||||
| @@ -449,7 +449,7 @@ packages: | |||||||
|     source: hosted |     source: hosted | ||||||
|     version: "1.2.0" |     version: "1.2.0" | ||||||
|   markdown: |   markdown: | ||||||
|     dependency: transitive |     dependency: "direct main" | ||||||
|     description: |     description: | ||||||
|       name: markdown |       name: markdown | ||||||
|       sha256: ef2a1298144e3f985cc736b22e0ccdaf188b5b3970648f2d9dc13efd1d9df051 |       sha256: ef2a1298144e3f985cc736b22e0ccdaf188b5b3970648f2d9dc13efd1d9df051 | ||||||
|   | |||||||
| @@ -50,6 +50,7 @@ dependencies: | |||||||
|   sentry_flutter: ^7.18.0 |   sentry_flutter: ^7.18.0 | ||||||
|   crypto: ^3.0.3 |   crypto: ^3.0.3 | ||||||
|   file_picker: ^8.0.0+1 |   file_picker: ^8.0.0+1 | ||||||
|  |   markdown: ^7.2.2 | ||||||
|  |  | ||||||
| dev_dependencies: | dev_dependencies: | ||||||
|   flutter_test: |   flutter_test: | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user