From 111e8ecd468927500c689800323dc3283063ca2f Mon Sep 17 00:00:00 2001 From: jadapema Date: Fri, 31 Jan 2025 16:45:56 -0600 Subject: [PATCH 1/3] feat: added alert on profile to notify when a user has content and the subscription policy is not set, also added the condition to hide the join button on movie details --- src/components/subscribe-to-unlock-card.tsx | 45 +++++++++++-------- .../view/publication-details-view.tsx | 45 ++++++++++--------- src/sections/user/view/user-profile-view.tsx | 20 +++++++++ 3 files changed, 71 insertions(+), 39 deletions(-) diff --git a/src/components/subscribe-to-unlock-card.tsx b/src/components/subscribe-to-unlock-card.tsx index 2ed40875..33811e41 100644 --- a/src/components/subscribe-to-unlock-card.tsx +++ b/src/components/subscribe-to-unlock-card.tsx @@ -5,6 +5,7 @@ import { useGetPolicyTerms } from '@src/hooks/use-get-policy-terms.ts'; import { Address } from 'viem'; import LoadingButton from '@mui/lab/LoadingButton'; import { GLOBAL_CONSTANTS } from '@src/config-global.ts'; +import { useIsPolicyAuthorized } from '@src/hooks/use-is-policy-authorized.ts'; interface Props { post: any; @@ -18,10 +19,12 @@ export const SubscribeToUnlockCard = ({ loadingSubscribe, post, }: Props) => { + const ownerAddress = post?.by?.ownedBy?.address as Address const { terms } = useGetPolicyTerms( GLOBAL_CONSTANTS.SUBSCRIPTION_POLICY_ADDRESS as Address, - post?.by?.ownedBy?.address as Address + ownerAddress ); + const { isAuthorized } = useIsPolicyAuthorized(GLOBAL_CONSTANTS.SUBSCRIPTION_POLICY_ADDRESS, ownerAddress); const durationDays = 30; // a month const totalCostWei = terms?.amount ? terms?.amount * BigInt(durationDays) : 0; // Calculate total cost in Wei: DAILY_COST_WEI * durationDays const totalCostMMC = ethers.formatUnits(totalCostWei, 18); // Converts Wei to MMC @@ -50,24 +53,28 @@ export const SubscribeToUnlockCard = ({ This content is exclusively for members. Become part of our growing community to access behind-the-scenes content, exclusive posts, and much more! - - - Join - - - - Join now for just {totalCostMMC} MMC/month and access to{' '} - {post?.by?.stats?.posts} exclusive posts from{' '} - {post?.by?.metadata?.displayName ?? post?.handle?.localName}! - - + {isAuthorized && ( + <> + + + Join + + + + Join now for just {totalCostMMC} MMC/month and access to{' '} + {post?.by?.stats?.posts} exclusive posts from{' '} + {post?.by?.metadata?.displayName ?? post?.handle?.localName}! + + + + )} ); diff --git a/src/sections/publication/view/publication-details-view.tsx b/src/sections/publication/view/publication-details-view.tsx index df918bb7..b1599758 100644 --- a/src/sections/publication/view/publication-details-view.tsx +++ b/src/sections/publication/view/publication-details-view.tsx @@ -33,6 +33,8 @@ import LoadingButton from '@mui/lab/LoadingButton'; import { useDispatch, useSelector } from 'react-redux'; import { openLoginModal } from '@redux/auth'; import { appId, PublicationType, usePublications } from '@lens-protocol/react-web'; +import { useIsPolicyAuthorized } from '@src/hooks/use-is-policy-authorized.ts'; +import { GLOBAL_CONSTANTS } from '@src/config-global.ts'; const MAX_LINES = 5; @@ -68,6 +70,7 @@ export default function PublicationDetailsView({ id }: Props) { fetching: accessFetchingLoading, refetch: refetchAccess, } = useHasAccess(ownerAddress); + const { isAuthorized } = useIsPolicyAuthorized(GLOBAL_CONSTANTS.SUBSCRIPTION_POLICY_ADDRESS, ownerAddress); const getMediaUri = (cid: string): string => `${cid}`; @@ -223,26 +226,28 @@ export default function PublicationDetailsView({ id }: Props) { }} /> - - - - Join - - + {isAuthorized && ( + + + + Join + + + )} )} diff --git a/src/sections/user/view/user-profile-view.tsx b/src/sections/user/view/user-profile-view.tsx index ac857b72..9bf94c91 100644 --- a/src/sections/user/view/user-profile-view.tsx +++ b/src/sections/user/view/user-profile-view.tsx @@ -22,6 +22,10 @@ import { RootState } from '@src/redux/store'; import { setFollowers, setFollowings } from '@redux/followers'; import ProfileReferrals from "@src/sections/user/profile-referrals.tsx"; import useReferrals from "@src/hooks/use-referrals.ts"; +import Alert from '@mui/material/Alert'; +import { useIsPolicyAuthorized } from '@src/hooks/use-is-policy-authorized.ts'; +import { GLOBAL_CONSTANTS } from '@src/config-global.ts'; +import { Address } from 'viem'; // ---------------------------------------------------------------------- @@ -47,6 +51,10 @@ const UserProfileView = ({ id }: any) => { metadata: { publishedOn: [appId('watchit')] }, }, }); + const { isAuthorized, loading: authorizedLoading } = useIsPolicyAuthorized( + GLOBAL_CONSTANTS.SUBSCRIPTION_POLICY_ADDRESS, + profile?.ownedBy?.address as Address + ); const { invitations: referrals, fetchInvitations, loading: loadingReferrals } = useReferrals(); @@ -115,8 +123,20 @@ const UserProfileView = ({ id }: any) => { ); + const showSubscriptionAlert = + sessionData?.authenticated && + sessionData?.profile?.id === profile?.id && + (publications?.length ?? 0) >= 1 && + !isAuthorized && + !authorizedLoading; + return ( + {showSubscriptionAlert && ( + + Set your subscription prices so users can access your content. Click 'Set Joining Prices' next to your profile picture. + + )} Date: Sun, 2 Feb 2025 09:44:38 -0600 Subject: [PATCH 2/3] fix: transfer modal, send button disabled --- .../finance-quick-transfer-modal.tsx | 77 +++++++++++-------- 1 file changed, 46 insertions(+), 31 deletions(-) diff --git a/src/sections/finance/components/finance-quick-transfer-modal.tsx b/src/sections/finance/components/finance-quick-transfer-modal.tsx index e529b6a8..9b6ea31b 100644 --- a/src/sections/finance/components/finance-quick-transfer-modal.tsx +++ b/src/sections/finance/components/finance-quick-transfer-modal.tsx @@ -59,17 +59,18 @@ function FinanceQuickTransferModal({ const { sendNotification } = useNotifications(); const [message, setMessage] = useState(''); - // For transfer button is clicked in some profile + // For the transfer button when using user input const MAX_AMOUNT = useSelector((state: any) => state.auth.balance); const [value, setValue] = useState(0); const [canContinue, setCanContinue] = useState(true); - // Check if we have a valid profile or not + // Check if we have a valid profile const hasProfile = !!contactInfo; // Check if the passed address matches the profile's address const isSame = - hasProfile && contactInfo?.ownedBy?.address?.toLowerCase() === address?.toLowerCase(); + hasProfile && + contactInfo?.ownedBy?.address?.toLowerCase() === address?.toLowerCase(); // If no valid profile, show "Destination wallet", else use profile’s displayName const displayName = hasProfile @@ -107,9 +108,14 @@ function FinanceQuickTransferModal({ } } + // Define the transfer amount: if a positive 'amount' is passed, use it; otherwise, use the entered value + const transferAmount = amount > 0 ? amount : value; + // Validation: if 'amount' is passed, assume it's valid; otherwise, ensure that the value is greater than 0 and input validation (canContinue) passes. + const isTransferValid = transferAmount > 0 && (amount > 0 || canContinue); + const handleConfirmTransfer = async () => { try { - await transfer({ amount: amount > 0 ? amount: value, recipient: address ?? '' }); + await transfer({ amount: transferAmount, recipient: address ?? '' }); onFinish(); @@ -120,24 +126,26 @@ function FinanceQuickTransferModal({ 'TRANSFER', { id: isSame ? (contactInfo?.id ?? '') : (address ?? ''), - displayName: isSame ? (contactInfo?.metadata?.displayName ?? 'No name') : 'External wallet', + displayName: isSame + ? (contactInfo?.metadata?.displayName ?? 'No name') + : 'External wallet', avatar: (contactInfo?.metadata?.picture as any)?.optimized?.uri ?? '', }, { - rawDescription: `${sessionData?.profile?.metadata?.displayName ?? address} sent you ${amount} MMC`, + rawDescription: `${sessionData?.profile?.metadata?.displayName ?? address} sent you ${transferAmount} MMC`, message, } ); - // Store transaction in supabase + // Store transaction in Supabase await storeTransactionInSupabase(contactInfo?.id ?? address, senderId, { address: contactInfo?.ownedBy?.address ?? address, - amount: amount > 0 ? amount : value, + amount: transferAmount, message, ...notificationPayload, }); - // Send notification to lens profile or address + // Send notification to the Lens profile or address await sendNotification( contactInfo?.id ?? address ?? '', sessionData?.profile?.id, @@ -145,32 +153,38 @@ function FinanceQuickTransferModal({ ); notifySuccess(SUCCESS.TRANSFER_CREATED_SUCCESSFULLY, { - destination: isSame ? contactInfo?.metadata?.displayName : truncateAddress(address ?? ''), + destination: isSame + ? contactInfo?.metadata?.displayName + : truncateAddress(address ?? ''), }); } catch (err: any) { notifyError(ERRORS.TRANSFER_FAILED_ERROR); } }; - const handleChangeInput = useCallback((event: React.ChangeEvent) => { - const value = Number(event.target.value); - handleAmountConstraints({value, MAX_AMOUNT, MAX_POOL, setAmount: setValue, setCanContinue}); - }, [MAX_AMOUNT]); - + const handleChangeInput = useCallback( + (event: React.ChangeEvent) => { + const value = Number(event.target.value); + handleAmountConstraints({ value, MAX_AMOUNT, MAX_POOL, setAmount: setValue, setCanContinue }); + }, + [MAX_AMOUNT] + ); const handleBlur = useCallback(() => { - handleAmountConstraints({value, MAX_AMOUNT, MAX_POOL, setAmount: setValue, setCanContinue}); + handleAmountConstraints({ value, MAX_AMOUNT, MAX_POOL, setAmount: setValue, setCanContinue }); }, [value, MAX_AMOUNT]); const RainbowEffect = transferLoading ? NeonPaper : Box; return ( - + Send to @@ -190,19 +204,20 @@ function FinanceQuickTransferModal({ - {amount > 0 ? ( - + {amount > 0 ? ( - ) : } + ) : ( + + )} @@ -219,7 +234,7 @@ function FinanceQuickTransferModal({ sx={{ borderTop: `dashed 1px ${theme.palette.divider}`, padding: '16px 24px', - marginTop: '24px' + marginTop: '24px', }} > @@ -236,7 +251,7 @@ function FinanceQuickTransferModal({ variant="contained" sx={{ backgroundColor: '#fff' }} onClick={handleConfirmTransfer} - disabled={transferLoading || !canContinue || value <= 0} + disabled={transferLoading || !isTransferValid} loading={transferLoading} > Confirm From 37abe068c3364875f7e3d46ca54eed61d6db57db Mon Sep 17 00:00:00 2001 From: jadapema Date: Sun, 2 Feb 2025 10:34:28 -0600 Subject: [PATCH 3/3] fix: search and select profile on transfer --- .../components/finance-display-profile-info.tsx | 2 +- .../components/finance-quick-transfer-modal.tsx | 2 +- .../finance/components/finance-quick-transfer.tsx | 11 ++++------- src/utils/wallet.ts | 2 ++ 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/sections/finance/components/finance-display-profile-info.tsx b/src/sections/finance/components/finance-display-profile-info.tsx index 2f802c68..cc0bf658 100644 --- a/src/sections/finance/components/finance-display-profile-info.tsx +++ b/src/sections/finance/components/finance-display-profile-info.tsx @@ -38,7 +38,7 @@ const FinanceDisplayProfileInfo: FC = ({initialList, ca { mode === 'profile' ? ( - {selectedProfile?.metadata?.displayName ?? 'No profile selected'} + {selectedProfile?.metadata?.displayName ?? selectedProfile?.handle?.localName ?? 'No profile selected'} ) : null } { diff --git a/src/sections/finance/components/finance-quick-transfer-modal.tsx b/src/sections/finance/components/finance-quick-transfer-modal.tsx index 9b6ea31b..2b6812e0 100644 --- a/src/sections/finance/components/finance-quick-transfer-modal.tsx +++ b/src/sections/finance/components/finance-quick-transfer-modal.tsx @@ -154,7 +154,7 @@ function FinanceQuickTransferModal({ notifySuccess(SUCCESS.TRANSFER_CREATED_SUCCESSFULLY, { destination: isSame - ? contactInfo?.metadata?.displayName + ? contactInfo?.metadata?.displayName ?? contactInfo?.handle?.localName : truncateAddress(address ?? ''), }); } catch (err: any) { diff --git a/src/sections/finance/components/finance-quick-transfer.tsx b/src/sections/finance/components/finance-quick-transfer.tsx index 0ed63538..60d7753f 100644 --- a/src/sections/finance/components/finance-quick-transfer.tsx +++ b/src/sections/finance/components/finance-quick-transfer.tsx @@ -103,6 +103,7 @@ export default function FinanceQuickTransfer({ // 3) Move the carousel right now carousel.setCurrentIndex(finalIndex); + setCurrentIndex(finalIndex); // 4) Update the wallet address & Redux setWalletAddress(profile.ownedBy?.address ?? ''); @@ -254,9 +255,6 @@ export default function FinanceQuickTransfer({ } }, [showRainbow, currentIndex, carousel]); - // We pick the contactInfo to pass to the modal. If currentIndex is -1, there's no matched profile - const contactInfoToPass = currentIndex === -1 ? undefined : getContactInfo; - // Render the carousel of profiles const renderCarousel = ( @@ -374,7 +372,6 @@ export default function FinanceQuickTransfer({ const Wrapper = showRainbow ? NeonPaper : Box; - console.log(list); return ( <> - + {list?.length > 0 ? renderCarousel : } - + {renderInput} @@ -417,7 +414,7 @@ export default function FinanceQuickTransfer({ address={walletAddress} onClose={confirm.onFalse} onFinish={handleTransferFinish} - contactInfo={contactInfoToPass} // If currentIndex is -1, this is undefined + contactInfo={getContactInfo} onChange={handleChangeInput} /> diff --git a/src/utils/wallet.ts b/src/utils/wallet.ts index 6f6455fd..933dedbb 100644 --- a/src/utils/wallet.ts +++ b/src/utils/wallet.ts @@ -2,6 +2,8 @@ // ---------------------------------------------------------------------- export const truncateAddress = (text: string, startChars: number = 6, endChars: number = 6) => { + if (!text) return ''; + if (text.length <= startChars + endChars) { return text; }