Skip to content

Commit 2110a38

Browse files
committed
Fix recommended posts for guest
1 parent 61d3c49 commit 2110a38

File tree

3 files changed

+221
-43
lines changed

3 files changed

+221
-43
lines changed

src/containers/post/PostViewer.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import { toast } from 'react-toastify';
3535
import MobileLikeButton from '../../components/post/MobileLikeButton';
3636
import RelatedPost from './RelatedPost';
3737
import optimizeImage from '../../lib/optimizeImage';
38+
import RelatedPostsForGuest from './RelatedPostsForGuest';
3839

3940
const UserProfileWrapper = styled(VelogResponsive)`
4041
margin-top: 16rem;
@@ -148,7 +149,7 @@ const PostViewer: React.FC<PostViewerProps> = ({
148149
if (percentage > 50) {
149150
prefetchLinkedPosts();
150151
}
151-
if (percentage > 75 && postReady) {
152+
if (percentage > 50 && postReady) {
152153
setShowRecommends(true);
153154
}
154155
}, [prefetchLinkedPosts, postReady]);
@@ -382,14 +383,21 @@ const PostViewer: React.FC<PostViewerProps> = ({
382383
/>
383384
</UserProfileWrapper>
384385
<LinkedPostList linkedPosts={post.linked_posts} />
386+
{showRecommends && userId === null && (
387+
<RelatedPostsForGuest
388+
postId={post.id}
389+
showAds={
390+
Date.now() - new Date(post.released_at).getTime() >
391+
1000 * 60 * 60 * 24 * 21
392+
}
393+
/>
394+
)}
385395
<PostComments
386396
count={post.comments_count}
387397
comments={post.comments}
388398
postId={post.id}
389399
/>
390-
{showRecommends && (
391-
<RelatedPost showAds={userId === null} postId={post.id} />
392-
)}
400+
{showRecommends && userId !== null && <RelatedPost postId={post.id} />}
393401
</PostViewerProvider>
394402
);
395403
};

src/containers/post/RelatedPost.tsx

Lines changed: 32 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,64 +5,57 @@ import { useQuery } from '@apollo/react-hooks';
55
import {
66
GetRecommendedPostResponse,
77
GET_RECOMMENDED_POST,
8-
PartialPost,
98
} from '../../lib/graphql/post';
109
import PostCardGrid from '../../components/common/PostCardGrid';
1110
import palette from '../../lib/styles/palette';
12-
import { detectAnyAdblocker } from 'just-detect-adblock';
11+
// import { detectAnyAdblocker } from 'just-detect-adblock';
1312

14-
function RelatedPost({
15-
showAds,
16-
postId,
17-
}: {
18-
showAds: boolean;
19-
postId: string;
20-
}) {
21-
const [adBlocked, setAdBlocked] = useState(false);
22-
useEffect(() => {
23-
detectAnyAdblocker().then((detected: boolean) => {
24-
if (detected) {
25-
setAdBlocked(true);
26-
}
27-
});
28-
}, []);
13+
function RelatedPost({ postId }: { postId: string }) {
14+
// const [adBlocked, setAdBlocked] = useState(false);
15+
// useEffect(() => {
16+
// detectAnyAdblocker().then((detected: boolean) => {
17+
// if (detected) {
18+
// setAdBlocked(true);
19+
// }
20+
// });
21+
// }, []);
2922

3023
const { data } = useQuery<GetRecommendedPostResponse>(GET_RECOMMENDED_POST, {
3124
variables: {
3225
id: postId,
3326
},
3427
});
3528

36-
const postWithAds = useMemo(() => {
37-
if (!data?.post) return null;
38-
if (!showAds || adBlocked) return data.post.recommended_posts;
39-
const cloned: (PartialPost | undefined)[] = [
40-
...data.post.recommended_posts,
41-
];
42-
// get random number between 0 and length of array
43-
const randomIndex = () => Math.floor(Math.random() * 8);
44-
const firstAdIndex = randomIndex();
45-
const secondAdIndex = (() => {
46-
let index = randomIndex();
47-
while (index === firstAdIndex) {
48-
index = randomIndex();
49-
}
50-
return index;
51-
})();
29+
// const postWithAds = useMemo(() => {
30+
// if (!data?.post) return null;
31+
// if (!showAds || adBlocked) return data.post.recommended_posts;
32+
// const cloned: (PartialPost | undefined)[] = [
33+
// ...data.post.recommended_posts,
34+
// ];
35+
// // get random number between 0 and length of array
36+
// const randomIndex = () => Math.floor(Math.random() * 8);
37+
// const firstAdIndex = randomIndex();
38+
// const secondAdIndex = (() => {
39+
// let index = randomIndex();
40+
// while (index === firstAdIndex) {
41+
// index = randomIndex();
42+
// }
43+
// return index;
44+
// })();
5245

53-
cloned[firstAdIndex] = undefined;
54-
cloned[secondAdIndex] = undefined;
55-
return cloned;
56-
}, [data, showAds, adBlocked]);
46+
// cloned[firstAdIndex] = undefined;
47+
// cloned[secondAdIndex] = undefined;
48+
// return cloned;
49+
// }, [data, showAds, adBlocked]);
5750

58-
if (!postWithAds) return null;
51+
if (!data?.post.recommended_posts) return null;
5952

6053
return (
6154
<>
6255
<Background>
6356
<Title>관심 있을 만한 포스트</Title>
6457
<Wrapper>
65-
<PostCardGrid posts={postWithAds} forPost />
58+
<PostCardGrid posts={data?.post.recommended_posts} forPost />
6659
</Wrapper>
6760
</Background>
6861
<PullUp />
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
import React, { useMemo, useState, useEffect } from 'react';
2+
import styled from 'styled-components';
3+
import media from '../../lib/styles/media';
4+
import { useQuery } from '@apollo/react-hooks';
5+
import {
6+
GetRecommendedPostResponse,
7+
GET_RECOMMENDED_POST,
8+
PartialPost,
9+
} from '../../lib/graphql/post';
10+
import PostCardGrid from '../../components/common/PostCardGrid';
11+
import palette from '../../lib/styles/palette';
12+
import VelogResponsive from '../../components/velog/VelogResponsive';
13+
import { userThumbnail } from '../../static/images';
14+
import { Link } from 'react-router-dom';
15+
import gtag from '../../lib/gtag';
16+
import optimizeImage from '../../lib/optimizeImage';
17+
// import { detectAnyAdblocker } from 'just-detect-adblock';
18+
19+
function RelatedPostsForGuest({
20+
postId,
21+
showAds,
22+
}: {
23+
postId: string;
24+
showAds: boolean;
25+
}) {
26+
const { data } = useQuery<GetRecommendedPostResponse>(GET_RECOMMENDED_POST, {
27+
variables: {
28+
id: postId,
29+
},
30+
});
31+
32+
const postsWithAds = useMemo(() => {
33+
if (!data?.post) return null;
34+
let sliced: (PartialPost | undefined)[] =
35+
data.post.recommended_posts.filter((post) => post.thumbnail);
36+
if (sliced.length < 6) {
37+
sliced = data.post.recommended_posts.slice(0, 6);
38+
} else {
39+
sliced = sliced.slice(0, 6);
40+
}
41+
if (!showAds) return sliced;
42+
43+
const indexes = [
44+
[0, 5],
45+
[0, 4],
46+
[0, 2],
47+
[1, 3],
48+
[1, 5],
49+
[2, 3],
50+
[2, 4],
51+
[3, 5],
52+
];
53+
54+
const randomIndex = Math.floor(Math.random() * indexes.length);
55+
const [firstIndex, secondIndex] = indexes[randomIndex];
56+
sliced[firstIndex] = undefined;
57+
sliced[secondIndex] = undefined;
58+
return sliced;
59+
}, [data, showAds]);
60+
61+
if (!postsWithAds) return null;
62+
63+
return (
64+
<Wrapper>
65+
<h4>관심 있을 만한 포스트</h4>
66+
<Grid>
67+
{postsWithAds.map((post) =>
68+
post ? (
69+
<Item onClick={() => gtag('event', 'recommend_guest_click')}>
70+
<StyledLink to={`/@${post.user.username}/${post.url_slug}`}>
71+
<div className="thumbnail-wrapper">
72+
<img
73+
src={optimizeImage(
74+
post.thumbnail ??
75+
post.user.profile.thumbnail ??
76+
userThumbnail,
77+
640,
78+
)}
79+
alt={post.title}
80+
/>
81+
</div>
82+
<h5>{post.title}</h5>
83+
</StyledLink>
84+
</Item>
85+
) : (
86+
<Item>
87+
<ins
88+
className="adsbygoogle"
89+
style={{ display: 'block' }}
90+
data-ad-format="fluid"
91+
data-ad-layout-key="-7p+de+1x+n+9"
92+
data-ad-client="ca-pub-5574866530496701"
93+
data-ad-slot="9497725960"
94+
></ins>
95+
</Item>
96+
),
97+
)}
98+
</Grid>
99+
</Wrapper>
100+
);
101+
}
102+
103+
const Wrapper = styled(VelogResponsive)`
104+
h4 {
105+
font-size: 1.125rem;
106+
color: ${palette.gray8};
107+
}
108+
margin-top: 4rem;
109+
margin-bottom: 3rem;
110+
${media.small} {
111+
flex-direction: column-reverse;
112+
padding-left: 1rem;
113+
padding-right: 1rem;
114+
}
115+
`;
116+
117+
const Grid = styled.div`
118+
margin-left: -0.5rem;
119+
margin-right: -0.5rem;
120+
display: flex;
121+
flex-wrap: wrap;
122+
margin-top: 1.5rem;
123+
`;
124+
125+
const Item = styled.div`
126+
position: relative;
127+
width: 33.333%;
128+
padding-left: 0.5rem;
129+
padding-right: 0.5rem;
130+
padding-bottom: 2rem;
131+
${media.medium} {
132+
width: 50%;
133+
padding-bottom: 1rem;
134+
}
135+
136+
.thumbnail-wrapper {
137+
width: 100%;
138+
padding-top: 52.35%;
139+
position: relative;
140+
141+
img {
142+
position: absolute;
143+
left: 0;
144+
top: 0;
145+
width: 100%;
146+
height: 100%;
147+
object-fit: cover;
148+
display: block;
149+
}
150+
}
151+
h5 {
152+
font-size: 1rem;
153+
line-height: 1.5;
154+
margin-top: 0.5rem;
155+
margin-bottom: 0;
156+
display: -webkit-box;
157+
-webkit-line-clamp: 2;
158+
-webkit-box-orient: vertical;
159+
overflow: hidden;
160+
text-overflow: ellipsis;
161+
text-decoration: none;
162+
color: inherit;
163+
color: ${palette.gray8};
164+
}
165+
`;
166+
167+
const StyledLink = styled(Link)`
168+
display: block;
169+
text-decoration: none;
170+
color: inherit;
171+
&:hover {
172+
text-decoration: underline;
173+
color: ${palette.gray7};
174+
}
175+
`;
176+
177+
export default RelatedPostsForGuest;

0 commit comments

Comments
 (0)