-
Notifications
You must be signed in to change notification settings - Fork 298
Expand file tree
/
Copy pathCard.tsx
More file actions
122 lines (105 loc) · 3.61 KB
/
Copy pathCard.tsx
File metadata and controls
122 lines (105 loc) · 3.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import React from 'react';
import { BaseImage } from '../../BaseImage';
import { SafeAnchor } from '../../SafeAnchor';
import { useChannelStateContext } from '../../../context/ChannelStateContext';
import { useComponentContext } from '../../../context';
import type { Attachment } from 'stream-chat';
import type { RenderAttachmentProps } from '../utils';
import type { Dimensions } from '../../../types/types';
import { IconLink as DefaultIconLink } from '../../Icons';
import { UnableToRenderCard } from './UnableToRenderCard';
import clsx from 'clsx';
type CardRootProps = {
cardUrl: string | undefined;
children: React.ReactNode;
type?: CardProps['type'];
};
const CardRoot = ({ cardUrl, children, type }: CardRootProps) => {
const className = clsx(
`str-chat__message-attachment-card str-chat__message-attachment-card--${type}`,
);
return cardUrl ? (
<SafeAnchor
className={className}
href={cardUrl}
rel='noopener noreferrer'
target='_blank'
>
{children}
</SafeAnchor>
) : (
<div className={className}>{children}</div>
);
};
type CardHeaderProps = Pick<CardProps, 'title' | 'type' | 'image_url' | 'thumb_url'> & {
dimensions: Dimensions;
image?: string;
};
const CardHeader = (props: CardHeaderProps) => {
const { dimensions, image, image_url, thumb_url, title } = props;
return image ? (
<div
className='str-chat__message-attachment-card--header str-chat__message-attachment-card-react--header'
data-testid={'card-header'}
>
<BaseImage
alt={title || image}
data-testid='image-test'
src={image_url ?? thumb_url}
title={title || image}
{...dimensions}
/>
</div>
) : null;
};
type CardContentProps = RenderAttachmentProps['attachment'];
const CardContent = (props: CardContentProps) => {
const { og_scrape_url, text, title, title_link } = props;
const url = title_link || og_scrape_url;
const { icons: { IconLink = DefaultIconLink } = {} } = useComponentContext();
return (
<div className='str-chat__message-attachment-card--content'>
{title && <div className='str-chat__message-attachment-card--title'>{title}</div>}
{text && <div className='str-chat__message-attachment-card--text'>{text}</div>}
{url && (
<div
className='str-chat__message-attachment-card--source-link'
data-testid='card-source-link'
>
<IconLink />
<div className='str-chat__message-attachment-card--url'>{url}</div>
</div>
)}
</div>
);
};
export type CardProps = RenderAttachmentProps['attachment'] & {
compact?: boolean;
};
const UnMemoizedCard = (props: CardProps) => {
const { giphy, image_url, og_scrape_url, thumb_url, title, title_link, type } = props;
const { giphyVersion: giphyVersionName } = useChannelStateContext('');
const cardUrl = title_link || og_scrape_url;
let image = thumb_url || image_url;
const dimensions: { height?: string; width?: string } = {};
if (type === 'giphy' && typeof giphy !== 'undefined') {
const giphyVersion =
giphy[giphyVersionName as keyof NonNullable<Attachment['giphy']>];
image = giphyVersion.url;
dimensions.height = giphyVersion.height;
dimensions.width = giphyVersion.width;
}
if (!title && !cardUrl && !image) {
return <UnableToRenderCard />;
}
return (
<CardRoot cardUrl={cardUrl} type={type}>
<CardHeader {...props} dimensions={dimensions} image={image} />
<CardContent {...props} />
</CardRoot>
);
};
/**
* Simple Card Layout for displaying links
*/
export const Card = React.memo(UnMemoizedCard) as typeof UnMemoizedCard;