Skip to content

Commit fae9a13

Browse files
authored
Merge pull request #915 from filecoin-project/@martinalong/edits-to-nft-links
@martinalong/edits to nft links
2 parents eb058d6 + 9adcaf5 commit fae9a13

File tree

1 file changed

+99
-3
lines changed

1 file changed

+99
-3
lines changed

components/core/Link/LinkCard.js

Lines changed: 99 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1+
import * as React from "react";
12
import * as System from "~/components/system";
23
import * as Styles from "~/common/styles";
34
import * as Constants from "~/common/constants";
45
import * as SVG from "~/common/svg";
56

67
import LinkTag from "~/components/core/Link/LinkTag";
78

8-
import { LoaderSpinner } from "~/components/system/components/Loaders";
9+
import { P3 } from "~/components/system/components/Typography";
910
import { css } from "@emotion/react";
1011

1112
const STYLES_CARD = css`
@@ -24,6 +25,11 @@ const STYLES_CARD = css`
2425
}
2526
`;
2627

28+
const STYLES_TAG_CONTAINER = (theme) => css`
29+
color: ${theme.semantic.textGray};
30+
${Styles.HORIZONTAL_CONTAINER_CENTERED}
31+
`;
32+
2733
const STYLES_FREEFORM_CARD = css`
2834
max-height: 90%;
2935
max-width: 90%;
@@ -69,12 +75,75 @@ const STYLES_BODY = css`
6975
max-width: 600px;
7076
`;
7177

78+
const STYLES_LINK = (theme) => css`
79+
display: block;
80+
width: 100%;
81+
${Styles.LINK}
82+
:hover small, .link_external_link {
83+
color: ${theme.semantic.textGrayDark};
84+
}
85+
86+
.link_external_link {
87+
opacity: 0;
88+
transition: opacity 0.3s;
89+
}
90+
:hover .link_external_link {
91+
opacity: 1;
92+
}
93+
`;
94+
95+
const STYLES_SOURCE = css`
96+
transition: color 0.4s;
97+
max-width: 80%;
98+
`;
99+
100+
const STYLES_SOURCE_LOGO = css`
101+
height: 12px;
102+
width: 12px;
103+
border-radius: 4px;
104+
`;
105+
72106
export default function LinkCard({ file, isNFTLink }) {
73107
const url = file.url;
74108
const link = file.data.link;
75109
const { image, name, body } = link;
76110

77111
if (isNFTLink) {
112+
const faviconImgState = useImage({ src: link.logo });
113+
114+
const tag = (
115+
<a
116+
css={STYLES_LINK}
117+
href={file.url}
118+
target="_blank"
119+
rel="noreferrer"
120+
style={{ position: "relative", zIndex: 2 }}
121+
onClick={(e) => e.stopPropagation()}
122+
>
123+
<div css={STYLES_TAG_CONTAINER}>
124+
{faviconImgState.error ? (
125+
<SVG.Link height={12} width={12} style={{ marginRight: 4 }} />
126+
) : (
127+
<img
128+
src={link.logo}
129+
alt="Link source logo"
130+
style={{ marginRight: 4 }}
131+
css={STYLES_SOURCE_LOGO}
132+
/>
133+
)}
134+
<P3 css={STYLES_SOURCE} as="small" color="textGray" nbrOflines={1}>
135+
{link.source}
136+
</P3>
137+
<SVG.ExternalLink
138+
className="link_external_link"
139+
height={12}
140+
width={12}
141+
style={{ marginLeft: 4 }}
142+
/>
143+
</div>
144+
</a>
145+
);
146+
78147
return (
79148
<a
80149
css={Styles.LINK}
@@ -87,15 +156,16 @@ export default function LinkCard({ file, isNFTLink }) {
87156
<div css={STYLES_IMAGE_CONTAINER}>
88157
<img src={image} css={Styles.IMAGE_FILL} style={{ maxHeight: "calc(100vh - 200px)" }} />
89158
</div>
90-
<div css={[Styles.VERTICAL_CONTAINER, STYLES_TEXT_BOX]}>
159+
<div css={[STYLES_TEXT_BOX]}>{tag}</div>
160+
{/* <div css={[Styles.VERTICAL_CONTAINER, STYLES_TEXT_BOX]}>
91161
<div css={STYLES_NAME}>
92162
<System.H3>{name}</System.H3>
93163
</div>
94164
<div css={STYLES_BODY}>
95165
<System.P1>{body}</System.P1>
96166
</div>
97167
<LinkTag url={url} fillWidth={false} style={{ color: Constants.semantic.textGray }} />
98-
</div>
168+
</div> */}
99169
</div>
100170
</a>
101171
);
@@ -143,3 +213,29 @@ export default function LinkCard({ file, isNFTLink }) {
143213
</div> */
144214
}
145215
}
216+
217+
const useImage = ({ src, maxWidth }) => {
218+
const [imgState, setImgState] = React.useState({
219+
loaded: false,
220+
error: true,
221+
overflow: false,
222+
});
223+
224+
React.useEffect(() => {
225+
if (!src) setImgState({ error: true, loaded: true });
226+
227+
const img = new Image();
228+
img.src = src;
229+
230+
img.onload = () => {
231+
if (maxWidth && img.naturalWidth < maxWidth) {
232+
setImgState((prev) => ({ ...prev, loaded: true, error: false, overflow: true }));
233+
} else {
234+
setImgState({ loaded: true, error: false });
235+
}
236+
};
237+
img.onerror = () => setImgState({ loaded: true, error: true });
238+
}, []);
239+
240+
return imgState;
241+
};

0 commit comments

Comments
 (0)