Skip to content
Merged
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
14 changes: 7 additions & 7 deletions src/Components/AuthorAsk/AuthorAsk.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,10 @@ export default function AuthorAsk({ post }: AuthorAskProps) {

setLoadingParentAuthor(true);
try {
// Get authors of the parent post
const parentAuthors = await queries.authors.ofPost(post.parent_post);
if (parentAuthors.length > 0) {
setParentPostAuthor(parentAuthors[0]); // Take the first author
// Get authors of the parent post using standardPostInfo
const parentPostInfo = await queries.views.standardPostInfo(post.parent_post);
if (parentPostInfo.profiles.length > 0) {
setParentPostAuthor(parentPostInfo.profiles[0]); // Take the first author
} else {
setParentPostAuthor(null);
}
Expand All @@ -152,11 +152,11 @@ export default function AuthorAsk({ post }: AuthorAskProps) {
useEffect(() => {
async function fetchAuthors() {
try {
const postAuthors = await queries.authors.ofPost(post.id);
setAuthors(postAuthors);
const postInfo = await queries.views.standardPostInfo(post.id);
setAuthors(postInfo.profiles);

// Check if the user is the last author
if (auth.user && postAuthors.length === 1 && postAuthors[0]?.id === auth.user.id) {
if (auth.user && postInfo.profiles.length === 1 && postInfo.profiles[0]?.id === auth.user.id) {
setIsLastAuthor(true);
} else {
setIsLastAuthor(false);
Expand Down
9 changes: 4 additions & 5 deletions src/Components/PostAdd/PostAdd.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,13 @@ export default function PostAdd({
try {
setIsLoadingPost(true);

// Charger le post
const post = await queries.posts.get(editPostId);
setBody(post.body ?? "");
// Load post info including authors
const postInfo = await queries.views.standardPostInfo(editPostId);
setBody(postInfo.post.body ?? "");

// Check that the user is the author of the post
const authors = await queries.authors.ofPost(editPostId);
const currentUserId = auth.user.id;
const isAuthor = authors.some((author) => author.id === currentUserId);
const isAuthor = postInfo.profiles.some((author) => author.id === currentUserId);

if (!isAuthor) {
setError("You are not allowed to edit this post.");
Expand Down
166 changes: 57 additions & 109 deletions src/Components/PostViewer/PostViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,73 +70,80 @@ export default function PostViewer(props: PostViewerProps) {
const mainAuthor = authors.length > 0 ? authors[0] : null;
const isAuthor = auth.user && authors.some((author) => author.id === auth.user?.id);
const isSimpleRetweet = queries.posts.isSimpleRetweet(props.post);
// Fetch post authors

// Fetch post info (authors, categories, likes, retweets) in one request
useEffect(() => {
async function fetchAuthors() {
async function fetchPostInfo() {
try {
// Si c'est un retweet simple, on récupère les auteurs du post original
// Si c'est un retweet simple, on récupère les infos du post original
if (queries.posts.isSimpleRetweet(props.post)) {
const originalPost = await queries.posts.getOriginalPost(props.post);
if (originalPost) {
const originalAuthors = await queries.authors.ofPost(originalPost.id);
setAuthors(originalAuthors);
// Set the original post state for use in other effects
setOriginalPost(originalPost);

const originalPostInfo = await queries.views.standardPostInfo(originalPost.id);
setAuthors(originalPostInfo.profiles);
setCategories(originalPostInfo.categories);
setLikeCount(originalPostInfo.likesCount);
setRetweetCount(originalPostInfo.rtCount);

// Récupérer l'auteur du retweet
const retweetAuthors = await queries.authors.ofPost(props.post.id);
setRetweetedBy(retweetAuthors[0] || null);

// Pour un retweet simple, l'utilisateur n'est jamais le dernier auteur du post original
setIsLastAuthor(false);
return;
} else {
setOriginalPost(null);
setRetweetedBy(null);
}
} else {
setOriginalPost(null);
setRetweetedBy(null);
}

// Pour les posts normaux ou les quote retweets
const postAuthors = await queries.authors.ofPost(props.post.id);
setAuthors(postAuthors);
const postInfo = await queries.views.standardPostInfo(props.post.id);
setAuthors(postInfo.profiles);
setCategories(postInfo.categories);
setLikeCount(postInfo.likesCount);
setRetweetCount(postInfo.rtCount);

// Check if the user is the last author
if (auth.user && postAuthors.length === 1 && postAuthors[0]?.id === auth.user.id) {
if (auth.user && postInfo.profiles.length === 1 && postInfo.profiles[0]?.id === auth.user.id) {
setIsLastAuthor(true);
} else {
setIsLastAuthor(false);
}
} catch {
setAuthors([]);
setCategories([]);
setLikeCount(0);
setRetweetCount(0);
setIsLastAuthor(false);
setOriginalPost(null);
setRetweetedBy(null);
}
}
void fetchAuthors();
void fetchPostInfo();
}, [props.post.id, props.post, auth.user]);
// Fetch categories
useEffect(() => {
async function fetchCategories() {
try {
// Si c'est un retweet simple, récupérer les catégories du post original
let postIdToUse = props.post.id;
if (queries.posts.isSimpleRetweet(props.post) && originalPost) {
postIdToUse = originalPost.id;
}

const postCategories = await queries.postsCategories.get(postIdToUse);
setCategories(postCategories);
} catch {
setCategories([]);
}
}
void fetchCategories();
}, [props.post.id, props.post, originalPost]);

// Fetch child posts with likes sorting
useEffect(() => {
async function fetchChildren() {
try {
const childPosts = await queries.posts.getChildren(props.post.id);

// For each child, get the number of likes
// For each child, get the number of likes using standardPostInfo
const childrenWithLikes = await Promise.all(
childPosts.map(async (child) => {
try {
const likes = await queries.like.byWho(child.id);
const childInfo = await queries.views.standardPostInfo(child.id);
return {
...child,
likeCount: likes.length,
likeCount: childInfo.likesCount,
};
} catch {
return {
Expand Down Expand Up @@ -223,52 +230,11 @@ export default function PostViewer(props: PostViewerProps) {
void fetchMediaUrls();
}, [props.post.id, props.post, originalPost]);

// Fetch likes
// Check if user liked the post and if user has retweeted
useEffect(() => {
async function fetchLikes() {
try {
// Si c'est un retweet simple, on récupère les likes du post original
let targetPostId = props.post.id;
if (queries.posts.isSimpleRetweet(props.post) && originalPost) {
targetPostId = originalPost.id;
}

const likedByUsers = await queries.like.byWho(targetPostId);
setLikeCount(likedByUsers.length);

if (auth.user) {
const userLikesPost = await queries.like.doesUserLikePost(auth.user.id, targetPostId);
setIsLiked(userLikesPost);
} else {
setIsLiked(false);
}
} catch {
setLikeCount(0);
setIsLiked(false);
}
}
void fetchLikes();
}, [props.post.id, props.post, auth.user, originalPost]); // Récupération des retweets
useEffect(() => {
async function fetchRetweets() {
try {
// Pour les retweets simples, compter les retweets du post original
let targetPostId = props.post.id;
if (queries.posts.isSimpleRetweet(props.post) && originalPost) {
targetPostId = originalPost.id;
}

const retweets = await queries.posts.getRetweetsOf(targetPostId);
setRetweetCount(retweets.length);
} catch {
setRetweetCount(0);
}
}
void fetchRetweets();
}, [props.post.id, props.post, originalPost]); // Vérifier si l'utilisateur a déjà retweeté ce post
useEffect(() => {
async function checkUserRetweet() {
async function checkUserActions() {
if (!auth.user) {
setIsLiked(false);
setHasRetweeted(false);
return;
}
Expand All @@ -280,39 +246,23 @@ export default function PostViewer(props: PostViewerProps) {
targetPostId = originalPost.id;
}

const hasUserRetweeted = await queries.posts.hasUserRetweeted(targetPostId, auth.user.id);
const [userLikesPost, hasUserRetweeted] = await Promise.all([
queries.like.doesUserLikePost(auth.user.id, targetPostId),
queries.posts.hasUserRetweeted(targetPostId, auth.user.id),
]);

setIsLiked(userLikesPost);
setHasRetweeted(hasUserRetweeted);
} catch {
} catch (error) {
console.error("[ERROR] Error checking user actions:", error);
setIsLiked(false);
setHasRetweeted(false);
}
}

void checkUserRetweet();
void checkUserActions();
}, [props.post.id, props.post, auth.user, originalPost]);

// Récupérer le post original si c'est un retweet simple
useEffect(() => {
async function fetchOriginalPost() {
if (queries.posts.isSimpleRetweet(props.post)) {
try {
const original = await queries.posts.getOriginalPost(props.post);
setOriginalPost(original);

// Récupérer l'auteur du retweet
const retweetAuthors = await queries.authors.ofPost(props.post.id);
setRetweetedBy(retweetAuthors[0] || null);
} catch {
setOriginalPost(null);
setRetweetedBy(null);
}
} else {
setOriginalPost(null);
setRetweetedBy(null);
}
}

void fetchOriginalPost();
}, [props.post]);
// Récupérer le post cité si c'est un quote tweet
useEffect(() => {
async function fetchQuotedPost() {
Expand All @@ -322,12 +272,10 @@ export default function PostViewer(props: PostViewerProps) {
setQuotedPost(quoted);

if (quoted) {
const quotedAuthors = await queries.authors.ofPost(quoted.id);
setQuotedPostAuthors(quotedAuthors);

// Récupérer les catégories du post cité
const quotedCategories = await queries.postsCategories.get(quoted.id);
setQuotedPostCategories(quotedCategories);
// Use standardPostInfo for quoted post data
const quotedPostInfo = await queries.views.standardPostInfo(quoted.id);
setQuotedPostAuthors(quotedPostInfo.profiles);
setQuotedPostCategories(quotedPostInfo.categories);

// Récupérer les médias du post cité
try {
Expand Down Expand Up @@ -436,7 +384,7 @@ export default function PostViewer(props: PostViewerProps) {
await queries.like.remove(targetPostId);

// Check after removal
const afterRemove = await queries.like.doesUserLikePost(auth.user.id, props.post.id);
const afterRemove = await queries.like.doesUserLikePost(auth.user.id, targetPostId);

if (!afterRemove) {
setLikeCount((prev) => prev - 1);
Expand Down Expand Up @@ -502,8 +450,8 @@ export default function PostViewer(props: PostViewerProps) {
setTimeout(() => {
void (async () => {
try {
const postAuthors = await queries.authors.ofPost(props.post.id);
setAuthors(postAuthors);
const postInfo = await queries.views.standardPostInfo(props.post.id);
setAuthors(postInfo.profiles);
// Refresh the page to ensure everything is up to date
setTimeout(() => {
window.location.reload();
Expand Down
6 changes: 3 additions & 3 deletions src/Components/QuoteTweetModal/QuoteTweetModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ export default function QuoteTweetModal({ post, originalPost, modalId, onSuccess

setLoading(true);
try {
const [authorsResult, { data: mediaFiles }] = await Promise.all([
queries.authors.ofPost(postToQuote.id),
const [postInfoResult, { data: mediaFiles }] = await Promise.all([
queries.views.standardPostInfo(postToQuote.id),
supabase.storage.from("post-media").list(postToQuote.id, { limit: 1 }),
]);

setAuthor(authorsResult[0] || null);
setAuthor(postInfoResult.profiles[0] || null);

if (mediaFiles?.length) {
const url = supabase.storage.from("post-media").getPublicUrl(`${postToQuote.id}/${mediaFiles[0].name}`)
Expand Down
8 changes: 7 additions & 1 deletion src/contexts/supabase/supabase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ interface stdPostInfo {
post: Tables<"posts">;
categories: Tables<"categories">[];
profiles: Tables<"profiles">[];
likesCount: number;
rtCount: number;
}

interface PostSearchQuery {
Expand Down Expand Up @@ -864,7 +866,9 @@ const queries = {
),
authors:authors(
profiles:profiles(*)
)
),
likes:likes(count),
rt_of:posts!rt_of(count)
`,
)
.eq("id", id)
Expand All @@ -880,6 +884,8 @@ const queries = {
post: req.data as Tables<"posts">,
categories,
profiles,
likesCount: req.data.likes[0]?.count ?? 0,
rtCount: req.data.rt_of?.count ?? 0,
};
},
},
Expand Down
Loading
Loading