From 1715e89ccf8bd0b9bd50ebdce2ce139aaafd0b27 Mon Sep 17 00:00:00 2001 From: trustratch Date: Tue, 11 Jun 2024 20:34:42 +0200 Subject: [PATCH 1/5] feat: add custom post in feed widdget --- lib/core/widget/feed_widget.dart | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/lib/core/widget/feed_widget.dart b/lib/core/widget/feed_widget.dart index 4abb212..6f635a2 100644 --- a/lib/core/widget/feed_widget.dart +++ b/lib/core/widget/feed_widget.dart @@ -482,6 +482,15 @@ class FeedContentWidget extends StatelessWidget { ); } + if (amityPostData is CustomData) { + final data = amityPostData as CustomData; + return Container( + // color: Colors.green, + child: + Text('Custom post content -->>>> ${data.rawData}'), + ); + } + return Container( color: Colors.red, child: Text('>>>>> $amityPostData <<<<<<'), From 827784a862c2557286848672752a4c8492c7f201 Mon Sep 17 00:00:00 2001 From: trustratch Date: Tue, 11 Jun 2024 20:48:11 +0200 Subject: [PATCH 2/5] feat: add custom post creation page --- lib/core/route/app_route.dart | 3 + lib/core/route/app_router.dart | 8 + .../create_custom_post_screen.dart | 140 ++++++++++++++++++ .../screen/dashboard/dashboard_screen.dart | 7 + 4 files changed, 158 insertions(+) create mode 100644 lib/presentation/screen/create_custom_post/create_custom_post_screen.dart diff --git a/lib/core/route/app_route.dart b/lib/core/route/app_route.dart index 707956b..2b352a6 100644 --- a/lib/core/route/app_route.dart +++ b/lib/core/route/app_route.dart @@ -103,6 +103,9 @@ class AppRoute { static const createPollPost = 'createPollPost'; static const createPollPostRoute = 'createPollPost'; + static const createCustomPost = 'createCustomPost'; + static const createCustomPostRoute = 'createCustomPost'; + static const chat = 'chat'; static const chatRoute = 'chatRoute/:channelId'; diff --git a/lib/core/route/app_router.dart b/lib/core/route/app_router.dart index ebb5279..b3fe5c0 100644 --- a/lib/core/route/app_router.dart +++ b/lib/core/route/app_router.dart @@ -23,6 +23,7 @@ import 'package:flutter_social_sample_app/presentation/screen/community_notifica import 'package:flutter_social_sample_app/presentation/screen/community_pending_post/community_pending_post_screen.dart'; import 'package:flutter_social_sample_app/presentation/screen/community_profile/community_profile_screen.dart'; import 'package:flutter_social_sample_app/presentation/screen/community_update/community_update_screen.dart'; +import 'package:flutter_social_sample_app/presentation/screen/create_custom_post/create_custom_post_screen.dart'; import 'package:flutter_social_sample_app/presentation/screen/create_livestream_post/create_livestream_post.dart'; import 'package:flutter_social_sample_app/presentation/screen/create_poll_post/create_poll_post_screen.dart'; import 'package:flutter_social_sample_app/presentation/screen/create_post/create_post_screen.dart'; @@ -317,6 +318,13 @@ class AppRouter { path: AppRoute.createPollPostRoute, builder: (context, state) => const CreatePollPostScreen(), ), + + GoRoute( + name: AppRoute.createCustomPost, + path: AppRoute.createCustomPostRoute, + builder: (context, state) => const CreateCustomPostScreen(), + ), + GoRoute( name: AppRoute.chat, path: AppRoute.chatRoute, diff --git a/lib/presentation/screen/create_custom_post/create_custom_post_screen.dart b/lib/presentation/screen/create_custom_post/create_custom_post_screen.dart new file mode 100644 index 0000000..4cfc0f7 --- /dev/null +++ b/lib/presentation/screen/create_custom_post/create_custom_post_screen.dart @@ -0,0 +1,140 @@ +import 'package:amity_sdk/amity_sdk.dart'; +import 'package:flutter/material.dart'; + +class CreateCustomPostScreen extends StatefulWidget { + const CreateCustomPostScreen({Key? key, this.userId}) : super(key: key); + final String? userId; + + @override + State createState() => _CreateCustomPostScreenState(); +} + +class _CreateCustomPostScreenState extends State { + final _targetUserTextEditController = TextEditingController(); + final _keyTextController = TextEditingController(); + final _valueTextController = TextEditingController(); + + @override + Widget build(BuildContext context) { + final themeData = Theme.of(context); + + if (widget.userId != null) { + _targetUserTextEditController.text = widget.userId!; + } + + return Scaffold( + appBar: AppBar( + title: const Text('Create Custom Post'), + actions: [ + LoadingButton( + onPressed: () async { + try { + FocusManager.instance.primaryFocus?.unfocus(); + final target = _targetUserTextEditController.text.trim(); + final key = _keyTextController.text.trim(); + final value = _valueTextController.text.trim(); + + if (key.isEmpty || value.isEmpty) { + CommonSnackbar.showNagativeSnackbar( + context, 'Error', 'Key and value cannot be empty'); + return; + } + + final customData = {key: value}; + + final amityPost = await AmitySocialClient.newPostRepository() + .createPost() + .targetMe() + .custom('amity.custom', customData) + .post(); + + CommonSnackbar.showPositiveSnackbar( + context, 'Success', 'Custom Post Created Successfully'); + } catch (error, stackTrace) { + print(stackTrace.toString()); + CommonSnackbar.showNagativeSnackbar( + context, 'Error', error.toString()); + } + }, + text: 'POST', + ), + ], + ), + body: SingleChildScrollView( + child: Container( + padding: const EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextFormField( + controller: _targetUserTextEditController, + decoration: InputDecoration( + label: Text('Target User'), + ), + ), + const SizedBox(height: 12), + Text( + 'Custom Data', + style: themeData.textTheme.titleMedium!.copyWith( + fontWeight: FontWeight.bold, + ), + ), + TextFormField( + controller: _keyTextController, + decoration: const InputDecoration( + hintText: 'Key', + ), + ), + const SizedBox(height: 12), + TextFormField( + controller: _valueTextController, + decoration: const InputDecoration( + hintText: 'Value', + ), + ), + ], + ), + ), + ), + ); + } +} + +class LoadingButton extends StatelessWidget { + final Future Function() onPressed; + final String text; + + const LoadingButton({ + Key? key, + required this.onPressed, + required this.text, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return TextButton( + onPressed: () => onPressed(), + child: Text(text), + ); + } +} + +class CommonSnackbar { + static void showPositiveSnackbar( + BuildContext context, String title, String message) { + final snackBar = SnackBar( + content: Text('$title: $message'), + backgroundColor: Colors.green, + ); + ScaffoldMessenger.of(context).showSnackBar(snackBar); + } + + static void showNagativeSnackbar( + BuildContext context, String title, String message) { + final snackBar = SnackBar( + content: Text('$title: $message'), + backgroundColor: Colors.red, + ); + ScaffoldMessenger.of(context).showSnackBar(snackBar); + } +} diff --git a/lib/presentation/screen/dashboard/dashboard_screen.dart b/lib/presentation/screen/dashboard/dashboard_screen.dart index 400a6d6..7fad791 100644 --- a/lib/presentation/screen/dashboard/dashboard_screen.dart +++ b/lib/presentation/screen/dashboard/dashboard_screen.dart @@ -129,6 +129,13 @@ class _DashboardScreenState extends State { child: const Text('Create Poll Post'), ), const SizedBox(height: 20), + TextButton( + onPressed: () { + GoRouter.of(context).goNamed(AppRoute.createCustomPost); + }, + child: const Text('Create Custom Post'), + ), + const SizedBox(height: 20), TextButton( onPressed: () async { FirebaseMessaging messaging = FirebaseMessaging.instance; From d0693362320c4f76b93d774da7cb6eb021010c78 Mon Sep 17 00:00:00 2001 From: trustratch Date: Tue, 11 Jun 2024 21:30:27 +0200 Subject: [PATCH 3/5] feat: add update custom post screen --- lib/core/widget/feed_widget.dart | 31 +++-- .../update_custom_post_screen.dart | 128 ++++++++++++++++++ 2 files changed, 150 insertions(+), 9 deletions(-) create mode 100644 lib/presentation/screen/update_post/update_custom_post_screen.dart diff --git a/lib/core/widget/feed_widget.dart b/lib/core/widget/feed_widget.dart index 6f635a2..d392532 100644 --- a/lib/core/widget/feed_widget.dart +++ b/lib/core/widget/feed_widget.dart @@ -4,12 +4,12 @@ import 'package:flutter/material.dart'; import 'package:flutter_social_sample_app/core/route/app_route.dart'; import 'package:flutter_social_sample_app/core/utils/extension/date_extension.dart'; import 'package:flutter_social_sample_app/core/widget/add_comment_widget.dart'; -import 'package:flutter_social_sample_app/core/widget/common_snackbar.dart'; import 'package:flutter_social_sample_app/core/widget/dynamic_text_highlighting.dart'; import 'package:flutter_social_sample_app/core/widget/poll_widget.dart'; import 'package:flutter_social_sample_app/core/widget/reaction_action_widget.dart'; import 'package:flutter_social_sample_app/core/widget/shadow_container_widget.dart'; import 'package:flutter_social_sample_app/core/widget/user_profile_info_row_widget.dart'; +import 'package:flutter_social_sample_app/presentation/screen/update_post/update_custom_post_screen.dart'; import 'package:flutter_social_sample_app/presentation/screen/update_post/update_post_screen.dart'; import 'package:flutter_social_sample_app/presentation/screen/video_player/full_screen_video_player.dart'; import 'package:go_router/go_router.dart'; @@ -94,15 +94,28 @@ class FeedWidget extends StatelessWidget { ), onSelected: (index) { if (index == 1) { - Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => UpdatePostScreen( - amityPost: value, - communityId: communityId, - isPublic: isPublic, + if (value.data is CustomData) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => + UpdateCustomPostScreen( + amityPost: value), ), - ), - ); + ); + + } else { + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => + UpdatePostScreen( + amityPost: value, + communityId: communityId, + isPublic: isPublic, + ), + ), + ); + } } if (index == 2) { value.delete(); diff --git a/lib/presentation/screen/update_post/update_custom_post_screen.dart b/lib/presentation/screen/update_post/update_custom_post_screen.dart new file mode 100644 index 0000000..3f3fdbd --- /dev/null +++ b/lib/presentation/screen/update_post/update_custom_post_screen.dart @@ -0,0 +1,128 @@ +import 'package:amity_sdk/amity_sdk.dart'; +import 'package:flutter/material.dart'; + +class UpdateCustomPostScreen extends StatefulWidget { + const UpdateCustomPostScreen({Key? key, required this.amityPost}) + : super(key: key); + final AmityPost amityPost; + + @override + State createState() => _UpdateCustomPostScreenState(); +} + +class _UpdateCustomPostScreenState extends State { + final _keyTextController = TextEditingController(); + final _valueTextController = TextEditingController(); + + @override + Widget build(BuildContext context) { + final themeData = Theme.of(context); + + return Scaffold( + appBar: AppBar( + title: const Text('Update Custom Post'), + actions: [ + LoadingButton( + onPressed: () async { + try { + FocusManager.instance.primaryFocus?.unfocus(); + final key = _keyTextController.text.trim(); + final value = _valueTextController.text.trim(); + + if (key.isEmpty || value.isEmpty) { + CommonSnackbar.showNagativeSnackbar( + context, 'Error', 'Key and value cannot be empty'); + return; + } + + final customData = {key: value}; + + await widget.amityPost + .edit() + .custom(customData) + .build() + .update(); + + CommonSnackbar.showPositiveSnackbar( + context, 'Success', 'Custom Post Updated Successfully'); + } catch (error, stackTrace) { + print(stackTrace.toString()); + CommonSnackbar.showNagativeSnackbar( + context, 'Error', error.toString()); + } + }, + text: 'UPDATE', + ), + ], + ), + body: SingleChildScrollView( + child: Container( + padding: const EdgeInsets.all(12), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Custom Data', + style: themeData.textTheme.titleMedium!.copyWith( + fontWeight: FontWeight.bold, + ), + ), + TextFormField( + controller: _keyTextController, + decoration: const InputDecoration( + hintText: 'Key', + ), + ), + const SizedBox(height: 12), + TextFormField( + controller: _valueTextController, + decoration: const InputDecoration( + hintText: 'Value', + ), + ), + ], + ), + ), + ), + ); + } +} + +class LoadingButton extends StatelessWidget { + final Future Function() onPressed; + final String text; + + const LoadingButton({ + Key? key, + required this.onPressed, + required this.text, + }) : super(key: key); + + @override + Widget build(BuildContext context) { + return TextButton( + onPressed: () => onPressed(), + child: Text(text), + ); + } +} + +class CommonSnackbar { + static void showPositiveSnackbar( + BuildContext context, String title, String message) { + final snackBar = SnackBar( + content: Text('$title: $message'), + backgroundColor: Colors.green, + ); + ScaffoldMessenger.of(context).showSnackBar(snackBar); + } + + static void showNagativeSnackbar( + BuildContext context, String title, String message) { + final snackBar = SnackBar( + content: Text('$title: $message'), + backgroundColor: Colors.red, + ); + ScaffoldMessenger.of(context).showSnackBar(snackBar); + } +} From 193b193a79084fd1c2fab083b078207f3bf5c529 Mon Sep 17 00:00:00 2001 From: trustratch Date: Tue, 11 Jun 2024 21:47:08 +0200 Subject: [PATCH 4/5] fix: oops, wrong custom post target in sample app --- .../screen/create_custom_post/create_custom_post_screen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/presentation/screen/create_custom_post/create_custom_post_screen.dart b/lib/presentation/screen/create_custom_post/create_custom_post_screen.dart index 4cfc0f7..c75b094 100644 --- a/lib/presentation/screen/create_custom_post/create_custom_post_screen.dart +++ b/lib/presentation/screen/create_custom_post/create_custom_post_screen.dart @@ -44,7 +44,7 @@ class _CreateCustomPostScreenState extends State { final amityPost = await AmitySocialClient.newPostRepository() .createPost() - .targetMe() + .targetUser(target) .custom('amity.custom', customData) .post(); From fc51f4f71b1304025abab2f71df1055b095fc960 Mon Sep 17 00:00:00 2001 From: trustratch Date: Thu, 13 Jun 2024 09:42:18 +0200 Subject: [PATCH 5/5] fix: remove trim from target id text field for custom post --- .../screen/create_custom_post/create_custom_post_screen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/presentation/screen/create_custom_post/create_custom_post_screen.dart b/lib/presentation/screen/create_custom_post/create_custom_post_screen.dart index c75b094..f6d7810 100644 --- a/lib/presentation/screen/create_custom_post/create_custom_post_screen.dart +++ b/lib/presentation/screen/create_custom_post/create_custom_post_screen.dart @@ -30,7 +30,7 @@ class _CreateCustomPostScreenState extends State { onPressed: () async { try { FocusManager.instance.primaryFocus?.unfocus(); - final target = _targetUserTextEditController.text.trim(); + final target = _targetUserTextEditController.text; final key = _keyTextController.text.trim(); final value = _valueTextController.text.trim();