Skip to content
Merged

Next #730

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
71 commits
Select commit Hold shift + click to select a range
a77336c
Add snapshot tests for FinanceDepositFromMetamask component
May 5, 2025
8ca8a2a
Update snapshot for FinanceDepositFromMetamask component and add load…
May 5, 2025
848450e
test(FinanceDepositFromMetamask ) : Refactor component to improve rea…
May 5, 2025
e89d7ce
test(FinanceDepositFromMetamask): Enhance tests for account connectio…
May 5, 2025
02a62b7
test(FinanceDepositFromMetamask): Add test for connect button click f…
May 5, 2025
15ca1e4
test(FinanceDepositFromStripe): Add snapshot test for FinanceDepositF…
May 5, 2025
1c4b808
test(FinanceDepositFromStripe): Refactor tests to use renderComponent…
May 5, 2025
de87f06
test(FinanceDepositFromStripe): Update snapshot and add test for Comi…
May 5, 2025
54d49c6
test(FinanceBoxRow): Add tests for rendering, children presence, and …
May 5, 2025
b9cf274
test(FinanceDialogsActions): Add initial test file and snapshot for c…
May 5, 2025
998280e
test(FinanceDialogsActions): Update tests to improve coverage and enh…
May 6, 2025
e7cb02a
test(FinanceDepositFromSmartAccount): Update mock for useAuth to hand…
May 6, 2025
cd8dff3
test(FinanceDepositModal): Add initial test file and snapshot for com…
May 7, 2025
41b935c
test(FinanceDepositModal): Update snapshot and enhance test mocks for…
May 8, 2025
02a6d29
test(FinanceDepositModal): Add test for rendering modal title
May 8, 2025
d1b0d68
test(FinanceDepositModal): Add test for displaying all deposit method…
May 8, 2025
0db48ac
test(FinanceDepositModal): Add test for rendering Metamask content on…
May 8, 2025
a5efcb0
test(FinanceDepositModal): Add test for rendering Smart Account conte…
May 8, 2025
05c6dc1
test(FinanceDepositModal): Add test for closing Metamask tab
May 8, 2025
ce7127c
test(FinanceDepositModal): Add test for closing Smart Account tab
May 8, 2025
b8b0005
Merge branch 'next' of github.com:WatchItDev/watchit-app into next
May 12, 2025
d41dc2b
test: add snapshot test for FinanceDisplayProfileInfo component
May 12, 2025
ee2572f
test: update tests for ExplorePublications to mock new API response
May 12, 2025
a141ff5
test: update ExploreView tests with Apollo Client mocks and remove un…
May 12, 2025
5ade91f
test: enhance ExploreView tests to include authentication mock and ve…
May 12, 2025
f6fe1da
Add snapshot tests for FinanceDepositFromMetamask component
May 5, 2025
a4348ce
Update snapshot for FinanceDepositFromMetamask component and add load…
May 5, 2025
3b8c7d0
test(FinanceDepositFromMetamask ) : Refactor component to improve rea…
May 5, 2025
7e48885
test(FinanceDepositFromMetamask): Enhance tests for account connectio…
May 5, 2025
f846da1
test(FinanceDepositFromMetamask): Add test for connect button click f…
May 5, 2025
29c4ddd
test(FinanceDepositFromStripe): Add snapshot test for FinanceDepositF…
May 5, 2025
b7d9c93
test(FinanceDepositFromStripe): Refactor tests to use renderComponent…
May 5, 2025
1e3e61e
test(FinanceDepositFromStripe): Update snapshot and add test for Comi…
May 5, 2025
26aae36
test(FinanceBoxRow): Add tests for rendering, children presence, and …
May 5, 2025
40bc0d8
test(FinanceDialogsActions): Add initial test file and snapshot for c…
May 5, 2025
f731f50
test(FinanceDialogsActions): Update tests to improve coverage and enh…
May 6, 2025
e87f6f1
test(FinanceDepositFromSmartAccount): Update mock for useAuth to hand…
May 6, 2025
0caff63
test(FinanceDepositModal): Add initial test file and snapshot for com…
May 7, 2025
2ad9029
test(FinanceDepositModal): Update snapshot and enhance test mocks for…
May 8, 2025
1804f3f
test(FinanceDepositModal): Add test for rendering modal title
May 8, 2025
1d00eb2
test(FinanceDepositModal): Add test for displaying all deposit method…
May 8, 2025
bacc715
test(FinanceDepositModal): Add test for rendering Metamask content on…
May 8, 2025
33d00ab
test(FinanceDepositModal): Add test for rendering Smart Account conte…
May 8, 2025
cd665d2
test(FinanceDepositModal): Add test for closing Metamask tab
May 8, 2025
4e9a519
test(FinanceDepositModal): Add test for closing Smart Account tab
May 8, 2025
a5f3968
test: add snapshot test for FinanceDisplayProfileInfo component
May 12, 2025
852c35b
test: update tests for ExplorePublications to mock new API response
May 12, 2025
b89fe2d
test: update ExploreView tests with Apollo Client mocks and remove un…
May 12, 2025
a38e6a2
test: enhance ExploreView tests to include authentication mock and ve…
May 12, 2025
53f3e2e
test: update ExploreView tests to include recent posts mock and enhan…
May 19, 2025
9b2bbbf
Merge branch 'refactor/tests-api-migration' of github.com:WatchItDev/…
May 19, 2025
6a20037
test: update ExploreView tests and snapshots for improved accuracy an…
May 19, 2025
409f534
test: update ExploreView mocks and snapshots to include recent posts …
May 19, 2025
6aa00c8
test: update ExploreBookmarks tests to use MockedProvider and improve…
May 19, 2025
aa05369
test: update ExploreTopPublications tests to use MockedProvider and e…
May 19, 2025
c3c269f
test: enhance ExploreTopPublications tests with new mock data and imp…
May 20, 2025
acc1a6c
test: update ExploreTopPublications tests for improved snapshot match…
May 20, 2025
15b43f0
test: update describe block for ExploreTopPublications tests to impro…
May 20, 2025
4e37a9a
test: update ExploreCreators tests with new mock data and improve sna…
May 21, 2025
0b23ce7
test: refactor ExploreCreators tests to improve clarity and accuracy …
May 22, 2025
6c2bb24
test: restore hidden creators and loading state tests in ExploreCreat…
May 22, 2025
661e30a
test: add mock data for GetRecentPostsDocument in explorePublications…
May 22, 2025
a5753b3
feat: delete redux (WIP)
Jadapema May 22, 2025
ddd95f9
feat: remove unused redux
Jadapema May 23, 2025
dd072d9
feat: added support box and terms and conditions
Jadapema May 23, 2025
7d9e2ac
fix: unauthenticated error after login
Jadapema May 24, 2025
d21d0f3
feat: added skeletons
Jadapema May 25, 2025
462a3c5
fix: sonarcloud
Jadapema May 26, 2025
d5d35dc
fix: sonarcloud
Jadapema May 26, 2025
f515e06
Merge pull request #729 from WatchItDev/app/fix/redux
geolffreym May 26, 2025
70bc6fb
Merge pull request #728 from WatchItDev/refactor/tests-api-migration
Jadapema May 26, 2025
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
79 changes: 79 additions & 0 deletions src/components/LoadingFade.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import {
ReactNode,
useLayoutEffect,
useRef,
useState,
} from 'react';
import { AnimatePresence, m } from 'framer-motion';

export interface LoadingFadeProps {
loading: boolean;
skeleton: ReactNode;
children: ReactNode;
durationMs?: number; // fade (default 300 ms)
delayMs?: number; // delay before fade starts (default 0 ms)
}

export const LoadingFade = ({
loading,
skeleton,
children,
durationMs = 300,
delayMs = 0,
}: LoadingFadeProps) => {
const durationSec = durationMs / 1000;
const delaySec = delayMs / 1000;

const skelRef = useRef<HTMLDivElement>(null);
const [minHeight, setMinHeight] = useState<number>();
const [overlaySkeleton, setOverlaySkeleton] = useState(false);

useLayoutEffect(() => {
if (loading && skelRef.current && minHeight === undefined) {
const h = skelRef.current.getBoundingClientRect().height;
if (h) {
setMinHeight(h);
setOverlaySkeleton(true);
}
}
}, [loading, minHeight]);

const handleSkeletonExit = () => {
setMinHeight(undefined);
setOverlaySkeleton(false);
};

return (
<div style={{ position: 'relative', width: '100%', minHeight }}>
<AnimatePresence onExitComplete={handleSkeletonExit}>
{loading && (
<m.div
key="skeleton"
ref={skelRef}
initial={{ opacity: 1 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: durationSec, delay: delaySec }}
style={{
position: overlaySkeleton ? 'absolute' : 'static',
inset: overlaySkeleton ? 0 : 'unset',
width: '100%',
pointerEvents: 'none',
}}
>
{skeleton}
</m.div>
)}
</AnimatePresence>

<m.div
initial={{ opacity: 0 }}
animate={{ opacity: loading ? 0 : 1 }}
transition={{ duration: durationSec, delay: delaySec }}
style={{ width: '100%' }}
>
{children}
</m.div>
</div>
);
};
8 changes: 3 additions & 5 deletions src/components/carousel/variants/carousel-top-titles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,13 @@ export default function CarouselTopTitles({ posts, category }: Readonly<Carousel
alignItems: 'stretch',
},
'.slick-slide': {
height: 'auto',
height: 'fit-content',
},
'.slick-list': {
height: 'auto',
},
'.slick-slide > div': {
height: '100%',
minHeight: '100%',
maxHeight: '100%',
height: 'auto',
},
}}
>
Expand All @@ -47,7 +45,7 @@ export default function CarouselTopTitles({ posts, category }: Readonly<Carousel
>
<Carousel ref={carousel.carouselRef} {...carousel.carouselSettings}>
{posts.map((post: Post) => (
<Box key={`${category}-${post.id}`} sx={{ px: 0.75 }}>
<Box key={`${category}-${post.id}`} sx={{ px: 0.75, height: '100%' }}>
<PosterTopTitles post={post} />
</Box>
))}
Expand Down
10 changes: 3 additions & 7 deletions src/components/follow-unfollow-button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
// REDUX IMPORTS
import { openLoginModal } from '@redux/auth';
import { useDispatch } from 'react-redux';
import { addFollower, removeFollower } from '@redux/followers';

// LOCAL IMPORTS
import Box from '@mui/material/Box';
Expand All @@ -31,6 +30,7 @@

interface FollowUnfollowButtonProps {
profileId: string;
onActionFinish?: () => void;
followButtonMinWidth?: number;
size?: 'small' | 'medium' | 'large';
}
Expand All @@ -41,6 +41,7 @@
profileId,
size = 'medium',
followButtonMinWidth = 120,
onActionFinish = () => {},

Check failure on line 44 in src/components/follow-unfollow-button.tsx

View workflow job for this annotation

GitHub Actions / Continuous-Integration / Static Analysis and Test | Node 20

Unexpected empty arrow function

Check failure on line 44 in src/components/follow-unfollow-button.tsx

View workflow job for this annotation

GitHub Actions / Static Analysis and Test | Node 20

Unexpected empty arrow function
}: PropsWithChildren<FollowUnfollowButtonProps>) => {
const dispatch = useDispatch();
const [loadProfile, { data: profileData, loading: profileLoading }] = useGetUserLazyQuery();
Expand Down Expand Up @@ -86,12 +87,7 @@

setIsFollowed(result?.data?.toggleFollow);
handleUpdateProfile();

if (result?.data?.toggleFollow) {
dispatch(addFollower(profile));
} else {
dispatch(removeFollower(profileId));
}
onActionFinish();

// Send notification to the profile being followed
const notificationPayload = generatePayload(
Expand Down
4 changes: 2 additions & 2 deletions src/components/poster/variants/poster-top-titles.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const PosterTopTitles = ({ post }: { post: Post }) => {

return (
<Stack
sx={{ position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'center' }}
sx={{ position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100%', overflow: 'hidden' }}
alignItems={'stretch'}
spacing={{ xs: 1, sm: 2, md: 4 }}
>
Expand All @@ -47,7 +47,7 @@ const PosterTopTitles = ({ post }: { post: Post }) => {
top: 0,
left: 0,
width: '100%',
height: '100%',
height: '99%',
opacity: 0.2,
filter: "blur(5px) !important",
backgroundSize: 'cover',
Expand Down
84 changes: 38 additions & 46 deletions src/components/publication-detail-main/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import { SubscribeToUnlockCard } from '@src/components/subscribe-to-unlock-card/
import Popover from '@mui/material/Popover';
import { useNotifications } from '@src/hooks/use-notifications.ts';
import { openLoginModal } from '@redux/auth';
import { useDispatch, useSelector } from 'react-redux';
import { useDispatch } from 'react-redux';
import { useNotificationPayload } from '@src/hooks/use-notification-payload.ts';
import AvatarProfile from "@src/components/avatar/avatar.tsx";
import { PublicationDetailProps } from '@src/components/publication-detail-main/types.ts';
Expand All @@ -56,8 +56,6 @@ import {
} from '@src/graphql/generated/hooks.tsx';
import { resolveSrc } from '@src/utils/image.ts';
import { useBookmarks } from '@src/hooks/use-bookmark.ts';
import { RootState } from '@redux/store.ts';
import { decrementCounterLikes, incrementCounterLikes, setCounterLikes } from '@redux/comments';

// ----------------------------------------------------------------------

Expand All @@ -73,8 +71,8 @@ export default function PublicationDetailMain({
const [openConfirmModal, setOpenConfirmModal] = useState(false);
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const [hasLiked, setHasLiked] = useState(false);
const likesCount = useSelector((s: RootState) => s.comments.counterLikes[post.id] ?? post.likeCount);
const counters = useSelector((s: RootState) => s.comments.counterLikes);
const [likesCount, setLikesCount] = useState(post.likeCount);
const [commentCount, setCommentCount] = useState(post.commentCount);

const router = useRouter();
const theme = useTheme();
Expand All @@ -83,68 +81,61 @@ export default function PublicationDetailMain({
const [ hidePost ] = useHidePostMutation();
const { sendNotification } = useNotifications();
const { generatePayload } = useNotificationPayload(sessionData);
const [getIsPostLiked, { data: postLikedData, loading: postLikedLoading }] = useGetIsPostLikedLazyQuery()
const [getIsPostLiked, { loading: postLikedLoading }] = useGetIsPostLikedLazyQuery()
const [ togglePostLike, { loading: togglePostLikeLoading } ] = useTogglePostLikeMutation()
const { has, loading: loadingList } = useBookmarks();
const { toggle, loading: loadingToggle } = useToggleBookmark();
const commentCount = useSelector((s: RootState) => s.comments.postCommentCount[post.id] ?? post.commentCount);

const isBookmarked = has(post.id);
const isLoading = togglePostLikeLoading || postLikedLoading
const variants = theme.direction === 'rtl' ? varFade().inLeft : varFade().inRight;
const openMenu = Boolean(anchorEl);

const toggleReaction = async () => {
const handleToggleLike = async () => {
if (!sessionData?.authenticated) return dispatch(openLoginModal());

// Send a notification to the profile owner using the sendNotification function from useNotifications hook
const payloadForNotification = generatePayload(
'LIKE',
{
id: post.author.address,
displayName: post.author.displayName ?? 'Watchit',
avatar: resolveSrc(post.author.profilePicture || post.author.address, 'profile'),
},
{
rawDescription: `${sessionData?.user?.displayName} liked ${post.title}`,
root_id: post.id,
post_title: post.title,
}
);

try {
const res = await togglePostLike({
variables: {
input: {
postId: post.id
}
}
});
const res = await togglePostLike({ variables: { input: { postId: post.id } } });
const isNowLiked = res.data?.togglePostLike ?? false;

const isLiked = res?.data?.togglePostLike ?? false;
setHasLiked(isNowLiked);
setLikesCount((prev) => prev + (isNowLiked ? 1 : -1));

setHasLiked(isLiked);
dispatch(isLiked ? incrementCounterLikes(post.id) : decrementCounterLikes(post.id));
if (isNowLiked) {
// Send a notification to the profile owner using the sendNotification function from useNotifications hook
const payloadForNotification = generatePayload(
'LIKE',
{
id: post.author.address,
displayName: post.author.displayName ?? 'Watchit',
avatar: resolveSrc(post.author.profilePicture || post.author.address, 'profile'),
},
{
rawDescription: `${sessionData?.user?.displayName} liked ${post.title}`,
root_id: post.id,
post_title: post.title,
}
);

// Send notification to the author when not already liked
if (res?.data?.togglePostLike) {
sendNotification(post.author.address, sessionData?.user?.address ?? '', payloadForNotification);
}
} catch (err) {
console.error('Error toggling reaction:', err);
console.error(err);
}
};

useEffect(() => {
setHasLiked(postLikedData?.getIsPostLiked ?? false);
}, [postLikedData]);
const handleCommentSuccess = (wasReply = false) => {
if (!wasReply) {
// Es un comentario raíz → solo incrementamos el counter del post
setCommentCount((c) => (c ?? 0) + 1);
}
};

useEffect(() => {
getIsPostLiked({ variables: { postId: post.id } });
if (post.likeCount !== undefined) {
dispatch(setCounterLikes({ publicationId: post.id, likes: post.likeCount }));
}
}, [post.likeCount, post.id]);
getIsPostLiked({ variables: { postId: post.id } }).then((res) =>
setHasLiked(res.data?.getIsPostLiked ?? false),
);
}, [post.id]);

const handleHide = async () => {
await hidePost({ variables: { postId: post.id } });
Expand Down Expand Up @@ -350,7 +341,7 @@ export default function PublicationDetailMain({
height: '40px',
minWidth: '40px',
}}
onClick={toggleReaction}
onClick={handleToggleLike}
disabled={isLoading}
>
{isLoading ? (
Expand Down Expand Up @@ -444,6 +435,7 @@ export default function PublicationDetailMain({
displayName: post.author.displayName ?? 'Watchit',
avatar: resolveSrc(post.author.profilePicture || post.author.address, 'profile'),
}}
onSuccess={() => handleCommentSuccess(false)}
/>
) : (
<Typography
Expand All @@ -462,7 +454,7 @@ export default function PublicationDetailMain({
)}
</Box>
<Box sx={{ display: 'flex', flexDirection: 'column', mt: 2, pr: 1 }}>
<PostCommentList publicationId={post.id} showReplies />
<PostCommentList publicationId={post.id} showReplies onReplyCreated={() => handleCommentSuccess(true)} />
</Box>
</Box>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export const SubscribeToUnlockCard = ({
size="lg"
/>
)}
{isAuthorized && (
{isJoinButtonVisible && (
<Box sx={{ mt: 3, borderRadius: 1 }}>
<Typography variant="body2" color="textSecondary">
Join now for just <strong>{totalCostMMC} MMC/month</strong> and access to{' '}
Expand Down
9 changes: 9 additions & 0 deletions src/components/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ReactNode } from 'react';

export interface HandleActionErrorProps extends Error{
requestedAmount?: {
asset?: { symbol: string };
Expand All @@ -9,3 +11,10 @@ export interface ActivateSubscriptionProfileModalProps {
isOpen: boolean;
onClose: () => void;
}

export interface LoadingFadeProps {
loading: boolean;
skeleton: ReactNode;
children: ReactNode;
duration?: number;
}
4 changes: 4 additions & 0 deletions src/config-global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export interface GlobalConstants {
ATTESTATION_BASE_URL: string;
FROM_BLOCK: bigint | string | number;
GQL_ENDPOINT: string;
OPEN_COLLECTIVE: string;
TERMS_AND_CONDITIONS: string;
}

export const GLOBAL_CONSTANTS: GlobalConstants = {
Expand Down Expand Up @@ -101,6 +103,8 @@ export const GLOBAL_CONSTANTS: GlobalConstants = {
process.env.VITE_URL_ATTESTATION_BASE || import.meta.env.VITE_URL_ATTESTATION_BASE || "",
FROM_BLOCK: process.env.VITE_BLOCK_FROM || import.meta.env.VITE_BLOCK_FROM || 0n,
GQL_ENDPOINT: process.env.VITE_GQL_ENDPOINT || import.meta.env.VITE_GQL_ENDPOINT || 'http://localhost:4000/graphql',
OPEN_COLLECTIVE: process.env.VITE_URL_OPEN_COLLECTIVE || import.meta.env.VITE_URL_OPEN_COLLECTIVE || '',
TERMS_AND_CONDITIONS: process.env.VITE_URL_TERMS_AND_CONDITIONS || import.meta.env.VITE_URL_TERMS_AND_CONDITIONS || '',
};

export const PATH_AFTER_LOGIN = paths.dashboard.root;
Loading
Loading