How to send type file message to community (Not AmityImage) (Flutter)

Currently I am using below code to first upload to amity server to get object amity image type, which then I can create file post in the community by attaching parameter amity image. However currently my user after taking photo in our app they leave the app, thus after uploading image to amity server to get amity image, the code of creating file post might not be executed. Is there a way to post file on community using file type and not amityimage type? As uploading the image to amity server takes a while, is there a faster/ better way?

“Below code uploads file to amity server and receives amity image which then create file post to the community, is there a way to create file post with file type instead of amity image? What would be the best way to handle this situation”

  await PostService().uploadAmityImage(output).then((value) {
          AppLogger.logInfo('Image uploaded to Amity: $value');
          switch (speedDialOption) {
            case SpeedDialOption.fam:
              try {
                PostService()
                    .createFamImagePost(userService.userData.famIds!, value);
              } catch (exception) {
                AppLogger.logError('Error creating fam image post: $exception');
              }
            case SpeedDialOption.private:
              PostService().createMyImagePost(value);
              break;
            case SpeedDialOption.trip:
              try {
                PostService().createCommunityImagePost(
                    value, userService.tripCommunityId!);
              } catch (exception) {
                AppLogger.logError(
                    'Error creating community image post: $exception');
              }

              break;
            default:
          }
        });

“PostService Class”

import 'dart:async';
import 'dart:io';

import 'package:amity_sdk/amity_sdk.dart';
import 'package:app/logger.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';

class PostService extends GetxController {
  //current post collection from feed repository
  late PagingController<AmityPost> _controller;
  late PostLiveCollection postLiveCollection;
  RxList<AmityPost> amityPosts = <AmityPost>[].obs;
  ScrollController? scrollController;

  void observeCommunityPosts(String communityId,
      {ScrollController? externalScrollController}) {
    try {
      AppLogger.logInfo(
          "Observing community posts for communityId: $communityId...");
      scrollController = externalScrollController ?? ScrollController();
      //initialize post live collection
      postLiveCollection = AmitySocialClient.newPostRepository()
          .getPosts()
          .targetCommunity(communityId)
          .getLiveCollection(pageSize: 20);

      //listen to data changes from live collection
      postLiveCollection.getStreamController().stream.listen((event) {
        AppLogger.logInfo("PostService: observeCommunityPosts: $event");
        // update latest results here
        // setState(() {
        amityPosts.clear();
        amityPosts.addAll(event);
        update();
        // });
      });

      //load first page when initiating widget
      postLiveCollection.loadNext();

      //add pagination listener when srolling to top/bottom
      scrollController!.addListener(paginationListener);
    } catch (exception) {
      AppLogger.logError(
          "Error PostService: observeCommunityPosts: $exception");
    }
  }

  void observeFriendPosts(String friendId,
      {ScrollController? externalScrollController}) {
    try {
      AppLogger.logInfo("Observing friend posts for friendId: $friendId...");
      scrollController = externalScrollController ?? ScrollController();
      //initialize post live collection
      postLiveCollection = AmitySocialClient.newPostRepository()
          .getPosts()
          .targetUser(friendId)
          .getLiveCollection(pageSize: 20);

      //listen to data changes from live collection
      postLiveCollection.getStreamController().stream.listen((event) {
        AppLogger.logInfo("PostService: observeCommunityPosts: $event");
        // update latest results here
        // setState(() {
        amityPosts.clear();
        amityPosts.addAll(event);
        update();
        // });
      });

      //load first page when initiating widget
      postLiveCollection.loadNext();

      //add pagination listener when srolling to top/bottom
      scrollController!.addListener(paginationListener);
    } catch (exception) {
      AppLogger.logError(
          "Error PostService: observeCommunityPosts: $exception");
    }
  }

  void paginationListener() {
    //check if
    //#1 scrolling reached top/bottom
    //#2 live collection has next page to load more
    if ((scrollController!.position.pixels ==
            (scrollController!.position.maxScrollExtent)) &&
        postLiveCollection.hasNextPage()) {
      postLiveCollection.loadNext();
    }
  }

  Future<void> createFamImagePost(List<String> famIds, AmityImage image) async {
    for (String famId in famIds) {
      AmitySocialClient.newPostRepository()
          .createPost()
          .targetUser(famId)
          .image([image]) // or targetMe(), targetCommunity(communityId: String)
          .post()
          .then((AmityPost post) => {
                AppLogger.logInfo("Fam Post created: ${post.postId}"),
              })
          .onError((error, stackTrace) => {
                AppLogger.logError("Error creating Fam Post: $error"),
              });
    }
  }

  void createTextPost() {
    AmitySocialClient.newPostRepository()
        .createPost()
        .targetUser(
            'userId') // or targetMe(), targetCommunity(communityId: String)
        .text('Hello from flutter!')
        .post()
        .then((AmityPost post) => {
              //handle result
              //optional: to present the created post in to the current post collection
              //you will need manually put the newly created post in to the collection
              //for example :
              _controller.add(post)
            })
        .onError((error, stackTrace) => {
              //handle error
            });
  }

  Future<AmityImage> uploadAmityImage(File uploadingImage) async {
    Completer<AmityImage> completer = Completer<AmityImage>();

    //first, upload image
    AmityCoreClient.newFileRepository()
        .uploadImage(uploadingImage)
        .stream
        .listen((AmityUploadResult<AmityImage> amityResult) {
      amityResult.when(
        progress: (uploadInfo, cancelToken) {},
        complete: (file) {
          //handle result
          completer.complete(file);
          AppLogger.logInfo('AmityImage uploadImage success: ${file.fileUrl}');
        },
        error: (error) {
          // handle error
          AppLogger.logError('AmityImage uploadImage error: ${error.message}');
          completer.completeError(error);
        },
        cancel: () {
          // handle cancel request
          completer.completeError('Amity Upload canceled');
        },
      );
    });

    return completer.future.timeout(const Duration(seconds: 60), onTimeout: () {
      AppLogger.logError('Amity Image Upload timed out');
      throw TimeoutException('Amity Image Upload timed out');
    });
  }

  Future<AmityPost> createMyImagePost(
    AmityImage uploadedImage,
  ) async {
    try {
      AmityPost post = await AmitySocialClient.newPostRepository()
          .createPost()
          .targetMe()
          .image([uploadedImage])
          .text('')
          .post();
      AppLogger.logInfo('createMyImagePost success: ${post.postId}');
      return post;
    } catch (exception) {
      AppLogger.logError('createMyImagePost error: ${exception.toString()}');
      rethrow;
    }
  }

  Future<AmityPost> createSendImagePostToFriend(
    AmityImage uploadedImage,
    String friendId,
  ) async {
    try {
      AmityPost post = await AmitySocialClient.newPostRepository()
          .createPost()
          .targetUser(
              friendId) // or targetMe(), targetCommunity(communityId: String)
          .image([uploadedImage])
          .text('')
          .post();
      AppLogger.logInfo('createSendImagePostToFriend success: ${post.postId}');
      return post;
    } catch (exception) {
      AppLogger.logError(
          'createSendImagePostToFriend error: ${exception.toString()}');
      rethrow;
    }
  }

  Future<AmityPost> createCommunityImagePost(
    AmityImage uploadedImage,
    String communityId,
  ) async {
    try {
      AmityPost post = await AmitySocialClient.newPostRepository()
          .createPost()
          .targetCommunity(
              communityId) // or targetMe(), targetCommunity(communityId: String)
          .image([uploadedImage])
          .text('')
          .post();
      AppLogger.logInfo('createCommunityImagePost success: ${post.postId}');
      return post;
    } catch (exception) {
      AppLogger.logError(
          'createCommunityImagePost error: ${exception.toString()}');
      rethrow;
    }
  }

  void uploadVideo(File uploadingVideo) {
    //first, upload video
    AmityCoreClient.newFileRepository()
        .uploadVideo(uploadingVideo)
        .stream
        .listen((AmityUploadResult<AmityVideo> amityResult) {
      amityResult.when(
        progress: (uploadInfo, cancelToken) {},
        complete: (file) {
          //handle result

          //then create a video post
          createVideoPost(file);
        },
        error: (error) {
          AppLogger.logError('uploadImage error: ${error.message}');
          // handle error
        },
        cancel: () {
          // handle cancel request
        },
      );
    });
  }

//current post collection from feed repository

  void createVideoPost(AmityVideo uploadedVideo) {
    AmitySocialClient.newPostRepository()
        .createPost()
        .targetUser(
            'userId') // or targetMe(), targetCommunity(communityId: String)
        .video([uploadedVideo])
        .text('Hello from flutter with video!')
        .post()
        .then((AmityPost post) => {
              //handle result
              //optional: to present the created post in to the current post collection
              //you will need manually put the newly created post in to the collection
              //for example :
              _controller.add(post)
            })
        .onError((error, stackTrace) => {
              //handle error
            });
  }

  //TODO GET POST

  void getPost(String postId) {
    AmitySocialClient.newPostRepository()
        .live
        .getPost(postId)
        .listen((AmityPost post) {
      //parent post text is always TextData
      //from this line you can get the post's text data
      //eg 'Hello bob'
      final textContent = post.data as TextData;
      final childrenPosts = post.children;
      //check if the chidren posts exist in the parent post
      if (childrenPosts?.isNotEmpty == true) {
        childrenPosts?.forEach((AmityPost childPost) {
          //check if the current child post is an image post
          if (childPost.type == AmityDataType.IMAGE) {
            //if the current child post is an image post,
            //we can cast its data to ImageData
            final AmityPostData? amityPostData = childPost.data;
            if (amityPostData != null) {
              final imageData = amityPostData as ImageData;
              //to get the full image url without transcoding
              final largeImageUrl = imageData.getUrl(AmityImageSize.FULL);
            }
          }
        });
      }
    }).onError((error, stackTrace) {
      //handle error
    });
  }

  void getImage(AmityPost post) {
    final AmityPostData? amityPostData = post.data;
    if (amityPostData != null) {
      final imageData = amityPostData as ImageData;
      //for large image url
      final largeImageUrl = imageData.getUrl(AmityImageSize.LARGE);
      //for small image url
      final smallImageUrl = imageData.getUrl(AmityImageSize.SMALL);
    }
  }

  void getFile(AmityPost post) {
    final AmityPostData? amityPostData = post.data;
    if (amityPostData != null) {
      final fileData = amityPostData as FileData;
      final AmityFile amityFile = fileData.file!;
      final String? fileUrl = amityFile.fileUrl;
    }
  }

  void getVideo(AmityPost post) {
    final AmityPostData? amityPostData = post.data;
    if (amityPostData != null) {
      final videoData = amityPostData as VideoData;
      //for high quality video
      videoData.getVideo(AmityVideoQuality.HIGH).then((AmityVideo video) {
        //handle result
      });
      //for low quality video
      videoData.getVideo(AmityVideoQuality.LOW).then((AmityVideo video) {
        //handle result
      });
    }
  }

  void deletePost(String postId) {
    AmitySocialClient.newPostRepository()
        .deletePost(postId: postId)
        .then((value) {
      //success
      //optional: to remove the deleted post from the current post collection
      //you will need manually remove the deleted post from the collection
      //for example :
      _controller.removeWhere((element) => element.postId == postId);
    }).onError((error, stackTrace) {
      //handle error
    });
  }

  void createTextPostWithMention() {
    const userId = 'userAId';
    const startMentionIndex = 0;
    const mentionLength = 6;
    //create AmityMentionMetadata from userId, startIndex and length
    final mentionMetadata = AmityUserMentionMetadata(
        userId: userId, index: startMentionIndex, length: mentionLength);
    //construct AmityMentionMetadata to JsonObject using AmityMentionMetadataCreator
    final mentionMetadataCreator =
        AmityMentionMetadataCreator([mentionMetadata]).create();

    //create a text post with mention
    AmitySocialClient.newPostRepository()
        .createPost()
        .targetUser(
            'userId') // or targetMe(), targetCommunity(communityId: String)
        .text('Hello from flutter!')
        //mentionUsers to trigger push notifications
        .mentionUsers([userId])
        //metadata to render mention highlights
        .metadata(mentionMetadataCreator)
        .post()
        .then((AmityPost post) => {
              //handle result
              //optional: to present the created post in to the current post collection
              //you will need manually put the newly created post in to the collection
              //for example :
              _controller.add(post)
            })
        .onError((error, stackTrace) => {
              //handle error
            });
  }

  void updateTextPostWithMention(AmityPost post) {
    const userId = 'userAId';
    const startMentionIndex = 0;
    const mentionLength = 6;
    //create AmityMentionMetadata from userId, startIndex and length
    final mentionMetadata = AmityUserMentionMetadata(
        userId: userId, index: startMentionIndex, length: mentionLength);
    //construct AmityMentionMetadata to JsonObject using AmityMentionMetadataCreator
    final mentionMetadataCreator =
        AmityMentionMetadataCreator([mentionMetadata]).create();

    //update a text post with mention
    post
        .edit()
        .text('updated post content')
        //mentionUsers to trigger push notifications
        .mentionUsers([userId])
        //metadata to render mention highlights
        .metadata(mentionMetadataCreator)
        .build()
        .update()
        .then((post) => {
              //success
            })
        .onError((error, stackTrace) => {
              //handle error
            });
  }

  void flagPost(AmityPost post) {
    post.report().flag().then((value) {
      //success
    }).onError((error, stackTrace) {
      //handle error
    });
  }

  void getFlagStatus(AmityPost post) {
    final isFlaggedByMe = post.isFlaggedByMe;
  }

  void unflagPost(AmityPost post) {
    post.report().unflag().then((value) {
      //success
    }).onError((error, stackTrace) {
      //handle error
    });
  }

  void checkStatus(AmityPost post) {
    switch (post.feedType) {
      case AmityFeedType.DECLINED:
        // do something
        break;
      case AmityFeedType.PUBLISHED:
        // do something else
        break;

      case AmityFeedType.REVIEWING:
        // do something else
        break;

      default:
        break;
    }
  }

  void getFeedtype(AmityPost post) {
    AmityFeedType? feedType = post.feedType;
  }

  void approvePost(String postId) {
    AmitySocialClient.newPostRepository()
        .reviewPost(postId: postId)
        .approve()
        .then((value) {
      //success
      //optional: to remove the approved post from the current post collection
      //you will need manually remove the approved post from the collection
      //for example :
      _controller.removeWhere((element) => element.postId == postId);
    }).onError((error, stackTrace) {
      //handle error
    });
  }

  void declinePost(String postId) {
    AmitySocialClient.newPostRepository()
        .reviewPost(postId: postId)
        .decline()
        .then((value) {
      //success
      //optional: to remove the declined post from the current post collection
      //you will need manually remove the declined post from the collection
      //for example :
      _controller.removeWhere((element) => element.postId == postId);
    }).onError((error, stackTrace) {
      //handle error
    });
  }
}

@danielkang98 In response to the issue you’ve reported, we recommended compressing the image sizes on your frontend. Unfortunately, transitioning to using File Post will not address the concern you’re facing.

1 Like