这里是整个系统中需要用到的类型,在这里统一做了定义。

完整的 types.mo 文件:

import Principal "mo:base/Principal";
import Time "mo:base/Time";

module {

// ==================== Feed ====================

    public type UserId = Principal;
    public type Time = Time.Time;
    public type PostId = Text; // 帖子 ID = BucketCanisterID + UserId + 自增

    public type Post = {
        postId: PostId; // 帖子 ID 
        feedCanister: Principal;
        index: Nat; // Post Index
        user: UserId; // 发布者
        content: Text;
        var repost: [Repost]; //转发者
        var like: [Like];
        var comment: [Comment];
        createdAt: Time; // 发布时间
    };

    public type PostImmutable = {
        postId: PostId; // 帖子 ID 
        feedCanister: Principal; 
        index: Nat; // Post Index
        user: UserId; // 发布者
        content: Text;
        repost: [Repost]; // 转发者
        like: [Like];
        comment: [Comment];
        createdAt: Time; // 发布时间
    };

    public type Comment = {
        user: UserId;
        content: Text;
        createdAt: Time;
    };

    public type NewComment = [Comment];

    public type Like = {
        user: UserId;
        createdAt: Time;
    };

    public type Repost = {
        user: UserId;
        createdAt: Time;
    };

    public type NewRepost = [Repost];

    public type NewLike = [Like];

    public type RootFeedActor = actor {
        getAllUserFeedCanister : shared query () -> async [(Principal, Principal)];
    };

    public type FeedActor = actor {
        getPosts : shared query () -> async [PostImmutable];
        receiveFeed : shared (Text) -> async Bool;
        batchReceiveFeed : shared ([Text]) -> async ();
        batchReceiveComment : shared ([Text]) -> async ();
        batchReceiveLike : shared ([Text]) -> async ();
        createComment : shared (Principal, Nat, Text) -> async ();
        deleteComment : shared (Principal, Nat, Nat) -> async ();
        createLike : shared (Principal, Nat) -> async ();
        deleteLike : shared (Principal, Nat) -> async ();
        updateFollowers : shared ([Principal]) -> async ();
    };

// ==================== Post ====================

    public type RootPostActor = actor {
        getAvailableBucket : shared query () -> async ?Principal;
        getAllBuckets : shared query () -> async [Principal];
        getAllAvailableBuckets : shared query () -> async [Principal];        
        getAllUnavailableBuckets : shared query () -> async [Principal];
        reCreateBucket : shared () -> async ();
    };

// ==================== Bucket ====================

    public type BucketActor = actor {
        storeFeed : shared (PostImmutable) -> async Bool;
        updatePostComment : shared (Text, NewComment) -> async Bool;
        updatePostLike : shared (Text, NewLike) -> async Bool;
        updatePostRepost : shared (Text, NewRepost) -> async Bool;
        getPosts : shared query ([Text]) -> async [PostImmutable];
        getPost : shared query (Text) -> async ?PostImmutable;
    };

// ==================== Fetch ====================

    public type RootFetchActor = actor {
        createPostFetchCanister : shared () -> async Principal;
        createCommentFetchCanister : shared () -> async Principal;
        createLikeFetchCanister : shared () -> async Principal;
        getAllPostFetchCanister : shared query () -> async [Principal];
        getAllCommentFetchCanister : shared query () -> async [Principal];
        getAllLikeFetchCanister : shared query () -> async [Principal];
    };

    public type PostFetchActor = actor {
        receiveNotify : shared ([Principal], Text) -> async ();
        addUserToFeedEntry : shared ((Principal, Principal)) -> async Bool;
        initUserToFeed : shared ([(Principal, Principal)]) -> async Bool;
    };

    public type CommentFetchActor = actor {
        receiveNotify : shared (PostImmutable) -> async ();
        receiveRepostUserNotify : shared ([Principal], Text) -> async ();
        addUserToFeedEntry : shared ((Principal, Principal)) -> async Bool;
        initUserToFeed : shared ([(Principal, Principal)]) -> async Bool;
    };
    
    public type LikeFetchActor = actor {
        receiveNotify : shared (PostImmutable) -> async ();
        receiveRepostUserNotify : shared ([Principal], Text) -> async ();
        addUserToFeedEntry : shared ((Principal, Principal)) -> async Bool;
        initUserToFeed : shared ([(Principal, Principal)]) -> async Bool;
    };

// ==================== User ====================

    public type Vertex = Principal;

    public type UserActor = actor {
        getFollowersList : shared query (Vertex) -> async [Vertex];
    };

}


utils.mo 文件提供一些用于处理帖子(Post)的辅助函数。

checkPostId 函数从帖子 ID 中提取了存储桶 ID 、用户 ID 和帖子索引。

  • 参数:postId - 帖子的唯一标识符(由 BucketCanisterID + UserId + 自增 构成)。
  • 返回值:元组,包含从帖子 ID 中提取的 bucket(存储桶 ID )、user(用户 ID )、postIndex(帖子索引)。

_convertPostToImmutable 函数用于将可变帖子转换为不可变帖子。

  • 参数:post - 可变的帖子(Post)。
  • 返回值:将可变帖子转换为不可变帖子(PostImmutable)的函数。

_isRepostUser 函数用于检查指定用户是否是给定帖子的转发用户之一。

  • 参数:post - 不可变的帖子(PostImmutable)、user - 要检查是否为转发用户的用户 ID 。
  • 返回值:如果指定用户是帖子的转发用户之一,则返回 true ;否则返回 false 。
import Iter "mo:base/Iter";
import Text "mo:base/Text";
import Principal "mo:base/Principal";
import Option "mo:base/Option";
import Nat "mo:base/Nat";
import Debug "mo:base/Debug";
import Types "./types";

module {
    type Post = Types.Post;
    type PostImmutable = Types.PostImmutable;

    public func checkPostId(postId: Text): (Principal, Principal, Nat) {
        let words = Iter.toArray(Text.split(postId, #char '#'));
        let bucket = Principal.fromText(words[0]);
        let user = Principal.fromText(words[1]);
        let postIndex = Option.unwrap(Nat.fromText(words[2]));
        // Debug.print("(bucket, user, index) : (" # words[0] # "," # words[1] # "," # words[2] # ")");
        (bucket, user, postIndex)
    };

    public func _convertPostToImmutable(post: Post): PostImmutable {
      {
        postId = post.postId;
        index = post.index;
        feedCanister = post.feedCanister;
        user = post.user;
        repost = post.repost;
        content = post.content;
        like = post.like;
        comment = post.comment;
        createdAt = post.createdAt;
      }
    };

    public func _isRepostUser(post: PostImmutable, user: Principal): Bool {
        for(_repostUser in post.repost.vals()) {
            if(_repostUser.user == user) {
                return true;
            };
        };
        false
    };

}