diff --git a/src/components/Publication.tsx b/src/components/Publication.tsx index ecb4d21..1b0e267 100644 --- a/src/components/Publication.tsx +++ b/src/components/Publication.tsx @@ -4,22 +4,29 @@ import { Text, Dimensions, Image, - TouchableHighlight -} from 'react-native' -import { useContext } from 'react' -import { formatDistanceStrict } from 'date-fns' + TouchableHighlight, +} from "react-native"; +import { useContext } from "react"; +import { formatDistanceStrict } from "date-fns"; import { PublicationStyles, ExtendedPublication, LensContextType, ThemeColors, - ProfileMetadata -} from '../types' -import { returnIpfsPathOrUrl } from '../utils' -import { LensContext } from '../context' -import { CommentIcon, MirrorIcon, CollectIcon, UnfilledHeartIcon, FilledHeartIcon } from './' + ProfileMetadata, +} from "../types"; +import { returnIpfsPathOrUrl } from "../utils"; +import { LensContext } from "../context"; +import { + CommentIcon, + MirrorIcon, + CollectIcon, + UnfilledHeartIcon, + FilledHeartIcon, +} from "./"; +import extractURL from "./extractURL"; -const width = Dimensions.get('window').width +const width = Dimensions.get("window").width; export function Publication({ publication, @@ -29,194 +36,184 @@ export function Publication({ hideMirrors = false, hideCollects = false, iconColor, - onCollectPress = publication => console.log({ publication }), - onCommentPress = publication => console.log({ publication }), - onMirrorPress= publication => console.log({ publication }), - onLikePress = publication => console.log({ publication }), - onProfileImagePress = publication => console.log({ publication }), - styles = baseStyles + onCollectPress = (publication) => console.log({ publication }), + onCommentPress = (publication) => console.log({ publication }), + onMirrorPress = (publication) => console.log({ publication }), + onLikePress = (publication) => console.log({ publication }), + onProfileImagePress = (publication) => console.log({ publication }), + styles = baseStyles, }: { - publication: ExtendedPublication, - signedInUser?: ProfileMetadata, - hideLikes?: boolean, - hideComments?: boolean, - hideMirrors?: boolean, - hideCollects?: boolean, - iconColor?: string, - onCollectPress?: (publication: ExtendedPublication) => void, - onCommentPress?:(publication: ExtendedPublication) => void, - onMirrorPress?: (publication: ExtendedPublication) => void, - onLikePress?: (publication: ExtendedPublication) => void, - onProfileImagePress?: (publication: ExtendedPublication) => void, - styles?: PublicationStyles + publication: ExtendedPublication; + signedInUser?: ProfileMetadata; + hideLikes?: boolean; + hideComments?: boolean; + hideMirrors?: boolean; + hideCollects?: boolean; + iconColor?: string; + onCollectPress?: (publication: ExtendedPublication) => void; + onCommentPress?: (publication: ExtendedPublication) => void; + onMirrorPress?: (publication: ExtendedPublication) => void; + onLikePress?: (publication: ExtendedPublication) => void; + onProfileImagePress?: (publication: ExtendedPublication) => void; + styles?: PublicationStyles; }) { - const { theme, IPFSGateway } = useContext(LensContext) + const { theme, IPFSGateway } = useContext(LensContext); if (theme) { - if (theme === 'dark') { - styles = darkThemeStyles - iconColor = ThemeColors.lightGray + if (theme === "dark") { + styles = darkThemeStyles; + iconColor = ThemeColors.lightGray; } } return ( - - + + onProfileImagePress(publication)} > - { - publication?.profile?.picture?.__typename === 'NftImage' ? ( + {publication?.profile?.picture?.__typename === "NftImage" ? ( - ) : - publication?.profile?.picture?.__typename !== 'MediaSet' || - publication.profile.missingAvatar ? ( - + ) : publication?.profile?.picture?.__typename !== "MediaSet" || + publication.profile.missingAvatar ? ( + ) : ( - ) - } + )} - { - publication.__typename === 'Mirror' && publication.mirrorOf && ( - - - Mirrored by {publication?.originalProfile?.name} - - ) - } + {publication.__typename === "Mirror" && publication.mirrorOf && ( + + + + Mirrored by {publication?.originalProfile?.name} + + + )} {publication.profile.name} - @{publication.profile.handle} - • {reduceDate(publication.createdAt)} + + @{publication.profile.handle} + + + • {reduceDate(publication.createdAt)} + - { - publication.metadata.content && ( - {publication.metadata.content} - ) - } - { - Number(publication.metadata.media.length) > 0 && ( - - ) - } - { - publication.stats && ( - - { - !hideComments && ( - - onCommentPress(publication)} - color={iconColor} - /> - {publication.stats.totalAmountOfComments} - - ) - } - { - !hideMirrors && ( - - onMirrorPress(publication)} - color={iconColor} - /> - {publication.stats.totalAmountOfMirrors} - - ) - } - { - !hideCollects && ( - - onCollectPress(publication)} - color={iconColor} - /> - {publication.stats.totalAmountOfCollects} - - ) - } - { - !signedInUser && !hideLikes && ( - - onLikePress(publication)} - color={iconColor} - /> - {publication.stats.totalUpvotes} - - ) - } - { - signedInUser && !hideLikes && ( - - onLikePress(publication)} - color={iconColor} - /> - {publication.stats.totalUpvotes} - - ) - } - - ) - } + {publication.metadata.content && ( + + {extractURL(publication.metadata.content)} + + )} + {Number(publication.metadata.media.length) > 0 && ( + + )} + {publication.stats && ( + + {!hideComments && ( + + onCommentPress(publication)} + color={iconColor} + /> + + {publication.stats.totalAmountOfComments} + + + )} + {!hideMirrors && ( + + onMirrorPress(publication)} + color={iconColor} + /> + + {publication.stats.totalAmountOfMirrors} + + + )} + {!hideCollects && ( + + onCollectPress(publication)} + color={iconColor} + /> + + {publication.stats.totalAmountOfCollects} + + + )} + {!signedInUser && !hideLikes && ( + + onLikePress(publication)} + color={iconColor} + /> + + {publication.stats.totalUpvotes} + + + )} + {signedInUser && !hideLikes && ( + + onLikePress(publication)} + color={iconColor} + /> + + {publication.stats.totalUpvotes} + + + )} + + )} - ) + ); } function reduceDate(date: any) { - const formattedDate = formatDistanceStrict(new Date(date), new Date()) - const dateArr = formattedDate.split(' ') - const dateInfo = dateArr[1].charAt(0) - return `${dateArr[0]}${dateInfo}` + const formattedDate = formatDistanceStrict(new Date(date), new Date()); + const dateArr = formattedDate.split(" "); + const dateInfo = dateArr[1].charAt(0); + return `${dateArr[0]}${dateInfo}`; } const baseStyles = StyleSheet.create({ publicationWrapper: { borderBottomWidth: 1, - borderBottomColor: 'rgba(0, 0, 0, .05)', - padding: 20 + borderBottomColor: "rgba(0, 0, 0, .05)", + padding: 20, }, publicationContainer: { - flexDirection: 'row', - }, - userProfileContainer: { + flexDirection: "row", }, + userProfileContainer: {}, missingAvatarPlaceholder: { width: 40, height: 40, borderRadius: 20, - backgroundColor: 'rgba(0, 0, 0, .4)' + backgroundColor: "rgba(0, 0, 0, .4)", }, smallAvatar: { width: 40, @@ -225,12 +222,12 @@ const baseStyles = StyleSheet.create({ }, postContentContainer: { flexShrink: 1, - paddingLeft: 15 + paddingLeft: 15, }, postText: { flexShrink: 1, marginTop: 7, - marginBottom: 5 + marginBottom: 5, }, metadataImage: { marginTop: 10, @@ -240,68 +237,67 @@ const baseStyles = StyleSheet.create({ }, statsContainer: { marginTop: 20, - flexDirection: 'row', + flexDirection: "row", }, statsDetailContainer: { - flexDirection: 'row', + flexDirection: "row", marginRight: 20, - alignItems: 'center' + alignItems: "center", }, statsDetailText: { marginLeft: 10, - fontSize: 12 + fontSize: 12, }, postOwnerDetailsContainer: { - flexDirection: 'row', - alignItems: 'center' + flexDirection: "row", + alignItems: "center", }, postOwnerName: { - fontWeight: '600' + fontWeight: "600", }, postOwnerHandle: { marginLeft: 4, - color: 'rgba(0, 0, 0, .5)' + color: "rgba(0, 0, 0, .5)", }, timestamp: { marginLeft: 4, - color: 'rgba(0, 0, 0, .5)', + color: "rgba(0, 0, 0, .5)", fontSize: 12, - fontWeight: '600' + fontWeight: "600", }, activityIndicatorContainer: { height: 60, - justifyContent: 'center', + justifyContent: "center", marginBottom: 10, }, mirrorContainer: { - flexDirection: 'row' + flexDirection: "row", }, mirrorText: { - fontWeight: '600', - color: 'rgba(0, 0, 0, .6)', + fontWeight: "600", + color: "rgba(0, 0, 0, .6)", fontSize: 12, marginBottom: 7, - marginLeft: 5 - } -}) + marginLeft: 5, + }, +}); const darkThemeStyles = StyleSheet.create({ publicationWrapper: { borderBottomWidth: 1, padding: 20, backgroundColor: ThemeColors.black, - borderBottomColor: ThemeColors.clearWhite + borderBottomColor: ThemeColors.clearWhite, }, publicationContainer: { - flexDirection: 'row', - }, - userProfileContainer: { + flexDirection: "row", }, + userProfileContainer: {}, missingAvatarPlaceholder: { width: 40, height: 40, borderRadius: 20, - backgroundColor: 'rgba(0, 0, 0, .4)' + backgroundColor: "rgba(0, 0, 0, .4)", }, smallAvatar: { width: 40, @@ -310,13 +306,13 @@ const darkThemeStyles = StyleSheet.create({ }, postContentContainer: { flexShrink: 1, - paddingLeft: 15 + paddingLeft: 15, }, postText: { flexShrink: 1, marginTop: 7, marginBottom: 5, - color: ThemeColors.white + color: ThemeColors.white, }, metadataImage: { marginTop: 10, @@ -326,50 +322,50 @@ const darkThemeStyles = StyleSheet.create({ }, statsContainer: { marginTop: 20, - flexDirection: 'row', + flexDirection: "row", paddingLeft: 20, }, statsDetailContainer: { - flexDirection: 'row', + flexDirection: "row", marginRight: 20, - alignItems: 'center' + alignItems: "center", }, statsDetailText: { marginLeft: 10, fontSize: 12, - color: ThemeColors.white + color: ThemeColors.white, }, postOwnerDetailsContainer: { - flexDirection: 'row', - alignItems: 'center' + flexDirection: "row", + alignItems: "center", }, postOwnerName: { - fontWeight: '600', - color: ThemeColors.white + fontWeight: "600", + color: ThemeColors.white, }, postOwnerHandle: { marginLeft: 4, - color: ThemeColors.lightGray + color: ThemeColors.lightGray, }, timestamp: { marginLeft: 4, fontSize: 12, - fontWeight: '600', - color: ThemeColors.lightGray + fontWeight: "600", + color: ThemeColors.lightGray, }, activityIndicatorContainer: { height: 60, - justifyContent: 'center', + justifyContent: "center", marginBottom: 10, }, mirrorContainer: { - flexDirection: 'row' + flexDirection: "row", }, mirrorText: { - fontWeight: '600', + fontWeight: "600", fontSize: 12, marginBottom: 7, marginLeft: 5, - color: ThemeColors.lightGray - } -}) \ No newline at end of file + color: ThemeColors.lightGray, + }, +}); diff --git a/src/components/extractURL.tsx b/src/components/extractURL.tsx new file mode 100644 index 0000000..21d3993 --- /dev/null +++ b/src/components/extractURL.tsx @@ -0,0 +1,26 @@ +import { Linking, Text } from "react-native"; + +const URL_REGEX = /https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/; + +function extractURL(content: string) { + const renderText = (content: string) => + content?.split(" ").map((part, index) => + URL_REGEX.test(part) ? ( + Linking.openURL(part)} + > + {part + " "} + + ) : ( + part + " " + ) + ); + + return renderText(content); +} + +export default extractURL;