This commit is contained in:
payacom
2026-07-23 15:58:15 +03:30
parent af5b27b610
commit a1d7db5e7e
445 changed files with 23456 additions and 8865 deletions

View File

@@ -1,6 +1,6 @@
"use client";
import { useCallback, useState } from "react";
import { useCallback, useEffect, useState } from "react";
import Image from "next/image";
import { Post } from "@/types/types";
import useAxios from "@/hooks/useAxios";
@@ -12,6 +12,12 @@ import useInfiniteScroll from "@/hooks/useInfiniteScroll";
import { buildPostPublicUrl } from "@/lib/postSlug";
import Cookies from "js-cookie";
import { trackExploreInteraction } from "@/api/trackExploreInteraction";
import { updateReelsSeedPostEngagement } from "@/lib/reelsSeedPost";
import { useTranslation } from "react-i18next";
function coerceBool(value: unknown): boolean {
return value === true || value === 1 || value === "true" || value === "1";
}
export function usePostSocialState(postData: Post) {
const {
@@ -26,13 +32,31 @@ export function usePostSocialState(postData: Post) {
type: postType,
} = postData;
const [liked, setLiked] = useState(is_liked || false);
const [liked, setLiked] = useState(() => coerceBool(is_liked));
const [likesCountState, setLikesCount] = useState(likesCount || 0);
const [saved, setSaved] = useState(initialSaved);
const [saved, setSaved] = useState(() => coerceBool(initialSaved));
const [savesCount, setSavesCount] = useState(initialSaves);
const [sendsCount, setSendsCount] = useState(initialSends);
const [following, setFollowing] = useState(initialFollowing);
const [following, setFollowing] = useState(() => coerceBool(initialFollowing));
useEffect(() => {
setLiked(coerceBool(is_liked));
setLikesCount(likesCount || 0);
setSaved(coerceBool(initialSaved));
setSavesCount(initialSaves);
setSendsCount(initialSends);
setFollowing(coerceBool(initialFollowing));
}, [
postId,
is_liked,
likesCount,
initialSaved,
initialSaves,
initialSends,
initialFollowing,
]);
const { t } = useTranslation("common");
const { request, loading } = useAxios();
const requireAuth = useRequireAuth();
const currentUserId = getStoredUserId();
@@ -58,7 +82,7 @@ export function usePostSocialState(postData: Post) {
const toggleLike = useCallback(async () => {
if (!requireAuth()) return;
if (!user_id || !postId) {
toast.error("لطفاً وارد حساب کاربری خود شوید");
toast.error(t("posts.loginToPost"));
return;
}
if (loading) return;
@@ -76,7 +100,12 @@ export function usePostSocialState(postData: Post) {
{ noToast: true }
);
setLikesCount(response?.likesCount ?? newLikesCount);
setLiked(response?.is_liked ?? newLiked);
const resolvedLiked = coerceBool(response?.is_liked ?? newLiked);
setLiked(resolvedLiked);
updateReelsSeedPostEngagement(String(postId), {
is_liked: resolvedLiked,
likesCount: response?.likesCount ?? newLikesCount,
});
const token = Cookies.get("token") || "";
if (token && newLiked) {
@@ -92,7 +121,7 @@ export function usePostSocialState(postData: Post) {
);
}
} catch (error: unknown) {
let errorMessage = "خطا در ارتباط با سرور";
let errorMessage = t("errors.serverConnection");
if (error instanceof Error) errorMessage = error.message;
else if (error instanceof AxiosError)
errorMessage = error.response?.data?.message ?? error.message;
@@ -109,6 +138,7 @@ export function usePostSocialState(postData: Post) {
likesCountState,
request,
postType,
t,
]);
const toggleSave = useCallback(async () => {
@@ -128,13 +158,18 @@ export function usePostSocialState(postData: Post) {
{ noToast: true }
);
setSavesCount(response?.savesCount ?? newCount);
setSaved(response?.is_saved ?? newSaved);
const resolvedSaved = coerceBool(response?.is_saved ?? newSaved);
setSaved(resolvedSaved);
updateReelsSeedPostEngagement(String(postId), {
is_saved: resolvedSaved,
savesCount: response?.savesCount ?? newCount,
});
} catch (error: unknown) {
toast.error("خطا در ذخیره پست");
toast.error(t("posts.bookmarkError"));
setSaved(!newSaved);
setSavesCount(savesCount);
}
}, [requireAuth, postId, loading, saved, savesCount, request]);
}, [requireAuth, postId, loading, saved, savesCount, request, t]);
const toggleFollow = useCallback(async () => {
if (!requireAuth()) return;
@@ -151,12 +186,14 @@ export function usePostSocialState(postData: Post) {
{ noToast: true }
);
setFollowing(response?.is_following ?? newFollowing);
toast.success(newFollowing ? "فالو شد" : "آنفالو شد");
toast.success(
newFollowing ? t("posts.followed") : t("stories.unfollowed")
);
} catch {
toast.error("خطا در فالو");
toast.error(t("stories.followError"));
setFollowing(!newFollowing);
}
}, [requireAuth, user_id, isOwnPost, loading, following, request]);
}, [requireAuth, user_id, isOwnPost, loading, following, request, t]);
const trackShare = useCallback(() => {
const token = Cookies.get("token") || "";
@@ -203,22 +240,25 @@ export const POST_SOCIAL_ICONS = {
? "drop-shadow-lg"
: size === "sm"
? "dark:invert drop-shadow-lg"
: "invert drop-shadow-lg",
: "invert brightness-125 drop-shadow-lg",
}),
comment: (size: PostSocialIconSize) => ({
src: "/images/icons/message-text.svg",
w: size === "sm" ? 20 : 28,
className: size === "sm" ? "dark:invert" : "invert drop-shadow-lg",
className:
size === "sm" ? "dark:invert" : "invert brightness-125 drop-shadow-lg",
}),
share: (size: PostSocialIconSize) => ({
src: "/images/icons/share.svg",
w: size === "sm" ? 20 : 28,
className: size === "sm" ? "dark:invert" : "invert drop-shadow-lg",
className:
size === "sm" ? "dark:invert" : "invert brightness-125 drop-shadow-lg",
}),
send: (size: PostSocialIconSize) => ({
src: "/images/icons/send-post.svg",
w: size === "sm" ? 20 : 28,
className: size === "sm" ? "dark:invert" : "invert drop-shadow-lg",
className:
size === "sm" ? "dark:invert" : "invert brightness-125 drop-shadow-lg",
}),
save: (saved: boolean, size: PostSocialIconSize) => ({
src: "/images/icons/bookmark-post.svg",
@@ -227,7 +267,7 @@ export const POST_SOCIAL_ICONS = {
? "drop-shadow-lg"
: size === "sm"
? "dark:invert"
: "invert drop-shadow-lg",
: "invert brightness-125 drop-shadow-lg",
}),
follow: (following: boolean, size: PostSocialIconSize) => ({
src: "/images/icons/follow-user.svg",
@@ -236,12 +276,13 @@ export const POST_SOCIAL_ICONS = {
? "opacity-60 drop-shadow-lg"
: size === "sm"
? "dark:invert"
: "invert drop-shadow-lg",
: "invert brightness-125 drop-shadow-lg",
}),
collaboration: (size: PostSocialIconSize) => ({
src: "/images/icons/collaboration-request.svg",
w: size === "sm" ? 20 : 28,
className: size === "sm" ? "dark:invert" : "invert drop-shadow-lg",
className:
size === "sm" ? "dark:invert" : "invert brightness-125 drop-shadow-lg",
}),
} as const;