Merge branch 'master' of https://bitbucket.org/vel1024/capstone
Showing
14 changed files
with
137 additions
and
72 deletions
... | @@ -33,13 +33,13 @@ sub-subject : making chat site using JS | ... | @@ -33,13 +33,13 @@ sub-subject : making chat site using JS |
33 | - [x] Create Chat Screen View, Make Queries for Front-End | 33 | - [x] Create Chat Screen View, Make Queries for Front-End |
34 | 34 | ||
35 | - 5/25 ~ 5/31 | 35 | - 5/25 ~ 5/31 |
36 | -- [ ] Make and Test chatting using GraphQL's Subscription | 36 | +- [X] Make and Test chatting using GraphQL's Subscription |
37 | 37 | ||
38 | - 6/1 ~ 6/7 | 38 | - 6/1 ~ 6/7 |
39 | -- [ ] Make one to one chatting, view, toggle. | 39 | +- [X] Make one to one chatting, view, toggle. |
40 | 40 | ||
41 | - 6/8 ~ 6/14 | 41 | - 6/8 ~ 6/14 |
42 | -- [ ] Debugging for whole codes in our project | 42 | +- [X] Debugging for whole codes in our project |
43 | 43 | ||
44 | - 6/15 ~ 6/21 | 44 | - 6/15 ~ 6/21 |
45 | - [ ] Deploy project in AWS amplify | 45 | - [ ] Deploy project in AWS amplify | ... | ... |
... | @@ -33,13 +33,13 @@ sub-subject : making chat site using JS | ... | @@ -33,13 +33,13 @@ sub-subject : making chat site using JS |
33 | - [x] Create Chat Screen View, Make Queries for Front-End | 33 | - [x] Create Chat Screen View, Make Queries for Front-End |
34 | 34 | ||
35 | - 5/25 ~ 5/31 | 35 | - 5/25 ~ 5/31 |
36 | -- [ ] Make and Test chatting using GraphQL's Subscription | 36 | +- [X] Make and Test chatting using GraphQL's Subscription |
37 | 37 | ||
38 | - 6/1 ~ 6/7 | 38 | - 6/1 ~ 6/7 |
39 | -- [ ] Make one to one chatting, view, toggle. | 39 | +- [X] Make one to one chatting, view, toggle. |
40 | 40 | ||
41 | - 6/8 ~ 6/14 | 41 | - 6/8 ~ 6/14 |
42 | -- [ ] Debugging for whole codes in our project | 42 | +- [X] Debugging for whole codes in our project |
43 | 43 | ||
44 | - 6/15 ~ 6/21 | 44 | - 6/15 ~ 6/21 |
45 | - [ ] Deploy project in AWS amplify | 45 | - [ ] Deploy project in AWS amplify | ... | ... |
1 | -import { prisma } from "../../../utils"; | 1 | +import { prisma, isAuthenticated } from "../../../utils"; |
2 | +import { NEW_CATEGORY } from "../../../topics"; | ||
2 | 3 | ||
3 | export default { | 4 | export default { |
4 | Mutation: { | 5 | Mutation: { |
5 | - addCategory: async (_, args) => { | 6 | + addCategory: async (_, args, { request, pubsub }) => { |
7 | + isAuthenticated(request); | ||
6 | const { name } = args; | 8 | const { name } = args; |
7 | const newCategory = await prisma.category.create({ | 9 | const newCategory = await prisma.category.create({ |
8 | data: { | 10 | data: { |
9 | name, | 11 | name, |
10 | }, | 12 | }, |
11 | }); | 13 | }); |
14 | + if (newCategory !== undefined) { | ||
15 | + pubsub.publish(NEW_CATEGORY, { subCategory: newCategory }); | ||
16 | + } | ||
12 | return newCategory; | 17 | return newCategory; |
13 | }, | 18 | }, |
14 | }, | 19 | }, | ... | ... |
... | @@ -33,13 +33,13 @@ sub-subject : making chat site using JS | ... | @@ -33,13 +33,13 @@ sub-subject : making chat site using JS |
33 | - [x] Create Chat Screen View, Make Queries for Front-End | 33 | - [x] Create Chat Screen View, Make Queries for Front-End |
34 | 34 | ||
35 | - 5/25 ~ 5/31 | 35 | - 5/25 ~ 5/31 |
36 | -- [ ] Make and Test chatting using GraphQL's Subscription | 36 | +- [X] Make and Test chatting using GraphQL's Subscription |
37 | 37 | ||
38 | - 6/1 ~ 6/7 | 38 | - 6/1 ~ 6/7 |
39 | -- [ ] Make one to one chatting, view, toggle. | 39 | +- [X] Make one to one chatting, view, toggle. |
40 | 40 | ||
41 | - 6/8 ~ 6/14 | 41 | - 6/8 ~ 6/14 |
42 | -- [ ] Debugging for whole codes in our project | 42 | +- [X] Debugging for whole codes in our project |
43 | 43 | ||
44 | - 6/15 ~ 6/21 | 44 | - 6/15 ~ 6/21 |
45 | - [ ] Deploy project in AWS amplify | 45 | - [ ] Deploy project in AWS amplify | ... | ... |
1 | import React from "react"; | 1 | import React from "react"; |
2 | import styled from "styled-components"; | 2 | import styled from "styled-components"; |
3 | import ProfileIcon from "./ProfileIcon"; | 3 | import ProfileIcon from "./ProfileIcon"; |
4 | -import moment from "moment"; | ||
5 | 4 | ||
6 | const MessageWrapper = styled.div` | 5 | const MessageWrapper = styled.div` |
7 | display: flex; | 6 | display: flex; |
... | @@ -35,18 +34,7 @@ const Msg = styled.span` | ... | @@ -35,18 +34,7 @@ const Msg = styled.span` |
35 | padding: 20px 10px; | 34 | padding: 20px 10px; |
36 | `; | 35 | `; |
37 | 36 | ||
38 | -const TimeBox = styled.div` | 37 | +export default ({ text, avatar }) => { |
39 | - display: flex; | ||
40 | - justify-content: flex-end; | ||
41 | - align-items: center; | ||
42 | - opacity: 0.8; | ||
43 | -`; | ||
44 | - | ||
45 | -const Time = styled.span` | ||
46 | - font-size: 15px; | ||
47 | -`; | ||
48 | - | ||
49 | -export default ({ text, avatar, time }) => { | ||
50 | return ( | 38 | return ( |
51 | <MessageWrapper className="MessageWrapper"> | 39 | <MessageWrapper className="MessageWrapper"> |
52 | <MsgContainer> | 40 | <MsgContainer> |
... | @@ -55,9 +43,6 @@ export default ({ text, avatar, time }) => { | ... | @@ -55,9 +43,6 @@ export default ({ text, avatar, time }) => { |
55 | <MsgBox> | 43 | <MsgBox> |
56 | <Msg> {text} </Msg> | 44 | <Msg> {text} </Msg> |
57 | </MsgBox> | 45 | </MsgBox> |
58 | - <TimeBox> | ||
59 | - <Time>1</Time> | ||
60 | - </TimeBox> | ||
61 | </ColumnBox> | 46 | </ColumnBox> |
62 | </MsgContainer> | 47 | </MsgContainer> |
63 | </MessageWrapper> | 48 | </MessageWrapper> | ... | ... |
1 | -import React from "react"; | 1 | +import React, { useEffect, useState } from "react"; |
2 | import CategoryPresenter from "./CategoryPresenter"; | 2 | import CategoryPresenter from "./CategoryPresenter"; |
3 | import { withRouter } from "react-router-dom"; | 3 | import { withRouter } from "react-router-dom"; |
4 | -import { useQuery } from "@apollo/react-hooks"; | 4 | +import { useQuery, useMutation } from "@apollo/react-hooks"; |
5 | -import { GET_CATEGORIRES } from "./CategoryQueries"; | 5 | +import { |
6 | + GET_CATEGORIRES, | ||
7 | + ADD_CATEGORY, | ||
8 | + SUBSCRIPTION_CATEGORY, | ||
9 | +} from "./CategoryQueries"; | ||
6 | 10 | ||
7 | export default withRouter(({ location }) => { | 11 | export default withRouter(({ location }) => { |
8 | - const { data } = useQuery(GET_CATEGORIRES); | 12 | + const [categoryArr, setCategoryArr] = useState([]); |
9 | - //const [addCategory] = useMutation(ADD_CATEGORY); | 13 | + const { |
10 | - //const [editCategory] = useMutation(EDIT_CATEGORY); | 14 | + subscribeToMore, |
11 | - //const [deleteCategory] = useMutation(DELETE_CATEGORY); | 15 | + data: categoryList, |
16 | + error: categoryQueryError, | ||
17 | + loading: categoryQueryLoading, | ||
18 | + } = useQuery(GET_CATEGORIRES); | ||
12 | 19 | ||
13 | let categories; | 20 | let categories; |
14 | - if (data !== undefined) { | 21 | + if (categoryList !== undefined) { |
15 | - const { getCategories } = data; | 22 | + const { getCategories } = categoryList; |
16 | categories = getCategories; | 23 | categories = getCategories; |
17 | } | 24 | } |
18 | 25 | ||
19 | - return <CategoryPresenter location={location} categories={categories} />; | 26 | + useEffect(() => { |
27 | + if (categoryQueryError) { | ||
28 | + console.error(categoryQueryError); | ||
29 | + } | ||
30 | + if (categoryArr) { | ||
31 | + setCategoryArr(categoryArr.getCategories, [ | ||
32 | + categoryQueryError, | ||
33 | + categoryArr, | ||
34 | + ]); | ||
35 | + } | ||
36 | + }, [categoryQueryLoading]); | ||
37 | + | ||
38 | + const subscribeToNewCategory = () => { | ||
39 | + subscribeToMore({ | ||
40 | + document: SUBSCRIPTION_CATEGORY, | ||
41 | + updateQuery: (currentCategories, { subscriptionData }) => { | ||
42 | + if (!subscriptionData.data) return currentCategories; | ||
43 | + const newCategory = subscriptionData.data.subCategory; | ||
44 | + const updateCategory = currentCategories.getCategories.concat( | ||
45 | + newCategory | ||
46 | + ); | ||
47 | + setCategoryArr(updateCategory); | ||
48 | + return { getCategories: updateCategory }; | ||
49 | + }, | ||
50 | + }); | ||
51 | + }; | ||
52 | + | ||
53 | + return ( | ||
54 | + <CategoryPresenter | ||
55 | + location={location} | ||
56 | + categories={categories} | ||
57 | + subscribeToNewCategory={subscribeToNewCategory} | ||
58 | + /> | ||
59 | + ); | ||
20 | }); | 60 | }); | ... | ... |
1 | -import React from "react"; | 1 | +import React, { useEffect } from "react"; |
2 | import styled from "styled-components"; | 2 | import styled from "styled-components"; |
3 | import { Link } from "react-router-dom"; | 3 | import { Link } from "react-router-dom"; |
4 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; | 4 | import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; |
... | @@ -62,9 +62,10 @@ const StyledLink = styled(Link)` | ... | @@ -62,9 +62,10 @@ const StyledLink = styled(Link)` |
62 | } | 62 | } |
63 | `; | 63 | `; |
64 | 64 | ||
65 | -export default ({ location, categories }) => { | 65 | +export default ({ location, categories, subscribeToNewCategory }) => { |
66 | const { pathname } = location; | 66 | const { pathname } = location; |
67 | let path; | 67 | let path; |
68 | + useEffect(() => subscribeToNewCategory(), []); | ||
68 | return ( | 69 | return ( |
69 | <> | 70 | <> |
70 | <CategoryContainer> | 71 | <CategoryContainer> | ... | ... |
... | @@ -23,3 +23,12 @@ export const DELETE_CATEGORY = gql` | ... | @@ -23,3 +23,12 @@ export const DELETE_CATEGORY = gql` |
23 | deleteCategory(name: $name) | 23 | deleteCategory(name: $name) |
24 | } | 24 | } |
25 | `; | 25 | `; |
26 | + | ||
27 | +export const SUBSCRIPTION_CATEGORY = gql` | ||
28 | + subscription { | ||
29 | + subCategory { | ||
30 | + id | ||
31 | + name | ||
32 | + } | ||
33 | + } | ||
34 | +`; | ... | ... |
... | @@ -11,7 +11,6 @@ import { | ... | @@ -11,7 +11,6 @@ import { |
11 | import useInput from "../../Hooks/useInput"; | 11 | import useInput from "../../Hooks/useInput"; |
12 | import { toast } from "react-toastify"; | 12 | import { toast } from "react-toastify"; |
13 | 13 | ||
14 | - | ||
15 | export default withRouter(({ location }) => { | 14 | export default withRouter(({ location }) => { |
16 | const [messageArr, setMessageArr] = useState([]); | 15 | const [messageArr, setMessageArr] = useState([]); |
17 | const { pathname } = location; | 16 | const { pathname } = location; |
... | @@ -20,7 +19,7 @@ export default withRouter(({ location }) => { | ... | @@ -20,7 +19,7 @@ export default withRouter(({ location }) => { |
20 | 19 | ||
21 | const message = useInput(""); | 20 | const message = useInput(""); |
22 | 21 | ||
23 | - let messageObj, roomNum, messageArray; | 22 | + let messageObj, roomNum, messageArray; // messageArray 는 useQuery 로 얻은 데이터 인데 undefined 가 아닌 데이터 |
24 | 23 | ||
25 | const { data: getRoom } = useQuery(GET_ROOM_BY_NAME, { | 24 | const { data: getRoom } = useQuery(GET_ROOM_BY_NAME, { |
26 | variables: { roomName }, | 25 | variables: { roomName }, |
... | @@ -36,7 +35,7 @@ export default withRouter(({ location }) => { | ... | @@ -36,7 +35,7 @@ export default withRouter(({ location }) => { |
36 | subscribeToMore, | 35 | subscribeToMore, |
37 | data: messageList, | 36 | data: messageList, |
38 | error: msgQueryError, | 37 | error: msgQueryError, |
39 | - loading: msgQueryyLoading, | 38 | + loading: msgQueryLoading, |
40 | } = useQuery(SEE_ALL_MESSAGE, { | 39 | } = useQuery(SEE_ALL_MESSAGE, { |
41 | variables: { roomId: roomNum }, | 40 | variables: { roomId: roomNum }, |
42 | }); | 41 | }); |
... | @@ -52,7 +51,7 @@ export default withRouter(({ location }) => { | ... | @@ -52,7 +51,7 @@ export default withRouter(({ location }) => { |
52 | if (messageArr) { | 51 | if (messageArr) { |
53 | setMessageArr(messageArr.seeAllMessage, [msgQueryError, messageArr]); | 52 | setMessageArr(messageArr.seeAllMessage, [msgQueryError, messageArr]); |
54 | } | 53 | } |
55 | - }, [msgQueryyLoading]); | 54 | + }, [msgQueryLoading]); |
56 | 55 | ||
57 | const subscribeToNewMessage = () => { | 56 | const subscribeToNewMessage = () => { |
58 | subscribeToMore({ | 57 | subscribeToMore({ | ... | ... |
... | @@ -107,28 +107,38 @@ const ChatScreenBox = styled.div` | ... | @@ -107,28 +107,38 @@ const ChatScreenBox = styled.div` |
107 | } | 107 | } |
108 | `; | 108 | `; |
109 | 109 | ||
110 | +const InputWrapper = styled.div` | ||
111 | + width: 100%; | ||
112 | + display: flex; | ||
113 | + flex-direction: row; | ||
114 | + justify-content: center; | ||
115 | + align-items: center; | ||
116 | +`; | ||
117 | + | ||
110 | const InputContainer = styled.div` | 118 | const InputContainer = styled.div` |
111 | position: fixed; | 119 | position: fixed; |
112 | bottom: 0; | 120 | bottom: 0; |
113 | justify-content: center; | 121 | justify-content: center; |
114 | align-items: center; | 122 | align-items: center; |
115 | - width: 70%; | 123 | + width: 50%; |
116 | - margin: 10px; | 124 | + margin-bottom: 20px; |
117 | display: flex; | 125 | display: flex; |
118 | flex-direction: row; | 126 | flex-direction: row; |
127 | + background-color: #b2bec3; | ||
128 | + border: none; | ||
119 | form { | 129 | form { |
120 | width: 100%; | 130 | width: 100%; |
121 | button { | 131 | button { |
122 | background-color: #27ae60; | 132 | background-color: #27ae60; |
123 | - width: 10%; | 133 | + width: 20%; |
124 | color: white; | 134 | color: white; |
125 | border-radius: 10px; | 135 | border-radius: 10px; |
126 | } | 136 | } |
127 | input { | 137 | input { |
138 | + background-color: #b2bec3; | ||
128 | width: 70%; | 139 | width: 70%; |
129 | } | 140 | } |
130 | } | 141 | } |
131 | - border: 1px solid rgba(0, 0, 0, 0.7); | ||
132 | border-radius: 10px; | 142 | border-radius: 10px; |
133 | `; | 143 | `; |
134 | 144 | ||
... | @@ -156,7 +166,7 @@ export default ({ | ... | @@ -156,7 +166,7 @@ export default ({ |
156 | }) => { | 166 | }) => { |
157 | const { pathname } = location; | 167 | const { pathname } = location; |
158 | const roomName = pathname.slice(1, pathname.length); | 168 | const roomName = pathname.slice(1, pathname.length); |
159 | - useEffect(() => subscribeToNewMessage()); | 169 | + useEffect(() => subscribeToNewMessage(), []); |
160 | 170 | ||
161 | return ( | 171 | return ( |
162 | <Wrapper> | 172 | <Wrapper> |
... | @@ -167,7 +177,7 @@ export default ({ | ... | @@ -167,7 +177,7 @@ export default ({ |
167 | <Title>{roomName} Room</Title> | 177 | <Title>{roomName} Room</Title> |
168 | </TitleContainer> | 178 | </TitleContainer> |
169 | <PeopleContainer> | 179 | <PeopleContainer> |
170 | - <StyledLink to="People"> | 180 | + <StyledLink to={`/${roomName}/People`}> |
171 | <FontAwesomeIcon icon={faAddressBook} /> | 181 | <FontAwesomeIcon icon={faAddressBook} /> |
172 | <ItemText>People</ItemText> | 182 | <ItemText>People</ItemText> |
173 | </StyledLink> | 183 | </StyledLink> |
... | @@ -176,30 +186,30 @@ export default ({ | ... | @@ -176,30 +186,30 @@ export default ({ |
176 | </ChatMenuContainer> | 186 | </ChatMenuContainer> |
177 | <ChatScreenContainer> | 187 | <ChatScreenContainer> |
178 | <ChatScreenHeader> | 188 | <ChatScreenHeader> |
179 | - <Title>Selected Menu Title</Title> | 189 | + <Title>{roomName}</Title> |
180 | </ChatScreenHeader> | 190 | </ChatScreenHeader> |
181 | <ChatScreenBox> | 191 | <ChatScreenBox> |
182 | - <ul> | 192 | + {messageArray && |
183 | - {messageArray && | 193 | + messageArray.seeAllMessage.map((e) => ( |
184 | - messageArray.seeAllMessage.map((e) => ( | 194 | + <Message |
185 | - <Message | 195 | + text={e.text} |
186 | - text={e.text} | 196 | + time={e.createdAt} |
187 | - time={e.createdAt} | 197 | + key={e.id} |
188 | - key={e.id} | 198 | + avatar={e.sender.avatarUrl} |
189 | - avatar={e.sender.avatarUrl} | ||
190 | - /> | ||
191 | - ))} | ||
192 | - </ul> | ||
193 | - <InputContainer className="InputContainer"> | ||
194 | - <form onSubmit={onSubmit}> | ||
195 | - <Input | ||
196 | - placeholder={"Enter any words"} | ||
197 | - type="text" | ||
198 | - {...message} | ||
199 | /> | 199 | /> |
200 | - <Button text={"Submit"} /> | 200 | + ))} |
201 | - </form> | 201 | + <InputWrapper> |
202 | - </InputContainer> | 202 | + <InputContainer className="InputContainer"> |
203 | + <form onSubmit={onSubmit}> | ||
204 | + <Input | ||
205 | + placeholder={"Enter any words"} | ||
206 | + type="text" | ||
207 | + {...message} | ||
208 | + /> | ||
209 | + <Button text={"Submit"} /> | ||
210 | + </form> | ||
211 | + </InputContainer> | ||
212 | + </InputWrapper> | ||
203 | </ChatScreenBox> | 213 | </ChatScreenBox> |
204 | </ChatScreenContainer> | 214 | </ChatScreenContainer> |
205 | </ChatWrapper> | 215 | </ChatWrapper> | ... | ... |
... | @@ -9,8 +9,8 @@ const LoggedInRoutes = () => ( | ... | @@ -9,8 +9,8 @@ const LoggedInRoutes = () => ( |
9 | <Switch> | 9 | <Switch> |
10 | <Route exact path="/" component={RoomList} /> | 10 | <Route exact path="/" component={RoomList} /> |
11 | <Route exact path="/:roomname" component={Chat} /> | 11 | <Route exact path="/:roomname" component={Chat} /> |
12 | - <Route path="/:roomname/People" component={Auth} /> | 12 | + <Route path="/:roomname/People" component={Chat} /> |
13 | - <Route path="/:roomname/:categoryName" component={Auth} /> | 13 | + <Route path="/:roomname/:categoryName" component={Chat} /> |
14 | <Redirect from="*" to="/" /> | 14 | <Redirect from="*" to="/" /> |
15 | </Switch> | 15 | </Switch> |
16 | ); | 16 | ); | ... | ... |
-
Please register or login to post a comment