diff --git a/packages/mobile/src/screens/coin-details-screen/components/TextPostCard.tsx b/packages/mobile/src/screens/coin-details-screen/components/TextPostCard.tsx index 76c9ee6acd0..d8037376ae5 100644 --- a/packages/mobile/src/screens/coin-details-screen/components/TextPostCard.tsx +++ b/packages/mobile/src/screens/coin-details-screen/components/TextPostCard.tsx @@ -1,8 +1,11 @@ import { useComment } from '@audius/common/api' import type { ID } from '@audius/common/models' import { getLargestTimeUnitText } from '@audius/common/utils' +import { View } from 'react-native' +import LinearGradient from 'react-native-linear-gradient' import { + Button, Flex, IconLock, Paper, @@ -14,7 +17,28 @@ import { ProfilePicture } from 'app/components/core' import { UserLink } from 'app/components/user-link' const messages = { - locked: 'Hold this coin to unlock' + unlock: 'Unlock', + membersOnly: 'Members Only' +} + +/** + * Generate a deterministic pseudo-random placeholder string for locked posts + * so each post looks visually distinct behind the blur. + */ +const generatePlaceholder = (commentId: ID) => { + const seed = Number(commentId) + const wordCount = 5 + (seed % 21) // 5–25 words + const words: string[] = [] + const pool = 'abcdefghijklmnopqrstuvwxyz' + for (let i = 0; i < wordCount; i++) { + const len = 3 + ((seed * (i + 1) * 7) % 8) // 3–10 chars per word + let word = '' + for (let j = 0; j < len; j++) { + word += pool[(seed * (i + 1) * (j + 1) * 13) % pool.length] + } + words.push(word) + } + return words.join(' ') } type TextPostCardProps = { @@ -23,7 +47,7 @@ type TextPostCardProps = { export const TextPostCard = ({ commentId }: TextPostCardProps) => { const { data: comment, isPending } = useComment(commentId) - const { color, spacing, cornerRadius } = useTheme() + const { color } = useTheme() if (isPending) { return ( @@ -76,20 +100,35 @@ export const TextPostCard = ({ commentId }: TextPostCardProps) => { {isLocked ? ( - - - - {messages.locked} - + + + + {generatePlaceholder(commentId)} + + + + + + + + + {messages.membersOnly} + + + ) : ( diff --git a/packages/web/src/pages/fan-club-detail-page/components/TextPostCard.tsx b/packages/web/src/pages/fan-club-detail-page/components/TextPostCard.tsx index df545db7db5..d90cad695e2 100644 --- a/packages/web/src/pages/fan-club-detail-page/components/TextPostCard.tsx +++ b/packages/web/src/pages/fan-club-detail-page/components/TextPostCard.tsx @@ -39,8 +39,25 @@ const messages = { edited: '(edited)' } -const LOCKED_PLACEHOLDER_TEXT = - 'This content is exclusively available for coin holders. Purchase coins to unlock access to this post and other exclusive content.' +/** + * Generate a deterministic pseudo-random placeholder string for locked posts + * so each post looks visually distinct behind the blur. + */ +const generatePlaceholder = (commentId: ID) => { + const seed = Number(commentId) + const wordCount = 5 + (seed % 21) // 5–25 words + const words = [] + const pool = 'abcdefghijklmnopqrstuvwxyz' + for (let i = 0; i < wordCount; i++) { + const len = 3 + ((seed * (i + 1) * 7) % 8) // 3–10 chars per word + let word = '' + for (let j = 0; j < len; j++) { + word += pool[(seed * (i + 1) * (j + 1) * 13) % pool.length] + } + words.push(word) + } + return words.join(' ') +} type TextPostCardProps = { commentId: ID @@ -165,7 +182,7 @@ export const TextPostCard = ({ commentId, mint }: TextPostCardProps) => { pointerEvents: 'none' }} > - {LOCKED_PLACEHOLDER_TEXT} + {generatePlaceholder(commentId)}