Merge branch 'master' of https://bitbucket.org/vel1024/capstone
# Conflicts: # back/Dockerfile # back/prisma/Dockerfile
Showing
12 changed files
with
96 additions
and
63 deletions
... | @@ -9,7 +9,11 @@ RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSI | ... | @@ -9,7 +9,11 @@ RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSI |
9 | && tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ | 9 | && tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ |
10 | && rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz | 10 | && rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz |
11 | 11 | ||
12 | +<<<<<<< HEAD | ||
12 | ENTRYPOINT [ "dockerize", "-wait", "tcp://root:prisma@mysql:3306/prisma:3306", "-timeout", "120s" ] | 13 | ENTRYPOINT [ "dockerize", "-wait", "tcp://root:prisma@mysql:3306/prisma:3306", "-timeout", "120s" ] |
14 | +======= | ||
15 | +ENTRYPOINT [ "dockerize", "-wait", "tcp://root:prisma@mysql:3306/prisma:3306", "-timeout", "60s" ] | ||
16 | +>>>>>>> 81d693438b3dd8e67a7daefac47486362f102999 | ||
13 | 17 | ||
14 | COPY package*.json ./ | 18 | COPY package*.json ./ |
15 | COPY prisma ./prisma/ | 19 | COPY prisma ./prisma/ | ... | ... |
... | @@ -2242,14 +2242,6 @@ | ... | @@ -2242,14 +2242,6 @@ |
2242 | "graphql-playground-html": "1.6.12" | 2242 | "graphql-playground-html": "1.6.12" |
2243 | } | 2243 | } |
2244 | }, | 2244 | }, |
2245 | - "graphql-subscriptions": { | ||
2246 | - "version": "0.5.8", | ||
2247 | - "resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz", | ||
2248 | - "integrity": "sha512-0CaZnXKBw2pwnIbvmVckby5Ge5e2ecmjofhYCdyeACbCly2j3WXDP/pl+s+Dqd2GQFC7y99NB+53jrt55CKxYQ==", | ||
2249 | - "requires": { | ||
2250 | - "iterall": "^1.2.1" | ||
2251 | - } | ||
2252 | - }, | ||
2253 | "graphql-tools": { | 2245 | "graphql-tools": { |
2254 | "version": "4.0.7", | 2246 | "version": "4.0.7", |
2255 | "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-4.0.7.tgz", | 2247 | "resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-4.0.7.tgz", |
... | @@ -2323,6 +2315,16 @@ | ... | @@ -2323,6 +2315,16 @@ |
2323 | "graphql-tools": "^4.0.0", | 2315 | "graphql-tools": "^4.0.0", |
2324 | "graphql-upload": "^8.0.0", | 2316 | "graphql-upload": "^8.0.0", |
2325 | "subscriptions-transport-ws": "^0.9.8" | 2317 | "subscriptions-transport-ws": "^0.9.8" |
2318 | + }, | ||
2319 | + "dependencies": { | ||
2320 | + "graphql-subscriptions": { | ||
2321 | + "version": "0.5.8", | ||
2322 | + "resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz", | ||
2323 | + "integrity": "sha512-0CaZnXKBw2pwnIbvmVckby5Ge5e2ecmjofhYCdyeACbCly2j3WXDP/pl+s+Dqd2GQFC7y99NB+53jrt55CKxYQ==", | ||
2324 | + "requires": { | ||
2325 | + "iterall": "^1.2.1" | ||
2326 | + } | ||
2327 | + } | ||
2326 | } | 2328 | } |
2327 | }, | 2329 | }, |
2328 | "has": { | 2330 | "has": { | ... | ... |
... | @@ -9,7 +9,11 @@ RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSI | ... | @@ -9,7 +9,11 @@ RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSI |
9 | && tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ | 9 | && tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \ |
10 | && rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz | 10 | && rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz |
11 | 11 | ||
12 | +<<<<<<< HEAD | ||
12 | ENTRYPOINT [ "dockerize", "-wait", "tcp://root:prisma@mysql:3306/prisma:3306", "-timeout", "120s" ] | 13 | ENTRYPOINT [ "dockerize", "-wait", "tcp://root:prisma@mysql:3306/prisma:3306", "-timeout", "120s" ] |
14 | +======= | ||
15 | +ENTRYPOINT [ "dockerize", "-wait", "tcp://root:prisma@mysql:3306/prisma:3306", "-timeout", "60s" ] | ||
16 | +>>>>>>> 81d693438b3dd8e67a7daefac47486362f102999 | ||
13 | 17 | ||
14 | COPY ./ ./prisma/ | 18 | COPY ./ ./prisma/ |
15 | 19 | ... | ... |
1 | import { prisma, isAuthenticated } from "../../../utils"; | 1 | import { prisma, isAuthenticated } from "../../../utils"; |
2 | +import { NEW_MESSAGE } from "../../../topics"; | ||
2 | 3 | ||
3 | export default { | 4 | export default { |
4 | Mutation: { | 5 | Mutation: { |
5 | - createMessage: async (_, args, { request }) => { | 6 | + createMessage: async (_, args, { request, pubsub }) => { |
6 | isAuthenticated(request); | 7 | isAuthenticated(request); |
7 | const { user } = request; | 8 | const { user } = request; |
8 | const { message, roomId } = args; | 9 | const { message, roomId } = args; |
... | @@ -46,6 +47,11 @@ export default { | ... | @@ -46,6 +47,11 @@ export default { |
46 | } else { | 47 | } else { |
47 | throw new Error("There is no room"); | 48 | throw new Error("There is no room"); |
48 | } | 49 | } |
50 | + | ||
51 | + if (messageObj !== undefined) { | ||
52 | + pubsub.publish(NEW_MESSAGE, { subMessage: messageObj }); | ||
53 | + } | ||
54 | + | ||
49 | return messageObj; | 55 | return messageObj; |
50 | }, | 56 | }, |
51 | }, | 57 | }, | ... | ... |
1 | -import { ONE_TO_ONE_MESSAGE } from "../../../topics"; | 1 | +import { NEW_MESSAGE } from "../../../topics"; |
2 | 2 | ||
3 | export default { | 3 | export default { |
4 | Subscription: { | 4 | Subscription: { |
5 | subMessage: { | 5 | subMessage: { |
6 | subscribe: async (_, __, { pubsub }) => { | 6 | subscribe: async (_, __, { pubsub }) => { |
7 | - return pubsub.asyncIterator(ONE_TO_ONE_MESSAGE); | 7 | + return pubsub.asyncIterator(NEW_MESSAGE); |
8 | }, | 8 | }, |
9 | }, | 9 | }, |
10 | }, | 10 | }, | ... | ... |
1 | import React from "react"; | 1 | import React from "react"; |
2 | import styled from "styled-components"; | 2 | import styled from "styled-components"; |
3 | -//import { parse, format } from "date-fns"; | 3 | +import ProfileIcon from "./ProfileIcon"; |
4 | 4 | ||
5 | const MessageWrapper = styled.div` | 5 | const MessageWrapper = styled.div` |
6 | display: flex; | 6 | display: flex; |
7 | - justify-content: flex-end; | 7 | + justify-content: flex-start; |
8 | align-items: center; | 8 | align-items: center; |
9 | padding: 20px 10px; | 9 | padding: 20px 10px; |
10 | margin-top: 20px; | 10 | margin-top: 20px; |
... | @@ -13,6 +13,11 @@ const MessageWrapper = styled.div` | ... | @@ -13,6 +13,11 @@ const MessageWrapper = styled.div` |
13 | 13 | ||
14 | const MsgContainer = styled.div` | 14 | const MsgContainer = styled.div` |
15 | display: flex; | 15 | display: flex; |
16 | + flex-direction: row; | ||
17 | +`; | ||
18 | + | ||
19 | +const ColumnBox = styled.div` | ||
20 | + display: flex; | ||
16 | flex-direction: column; | 21 | flex-direction: column; |
17 | `; | 22 | `; |
18 | 23 | ||
... | @@ -20,9 +25,7 @@ const MsgBox = styled.div` | ... | @@ -20,9 +25,7 @@ const MsgBox = styled.div` |
20 | display: flex; | 25 | display: flex; |
21 | justify-content: center; | 26 | justify-content: center; |
22 | align-items: center; | 27 | align-items: center; |
23 | - background-color: #54a0ff; | 28 | + color: black; |
24 | - color: white; | ||
25 | - border-radius: 20px; | ||
26 | margin-bottom: 10px; | 29 | margin-bottom: 10px; |
27 | `; | 30 | `; |
28 | 31 | ||
... | @@ -42,16 +45,19 @@ const Time = styled.span` | ... | @@ -42,16 +45,19 @@ const Time = styled.span` |
42 | font-size: 15px; | 45 | font-size: 15px; |
43 | `; | 46 | `; |
44 | 47 | ||
45 | -export default ({ text }) => { | 48 | +export default ({ text, avatar }) => { |
46 | return ( | 49 | return ( |
47 | <MessageWrapper className="MessageWrapper"> | 50 | <MessageWrapper className="MessageWrapper"> |
48 | <MsgContainer> | 51 | <MsgContainer> |
49 | - <MsgBox> | 52 | + <ProfileIcon avatar={avatar} /> |
50 | - <Msg> {text} </Msg> | 53 | + <ColumnBox> |
51 | - </MsgBox> | 54 | + <MsgBox> |
52 | - <TimeBox> | 55 | + <Msg> {text} </Msg> |
53 | - <Time></Time> | 56 | + </MsgBox> |
54 | - </TimeBox> | 57 | + <TimeBox> |
58 | + <Time>1</Time> | ||
59 | + </TimeBox> | ||
60 | + </ColumnBox> | ||
55 | </MsgContainer> | 61 | </MsgContainer> |
56 | </MessageWrapper> | 62 | </MessageWrapper> |
57 | ); | 63 | ); | ... | ... |
1 | import React from "react"; | 1 | import React from "react"; |
2 | import styled from "styled-components"; | 2 | import styled from "styled-components"; |
3 | -import defaultProfile from "../imgs/defaultProfile.jpg"; | ||
4 | 3 | ||
5 | const ProfileIconBox = styled.div` | 4 | const ProfileIconBox = styled.div` |
6 | display: flex; | 5 | display: flex; |
... | @@ -15,10 +14,10 @@ const ProfileIcon = styled.img` | ... | @@ -15,10 +14,10 @@ const ProfileIcon = styled.img` |
15 | src: ${(props) => props.theme.defaultProfile}; | 14 | src: ${(props) => props.theme.defaultProfile}; |
16 | `; | 15 | `; |
17 | 16 | ||
18 | -export default () => { | 17 | +export default ({ avatar }) => { |
19 | return ( | 18 | return ( |
20 | - <ProfileIconBox> | 19 | + <ProfileIconBox className="ProfileIconBox"> |
21 | - <ProfileIcon src={defaultProfile} /> | 20 | + <ProfileIcon src={avatar} /> |
22 | </ProfileIconBox> | 21 | </ProfileIconBox> |
23 | ); | 22 | ); |
24 | }; | 23 | }; | ... | ... |
... | @@ -6,20 +6,19 @@ import { | ... | @@ -6,20 +6,19 @@ import { |
6 | CREATE_MESSAGE, | 6 | CREATE_MESSAGE, |
7 | GET_ROOM_BY_NAME, | 7 | GET_ROOM_BY_NAME, |
8 | SEE_ALL_MESSAGE, | 8 | SEE_ALL_MESSAGE, |
9 | + SUBSCRIPTION_MSG, | ||
9 | } from "./ChatQueries"; | 10 | } from "./ChatQueries"; |
10 | import useInput from "../../Hooks/useInput"; | 11 | import useInput from "../../Hooks/useInput"; |
11 | import { toast } from "react-toastify"; | 12 | import { toast } from "react-toastify"; |
12 | -//import defaultProfile from "../imgs/defaultProfile.jpg"; | ||
13 | 13 | ||
14 | export default withRouter(({ location }) => { | 14 | export default withRouter(({ location }) => { |
15 | const { pathname } = location; | 15 | const { pathname } = location; |
16 | const roomName = pathname.slice(1, pathname.length); | 16 | const roomName = pathname.slice(1, pathname.length); |
17 | const [createMsg] = useMutation(CREATE_MESSAGE); | 17 | const [createMsg] = useMutation(CREATE_MESSAGE); |
18 | - //const { data } = useSubscription(SUBSCRIPTION_MSG); | ||
19 | 18 | ||
20 | const message = useInput(""); | 19 | const message = useInput(""); |
21 | 20 | ||
22 | - let messageObj, roomNum, messageText, messageTime, newMsgObj, messageArray; | 21 | + let messageObj, roomNum, messageArray; |
23 | 22 | ||
24 | const { data: getRoom } = useQuery(GET_ROOM_BY_NAME, { | 23 | const { data: getRoom } = useQuery(GET_ROOM_BY_NAME, { |
25 | variables: { roomName }, | 24 | variables: { roomName }, |
... | @@ -31,17 +30,26 @@ export default withRouter(({ location }) => { | ... | @@ -31,17 +30,26 @@ export default withRouter(({ location }) => { |
31 | roomNum = Number(roomId); | 30 | roomNum = Number(roomId); |
32 | } | 31 | } |
33 | 32 | ||
34 | - const { data: messageList } = useQuery(SEE_ALL_MESSAGE, { | 33 | + const { subscribeToMore, data: messageList } = useQuery(SEE_ALL_MESSAGE, { |
35 | variables: { roomId: roomNum }, | 34 | variables: { roomId: roomNum }, |
36 | }); | 35 | }); |
36 | + | ||
37 | if (messageList !== undefined) { | 37 | if (messageList !== undefined) { |
38 | messageList.seeAllMessage.map((e) => { | 38 | messageList.seeAllMessage.map((e) => { |
39 | if (e.sender.avatarUrl === "") { | 39 | if (e.sender.avatarUrl === "") { |
40 | + e.sender.avatarUrl = "../../imgs/defaultProfile.jpg"; | ||
40 | } | 41 | } |
41 | }); | 42 | }); |
42 | messageArray = messageList; | 43 | messageArray = messageList; |
43 | } | 44 | } |
44 | 45 | ||
46 | + let resultObj = subscribeToMore({ | ||
47 | + document: SUBSCRIPTION_MSG, | ||
48 | + updateQuery: (prev, { subscriptionData }) => { | ||
49 | + if (!subscriptionData.data) return prev; | ||
50 | + }, | ||
51 | + }); | ||
52 | + | ||
45 | const onSubmit = async (e) => { | 53 | const onSubmit = async (e) => { |
46 | e.preventDefault(); | 54 | e.preventDefault(); |
47 | if (message.value !== undefined || message.value !== "") { | 55 | if (message.value !== undefined || message.value !== "") { |
... | @@ -54,29 +62,18 @@ export default withRouter(({ location }) => { | ... | @@ -54,29 +62,18 @@ export default withRouter(({ location }) => { |
54 | }); | 62 | }); |
55 | if (!messageObj) { | 63 | if (!messageObj) { |
56 | toast.error("fail to create new message !, try again"); | 64 | toast.error("fail to create new message !, try again"); |
57 | - } else { | ||
58 | - const { | ||
59 | - data: { | ||
60 | - createMessage: { text, createdAt }, | ||
61 | - }, | ||
62 | - } = messageObj; | ||
63 | - messageText = text; | ||
64 | - messageTime = createdAt; | ||
65 | - newMsgObj = messageObj; | ||
66 | } | 65 | } |
67 | } catch { | 66 | } catch { |
68 | toast.error("text must be not empty"); | 67 | toast.error("text must be not empty"); |
69 | } | 68 | } |
70 | } | 69 | } |
71 | }; | 70 | }; |
71 | + | ||
72 | return ( | 72 | return ( |
73 | <ChatPresenter | 73 | <ChatPresenter |
74 | location={location} | 74 | location={location} |
75 | message={message} | 75 | message={message} |
76 | onSubmit={onSubmit} | 76 | onSubmit={onSubmit} |
77 | - messageText={messageText} | ||
78 | - messageTime={messageTime} | ||
79 | - newMsgObj={newMsgObj} | ||
80 | messageArray={messageArray} | 77 | messageArray={messageArray} |
81 | /> | 78 | /> |
82 | ); | 79 | ); | ... | ... |
... | @@ -90,17 +90,32 @@ const ChatScreenBox = styled.div` | ... | @@ -90,17 +90,32 @@ const ChatScreenBox = styled.div` |
90 | flex-direction: column; | 90 | flex-direction: column; |
91 | width: 100%; | 91 | width: 100%; |
92 | height: 100%; | 92 | height: 100%; |
93 | + overflow-y: scroll; | ||
94 | + &::-webkit-scrollbar { | ||
95 | + width: 10px; | ||
96 | + } | ||
97 | + &::-webkit-scrollbar-track { | ||
98 | + background-color: transparent; | ||
99 | + } | ||
100 | + &::-webkit-scrollbar-thumb { | ||
101 | + border-radius: 3px; | ||
102 | + background-color: gray; | ||
103 | + } | ||
104 | + &::-webkit-scrollbar-button { | ||
105 | + width: 0; | ||
106 | + height: 0; | ||
107 | + } | ||
93 | `; | 108 | `; |
94 | 109 | ||
95 | const InputContainer = styled.div` | 110 | const InputContainer = styled.div` |
96 | position: fixed; | 111 | position: fixed; |
97 | bottom: 0; | 112 | bottom: 0; |
98 | - justify-self: center; | 113 | + justify-content: center; |
99 | - padding: 10px; | 114 | + align-items: center; |
100 | - margin-bottom: 20px; | 115 | + width: 70%; |
116 | + margin: 10px; | ||
101 | display: flex; | 117 | display: flex; |
102 | flex-direction: row; | 118 | flex-direction: row; |
103 | - width: 70%; | ||
104 | form { | 119 | form { |
105 | width: 100%; | 120 | width: 100%; |
106 | button { | 121 | button { |
... | @@ -132,20 +147,10 @@ const StyledLink = styled(Link)` | ... | @@ -132,20 +147,10 @@ const StyledLink = styled(Link)` |
132 | } | 147 | } |
133 | `; | 148 | `; |
134 | 149 | ||
135 | -export default ({ | 150 | +export default ({ location, message, onSubmit, messageArray }) => { |
136 | - location, | ||
137 | - message, | ||
138 | - onSubmit, | ||
139 | - messageText, | ||
140 | - messageTime, | ||
141 | - newMsgObj, | ||
142 | - messageArray, | ||
143 | -}) => { | ||
144 | const { pathname } = location; | 151 | const { pathname } = location; |
145 | const roomName = pathname.slice(1, pathname.length); | 152 | const roomName = pathname.slice(1, pathname.length); |
146 | 153 | ||
147 | - console.log(messageArray); | ||
148 | - | ||
149 | return ( | 154 | return ( |
150 | <Wrapper> | 155 | <Wrapper> |
151 | <Header text={"KhuChat"} /> | 156 | <Header text={"KhuChat"} /> |
... | @@ -169,10 +174,14 @@ export default ({ | ... | @@ -169,10 +174,14 @@ export default ({ |
169 | <ChatScreenBox> | 174 | <ChatScreenBox> |
170 | {messageArray && | 175 | {messageArray && |
171 | messageArray.seeAllMessage.map((e) => ( | 176 | messageArray.seeAllMessage.map((e) => ( |
172 | - <Message text={e.text} time={e.createdAt} key={e.id} /> | 177 | + <Message |
178 | + text={e.text} | ||
179 | + time={e.createdAt} | ||
180 | + key={e.id} | ||
181 | + avatar={e.sender.avatarUrl} | ||
182 | + /> | ||
173 | ))} | 183 | ))} |
174 | - {newMsgObj && <Message text={messageText} time={messageTime} />} | 184 | + <InputContainer className="InputContainer"> |
175 | - <InputContainer> | ||
176 | <form onSubmit={onSubmit}> | 185 | <form onSubmit={onSubmit}> |
177 | <Input | 186 | <Input |
178 | placeholder={"Enter any words"} | 187 | placeholder={"Enter any words"} | ... | ... |
1 | import { gql } from "apollo-boost"; | 1 | import { gql } from "apollo-boost"; |
2 | 2 | ||
3 | export const SUBSCRIPTION_MSG = gql` | 3 | export const SUBSCRIPTION_MSG = gql` |
4 | - subscription subMessage { | 4 | + subscription { |
5 | subMessage { | 5 | subMessage { |
6 | id | 6 | id |
7 | text | 7 | text |
8 | + room { | ||
9 | + id | ||
10 | + name | ||
11 | + } | ||
8 | sender { | 12 | sender { |
9 | id | 13 | id |
10 | username | 14 | username |
15 | + avatarUrl | ||
11 | } | 16 | } |
12 | createdAt | 17 | createdAt |
13 | } | 18 | } | ... | ... |
-
Please register or login to post a comment