The types needed in the entire system are defined here.
The complete types.mo file:
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; // Post ID = BucketCanisterID + UserId + Incremental
public type Post = {
postId: PostId; // Post ID
feedCanister: Principal;
index: Nat; // Post Index
user: UserId; // Publisher
content: Text;
var repost: [Repost]; // Reposters
var like: [Like];
var comment: [Comment];
createdAt: Time; // Publication time
};
public type PostImmutable = {
postId: PostId; // Post ID
feedCanister: Principal;
index: Nat; // Post Index
user: UserId; // Publisher
content: Text;
repost: [Repost]; // Reposters
like: [Like];
comment: [Comment];
createdAt: Time; // Publication 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 file provides some helper functions for handling posts.
The checkPostId
function extracts the bucket ID, user ID, and post index from the post ID.
- Parameters:
postId
- The unique identifier of the post (composed ofBucketCanisterID + UserId + Incremental
). - Return value: A tuple containing the extracted
bucket
(bucket ID),user
(user ID), andpostIndex
(post index) from the post ID.
The _convertPostToImmutable
function is used to convert a mutable post to an immutable post.
- Parameters:
post
- Mutable post (Post). - Return value: A function that converts a mutable post to an immutable post (PostImmutable).
The _isRepostUser
function checks if a specified user is one of the repost users for a given post.
- Parameters:
post
- Immutable post (PostImmutable),user
- User ID to check if it is a repost user. - Return value: Returns true if the specified user is one of the repost users for the post; otherwise, returns 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
};
}