Skip to content

Commit 40e390a

Browse files
committed
feat: ✨ Applies GraphCDN
1 parent 2320262 commit 40e390a

File tree

6 files changed

+122
-5
lines changed

6 files changed

+122
-5
lines changed

src/components/base/HeaderUserMenu.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const HeaderUserMenuBlock = styled.div`
2727
`;
2828

2929
interface HeaderUserMenuProps {
30-
onClose: (e: React.MouseEvent) => void;
30+
onClose: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void;
3131
onLogout: () => void;
3232
username: string;
3333
visible: boolean;

src/components/home/HomeMobileHeadExtra.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import palette from '../../lib/styles/palette';
55
import { Link } from 'react-router-dom';
66
import { useTransition, animated } from 'react-spring';
77
import OutsideClickHandler from 'react-outside-click-handler';
8+
import { useTheme } from '../../lib/hooks/useTheme';
89

910
export type MainMobileHeadExtraProps = {
1011
visible: boolean;
@@ -31,6 +32,12 @@ function MainMobileHeadExtra({ visible, onClose }: MainMobileHeadExtraProps) {
3132
},
3233
});
3334

35+
const theme = useTheme();
36+
const img =
37+
theme === 'dark'
38+
? 'https://graphcdn.io/badge-light.svg'
39+
: 'https://graphcdn.io/badge.svg';
40+
3441
return (
3542
<>
3643
{transition((styles, item) =>
@@ -62,6 +69,11 @@ function MainMobileHeadExtra({ visible, onClose }: MainMobileHeadExtraProps) {
6269
<h5>문의</h5>
6370
<div className="email">[email protected]</div>
6471
</div>
72+
<GraphCDNWrapper>
73+
<a href="https://graphcdn.io/?ref=powered-by">
74+
<img src={img} alt="Powered by GraphCDN, the GraphQL CDN" />
75+
</a>
76+
</GraphCDNWrapper>
6577
</Block>
6678
</OutsideClickHandler>
6779
</Aligner>
@@ -78,6 +90,7 @@ const Aligner = styled.div`
7890
z-index: 5;
7991
`;
8092
const Block = styled(animated.div)`
93+
border: 1px solid ${themedPalette.border3};
8194
margin-top: 0.5rem;
8295
width: 12rem;
8396
box-shadow: 0 0 8px 0 rgba(0, 0, 0, 0.1);
@@ -122,4 +135,15 @@ const Block = styled(animated.div)`
122135
}
123136
`;
124137

138+
const GraphCDNWrapper = styled.div`
139+
display: flex;
140+
justify-content: center;
141+
padding-top: 0.5rem;
142+
padding-bottom: 0.5rem;
143+
img {
144+
width: 120px;
145+
height: auto;
146+
}
147+
`;
148+
125149
export default MainMobileHeadExtra;
Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import * as React from 'react';
1+
import React, { createContext, useContext, useState } from 'react';
22
import styled from 'styled-components';
3+
import { useTheme } from '../../lib/hooks/useTheme';
34
import PageTemplate from '../base/PageTemplate';
45

56
const VelogPageTemplateBlock = styled(PageTemplate)`
@@ -8,8 +9,50 @@ const VelogPageTemplateBlock = styled(PageTemplate)`
89

910
export interface VelogPageTemplateProps {}
1011

12+
const FooterContext = createContext<(value: boolean) => void>(() => {});
13+
1114
const VelogPageTemplate: React.FC<VelogPageTemplateProps> = ({ children }) => {
12-
return <VelogPageTemplateBlock>{children}</VelogPageTemplateBlock>;
15+
const [showFooter, setShowFooter] = useState(false);
16+
return (
17+
<FooterContext.Provider value={setShowFooter}>
18+
<VelogPageTemplateBlock>
19+
{children}
20+
{showFooter && <GraphCDNFooter />}
21+
</VelogPageTemplateBlock>
22+
</FooterContext.Provider>
23+
);
1324
};
1425

26+
export function useSetShowFooter() {
27+
return useContext(FooterContext);
28+
}
29+
30+
function GraphCDNFooter() {
31+
const theme = useTheme();
32+
const img =
33+
theme === 'dark'
34+
? 'https://graphcdn.io/badge-light.svg'
35+
: 'https://graphcdn.io/badge.svg';
36+
return (
37+
<Block>
38+
<a href="https://graphcdn.io/?ref=powered-by">
39+
<img src={img} alt="Powered by GraphCDN, the GraphQL CDN" />
40+
</a>
41+
</Block>
42+
);
43+
}
44+
45+
const Block = styled.div`
46+
display: flex;
47+
justify-content: center;
48+
padding-top: 1rem;
49+
padding-bottom: 1rem;
50+
position: relative;
51+
z-index: 50;
52+
img {
53+
width: 150px;
54+
height: auto;
55+
}
56+
`;
57+
1558
export default VelogPageTemplate;

src/containers/post/PostViewer.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import RelatedPost from './RelatedPost';
3737
import optimizeImage from '../../lib/optimizeImage';
3838
import RelatedPostsForGuest from './RelatedPostsForGuest';
3939
import HorizontalAd from './HorizontalAd';
40+
import { useSetShowFooter } from '../../components/velog/VelogPageTemplate';
4041

4142
const UserProfileWrapper = styled(VelogResponsive)`
4243
margin-top: 16rem;
@@ -64,6 +65,7 @@ const PostViewer: React.FC<PostViewerProps> = ({
6465
history,
6566
match,
6667
}) => {
68+
const setShowFooter = useSetShowFooter();
6769
const [showRecommends, setShowRecommends] = useState(false);
6870
useEffect(() => {
6971
window.scrollTo(0, 0);
@@ -142,6 +144,16 @@ const PostViewer: React.FC<PostViewerProps> = ({
142144

143145
const postReady = !!data?.post;
144146

147+
useEffect(() => {
148+
setShowFooter(postReady);
149+
}, [setShowFooter, postReady]);
150+
151+
useEffect(() => {
152+
return () => {
153+
setShowFooter(false);
154+
};
155+
}, [setShowFooter]);
156+
145157
const onScroll = useCallback(() => {
146158
const scrollTop = getScrollTop();
147159
const { scrollHeight } = document.body;

src/lib/graphql/post.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,44 @@ export const GET_POST_LIST = gql`
177177
}
178178
`;
179179

180+
export const GET_RECENT_POSTS = gql`
181+
query RecentPosts(
182+
$cursor: ID
183+
$username: String
184+
$temp_only: Boolean
185+
$tag: String
186+
$limit: Int
187+
) {
188+
posts(
189+
cursor: $cursor
190+
username: $username
191+
temp_only: $temp_only
192+
tag: $tag
193+
limit: $limit
194+
) {
195+
id
196+
title
197+
short_description
198+
thumbnail
199+
user {
200+
id
201+
username
202+
profile {
203+
id
204+
thumbnail
205+
}
206+
}
207+
url_slug
208+
released_at
209+
updated_at
210+
comments_count
211+
tags
212+
is_private
213+
likes
214+
}
215+
}
216+
`;
217+
180218
export const GET_TRENDING_POSTS = gql`
181219
query TrendingPosts($limit: Int, $offset: Int, $timeframe: String) {
182220
trendingPosts(limit: $limit, offset: $offset, timeframe: $timeframe) {

src/pages/home/hooks/useRecentPosts.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import { useQuery } from '@apollo/react-hooks';
2-
import { GET_POST_LIST, PartialPost } from '../../../lib/graphql/post';
2+
import { GET_RECENT_POSTS, PartialPost } from '../../../lib/graphql/post';
33
import { useCallback, useState } from 'react';
44
import useScrollPagination from '../../../lib/hooks/useScrollPagination';
55

66
export default function useRecentPosts() {
77
const { data, loading, fetchMore } = useQuery<{ posts: PartialPost[] }>(
8-
GET_POST_LIST,
8+
GET_RECENT_POSTS,
99
{
1010
variables: {
1111
limit: 24,

0 commit comments

Comments
 (0)