Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 23 additions & 32 deletions packages/frontend-main/src/composables/useCreatePost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { userPosts } from './useUserPosts';
import { useWallet } from './useWallet';

import { fractionalDigits } from '@/utility/atomics';
import { infiniteDataWithNewItem, newPost } from '@/utility/optimisticBuilders';
import { infiniteDataWithNewItem, newPost as newPostFn } from '@/utility/optimisticBuilders';

interface CreatePostRequestMutation {
message: string;
Expand All @@ -26,9 +26,7 @@ export function useCreatePost(
const isToastShown = ref(false);
useTxNotification('Post', txSuccess, txError);

const {
mutateAsync,
} = useMutation({
const { mutateAsync } = useMutation({
mutationFn: async ({ message, amountAtomics }: CreatePostRequestMutation) => {
txError.value = undefined;
txSuccess.value = undefined;
Expand All @@ -55,43 +53,36 @@ export function useCreatePost(
return txSuccess.value;
}
},
onMutate: async () => {
const feedOpts = feed(queryClient);
const userPostsOpts = userPosts({ userAddress: wallet.address });
await Promise.all([
queryClient.cancelQueries(feedOpts),
queryClient.cancelQueries(userPostsOpts),
]);

const previousFeed = queryClient.getQueryData(
feedOpts.queryKey,
) as InfiniteData<Post[], unknown> | undefined;
const previousUserPosts = queryClient.getQueryData(
userPostsOpts.queryKey,
) as InfiniteData<Post[], unknown> | undefined;

return { previousFeed, previousUserPosts };
},
onSuccess: (hash, variables, context) => {
onSuccess: (hash, variables) => {
if (!hash) throw new Error('Error: No hash in TX');

const feedOpts = feed(queryClient);
const userPostsOpts = userPosts({ userAddress: wallet.address });

// Created Post
const optimisticNewPost: Post = newPost({ message: variables.message, quantity: Decimal.fromAtomics(variables.amountAtomics, fractionalDigits).atomics, hash, author: wallet.address.value, postHash: null });
const newFeedData = infiniteDataWithNewItem<Post>({ previousItems: context.previousFeed, newItem: optimisticNewPost });
const newUserPostsData = infiniteDataWithNewItem<Post>({ previousItems: context.previousUserPosts, newItem: optimisticNewPost });
const newPost: Post = newPostFn({
message: variables.message,
quantity: Decimal.fromAtomics(variables.amountAtomics, fractionalDigits).atomics,
hash,
author: wallet.address.value,
postHash: null,
});

const previousFeed = queryClient.getQueryData<InfiniteData<Post[]>>(feedOpts.queryKey);
const previousUserPosts = queryClient.getQueryData<InfiniteData<Post[]>>(userPostsOpts.queryKey);

const newFeedData = infiniteDataWithNewItem<Post>({
previousItems: previousFeed,
newItem: newPost,
});

const newUserPostsData = infiniteDataWithNewItem({
previousItems: previousUserPosts,
newItem: newPost,
});

queryClient.setQueryData(feedOpts.queryKey, newFeedData);
queryClient.setQueryData(userPostsOpts.queryKey, newUserPostsData);
},
onError: (_, __, context) => {
const feedOpts = feed(queryClient);
const userPostsOpts = userPosts({ userAddress: wallet.address });
queryClient.setQueryData(feedOpts.queryKey, context?.previousFeed);
queryClient.setQueryData(userPostsOpts.queryKey, context?.previousUserPosts);
},
onSettled: () => {
isToastShown.value = false;
},
Expand Down
62 changes: 16 additions & 46 deletions packages/frontend-main/src/composables/useCreateReply.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { Post, ReplyWithParent } from 'api-main/types/feed';

import { type Ref, ref } from 'vue';
import { Decimal } from '@cosmjs/math';
import { type InfiniteData, useMutation, useQueryClient } from '@tanstack/vue-query';
import { useMutation, useQueryClient } from '@tanstack/vue-query';

import { post } from './usePost';
import { replies } from './useReplies';
Expand All @@ -28,9 +28,7 @@ export function useCreateReply(
const isToastShown = ref(false);
useTxNotification('Reply', txSuccess, txError);

const {
mutateAsync,
} = useMutation({
const { mutateAsync } = useMutation({
mutationFn: async ({ parentPost, message, amountAtomics }: CreateReplyRequestMutation) => {
txError.value = undefined;
txSuccess.value = undefined;
Expand All @@ -57,67 +55,39 @@ export function useCreateReply(
return txSuccess.value;
}
},
onMutate: async (variables) => {
const parentPostOpts = post({ hash: ref(variables.parentPost.value.hash) });
const repliesOpts = replies({ hash: ref(variables.parentPost.value.hash) });
const userRepliesOpts = userReplies({ userAddress: wallet.address });

await Promise.all([
queryClient.cancelQueries(parentPostOpts),
queryClient.cancelQueries(repliesOpts),
queryClient.cancelQueries(userRepliesOpts),
]);

const previousParentPost = queryClient.getQueryData(
parentPostOpts.queryKey,
) as Post | undefined;
const previousReplies = queryClient.getQueryData(
repliesOpts.queryKey,
) as InfiniteData<Post[], unknown> | undefined;
const previousUserReplies = queryClient.getQueryData(
userRepliesOpts.queryKey,
) as InfiniteData<ReplyWithParent[], unknown> | undefined;

return { previousParentPost, previousReplies, previousUserReplies };
},
onSuccess: (createdHash, variables, context) => {
onSuccess: (createdHash, variables) => {
if (!createdHash) throw new Error('Error: No hash in TX');

const parentPostOpts = post({ hash: ref(variables.parentPost.value.hash) });
const repliesOpts = replies({ hash: ref(variables.parentPost.value.hash) });
const userRepliesOpts = userReplies({ userAddress: wallet.address });

const previousParentPost = queryClient.getQueryData(parentPostOpts.queryKey);
const previousReplies = queryClient.getQueryData(repliesOpts.queryKey);
const previousUserReplies = queryClient.getQueryData(userRepliesOpts.queryKey);

// Parent Post with updated replies count
const optimisticParentPost: Post
= context.previousParentPost
? { ...context.previousParentPost, replies: (context.previousParentPost.replies || 0) + 1 }
const newParentPost: Post
= previousParentPost
? { ...previousParentPost, replies: (previousParentPost.replies || 0) + 1 }
: { ...variables.parentPost.value, replies: (variables.parentPost.value.replies || 0) + 1 };
// Created Post with parent hash as post_hash
const optimisticNewReply: Post = newPost({ message: variables.message, quantity: Decimal.fromAtomics(variables.amountAtomics, fractionalDigits).atomics, hash: createdHash, postHash: variables.parentPost.value.hash, author: wallet.address.value });
const newReply: Post = newPost({ message: variables.message, quantity: Decimal.fromAtomics(variables.amountAtomics, fractionalDigits).atomics, hash: createdHash, postHash: variables.parentPost.value.hash, author: wallet.address.value });
// Created Post in ReplyWithParent
const optimisticNewUserReply: ReplyWithParent = {
const newUserReply: ReplyWithParent = {
reply: newPost(
{ message: variables.message, quantity: Decimal.fromAtomics(variables.amountAtomics, fractionalDigits).atomics, hash: createdHash, postHash: variables.parentPost.value.hash, author: wallet.address.value },
),
parent: optimisticParentPost,
parent: newParentPost,
};

const newRepliesData = infiniteDataWithNewItem<Post>({ previousItems: context.previousReplies, newItem: optimisticNewReply });
const newUserRepliesData = infiniteDataWithNewItem<ReplyWithParent>({ previousItems: context.previousUserReplies, newItem: optimisticNewUserReply });
const newRepliesData = infiniteDataWithNewItem<Post>({ previousItems: previousReplies, newItem: newReply });
const newUserRepliesData = infiniteDataWithNewItem<ReplyWithParent>({ previousItems: previousUserReplies, newItem: newUserReply });

queryClient.setQueryData(parentPostOpts.queryKey, optimisticParentPost);
queryClient.setQueryData(parentPostOpts.queryKey, newParentPost);
queryClient.setQueryData(repliesOpts.queryKey, newRepliesData);
queryClient.setQueryData(userRepliesOpts.queryKey, newUserRepliesData);
},
onError: (_, variables, context) => {
const parentPostOpts = post({ hash: ref(variables.parentPost.value.hash) });
const repliesOpts = replies({ hash: ref(variables.parentPost.value.hash) });
const userRepliesOpts = userReplies({ userAddress: wallet.address });

queryClient.setQueryData(parentPostOpts.queryKey, context?.previousParentPost);
queryClient.setQueryData(repliesOpts.queryKey, context?.previousReplies);
queryClient.setQueryData(userRepliesOpts.queryKey, context?.previousUserReplies);
},
onSettled: () => {
isToastShown.value = false;
},
Expand Down
41 changes: 9 additions & 32 deletions packages/frontend-main/src/composables/useDislikePost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,15 @@ interface DislikePostRequestMutation {
amountAtomics: string;
}

export function useDislikePost(
) {
export function useDislikePost() {
const queryClient = useQueryClient();
const wallet = useWallet();
const txError = ref<string>();
const txSuccess = ref<string>();
const isToastShown = ref(false);
useTxNotification('Dislike', txSuccess, txError);

const {
mutateAsync,
} = useMutation({
const { mutateAsync } = useMutation({
mutationFn: async ({ post, amountAtomics }: DislikePostRequestMutation) => {
txError.value = undefined;
txSuccess.value = undefined;
Expand All @@ -41,34 +38,14 @@ export function useDislikePost(
}
txSuccess.value = result.tx?.transactionHash;
},
onMutate: async (variables) => {
onSuccess: (_, variables) => {
const postOpts = post({ hash: ref(variables.post.value.hash) });

await Promise.all([
queryClient.cancelQueries(postOpts),
]);

const previousPost = queryClient.getQueryData(
postOpts.queryKey,
) as Post | undefined;

return {
previousPost,
};
},
onSuccess: (_, variables, context) => {
const postOpts = post({ hash: ref(variables.post.value.hash) });
// Post with updated dislikes_burnt
const optimisticPost: Post
= context.previousPost
? { ...context.previousPost, dislikes_burnt: addAtomics((context.previousPost.dislikes_burnt ?? 0).toString(), variables.amountAtomics) }
: { ...variables.post.value, dislikes_burnt: addAtomics((variables.post.value.dislikes_burnt ?? 0).toString(), variables.amountAtomics) };

queryClient.setQueryData(postOpts.queryKey, optimisticPost);
},
onError: (_, variables, context) => {
const postOpts = post({ hash: ref(variables.post.value.hash) });
queryClient.setQueryData(postOpts.queryKey, context?.previousPost);
// Update post's dislikes_burnt
queryClient.setQueryData<Post>(postOpts.queryKey, (current) => {
const currentDislikesBurnt = current?.dislikes_burnt ?? variables.post.value.dislikes_burnt ?? '0';
const newDislikeBurnt = addAtomics(currentDislikesBurnt, variables.amountAtomics);
return { ...(current ?? variables.post.value), dislikes_burnt: newDislikeBurnt };
});
},
onSettled: () => {
isToastShown.value = false;
Expand Down
38 changes: 8 additions & 30 deletions packages/frontend-main/src/composables/useFlagPost.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ export function useFlagPost(
const isToastShown = ref(false);
useTxNotification('Flag', txSuccess, txError);

const {
mutateAsync,
} = useMutation({
const { mutateAsync } = useMutation({
mutationFn: async ({ post, amountAtomics }: FlagPostRequestMutation) => {
txError.value = undefined;
txSuccess.value = undefined;
Expand All @@ -45,34 +43,14 @@ export function useFlagPost(
return txSuccess.value;
}
},
onMutate: async (variables) => {
onSuccess: (_, variables) => {
const postOpts = post({ hash: ref(variables.post.value.hash) });

await Promise.all([
queryClient.cancelQueries(postOpts),
]);

const previousPost = queryClient.getQueryData(
postOpts.queryKey,
) as Post | undefined;

return {
previousPost,
};
},
onSuccess: (_, variables, context) => {
const postOpts = post({ hash: ref(variables.post.value.hash) });
// Post with updated flags_burnt
const optimisticPost: Post
= context.previousPost
? { ...context.previousPost, flags_burnt: addAtomics((context.previousPost.flags_burnt ?? 0).toString(), variables.amountAtomics) }
: { ...variables.post.value, flags_burnt: addAtomics((variables.post.value.flags_burnt ?? 0).toString(), variables.amountAtomics) };

queryClient.setQueryData(postOpts.queryKey, optimisticPost);
},
onError: (_, variables, context) => {
const postOpts = post({ hash: ref(variables.post.value.hash) });
queryClient.setQueryData(postOpts.queryKey, context?.previousPost);
// Update post's flags_burnt
queryClient.setQueryData<Post>(postOpts.queryKey, (current) => {
const currentFlagsBurnt = current?.flags_burnt ?? variables.post.value.flags_burnt ?? '0';
const newFlagsBurnt = addAtomics(currentFlagsBurnt, variables.amountAtomics);
return { ...(current ?? variables.post.value), flags_burnt: newFlagsBurnt };
});
},
onSettled: () => {
isToastShown.value = false;
Expand Down
55 changes: 15 additions & 40 deletions packages/frontend-main/src/composables/useFollowUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ export function useFollowUser(
const isToastShown = ref(false);
useTxNotification('Follow', txSuccess, txError);

const {
mutateAsync,
} = useMutation({
const { mutateAsync } = useMutation({
mutationFn: async ({ userAddress, amountAtomics }: FollowUserRequestMutation) => {
txError.value = undefined;
txSuccess.value = undefined;
Expand All @@ -44,49 +42,26 @@ export function useFollowUser(
}
txSuccess.value = result.tx?.transactionHash;
},
onMutate: async (variables) => {
const isFollowingOpts = isFollowing({ followerAddress: wallet.address, followingAddress: variables.userAddress });
const followingOpts = following({ userAddress: wallet.address });

await Promise.all([
await queryClient.cancelQueries(isFollowingOpts),
await queryClient.cancelQueries(followingOpts),
]);

const previousIsFollowing = queryClient.getQueryData(
isFollowingOpts.queryKey,
) as boolean | undefined;
const previousFollowing = queryClient.getQueryData(
followingOpts.queryKey,
) as InfiniteData<Following[], unknown> | undefined;

return {
previousIsFollowing,
previousFollowing,
};
},
onSuccess: (_, variables, context) => {
const isFollowingOpts = isFollowing({ followerAddress: wallet.address, followingAddress: variables.userAddress });
onSuccess: (_, variables) => {
const isFollowingOpts = isFollowing({
followerAddress: wallet.address,
followingAddress: variables.userAddress,
});
const followingOpts = following({ userAddress: wallet.address });
const followingPostsOpts = followingPosts({ userAddress: wallet.address });

const optimisticNewFollowing: Following = newFollowing({ address: variables.userAddress.value });
const newFollowingData = infiniteDataWithNewItem<Following>({
previousItems: context.previousFollowing,
newItem: optimisticNewFollowing,
const newFollowingItem: Following = newFollowing({
address: variables.userAddress.value,
});

queryClient.setQueryData(isFollowingOpts.queryKey, true);
queryClient.setQueryData(followingOpts.queryKey, newFollowingData);
queryClient.setQueryData(isFollowingOpts.queryKey, () => true);
queryClient.setQueryData<InfiniteData<Following[]>>(followingOpts.queryKey, current =>
infiniteDataWithNewItem<Following>({
previousItems: current ?? { pages: [], pageParams: [] },
newItem: newFollowingItem,
}),
);
queryClient.invalidateQueries(followingPostsOpts);
},
onError: (_, variables, context) => {
const isFollowingOpts = isFollowing({ followerAddress: wallet.address, followingAddress: variables.userAddress });
const followingOpts = following({ userAddress: wallet.address });

queryClient.setQueryData(isFollowingOpts.queryKey, context?.previousIsFollowing);
queryClient.setQueryData(followingOpts.queryKey, context?.previousFollowing);
},
onSettled: () => {
isToastShown.value = false;
},
Expand Down
Loading