minsung

Merge branch 'master' of https://bitbucket.org/vel1024/capstone

# Conflicts:
#	back/Dockerfile
#	back/prisma/Dockerfile
......@@ -9,7 +9,11 @@ RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSI
&& tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz
<<<<<<< HEAD
ENTRYPOINT [ "dockerize", "-wait", "tcp://root:prisma@mysql:3306/prisma:3306", "-timeout", "120s" ]
=======
ENTRYPOINT [ "dockerize", "-wait", "tcp://root:prisma@mysql:3306/prisma:3306", "-timeout", "60s" ]
>>>>>>> 81d693438b3dd8e67a7daefac47486362f102999
COPY package*.json ./
COPY prisma ./prisma/
......
......@@ -2242,14 +2242,6 @@
"graphql-playground-html": "1.6.12"
}
},
"graphql-subscriptions": {
"version": "0.5.8",
"resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz",
"integrity": "sha512-0CaZnXKBw2pwnIbvmVckby5Ge5e2ecmjofhYCdyeACbCly2j3WXDP/pl+s+Dqd2GQFC7y99NB+53jrt55CKxYQ==",
"requires": {
"iterall": "^1.2.1"
}
},
"graphql-tools": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/graphql-tools/-/graphql-tools-4.0.7.tgz",
......@@ -2323,6 +2315,16 @@
"graphql-tools": "^4.0.0",
"graphql-upload": "^8.0.0",
"subscriptions-transport-ws": "^0.9.8"
},
"dependencies": {
"graphql-subscriptions": {
"version": "0.5.8",
"resolved": "https://registry.npmjs.org/graphql-subscriptions/-/graphql-subscriptions-0.5.8.tgz",
"integrity": "sha512-0CaZnXKBw2pwnIbvmVckby5Ge5e2ecmjofhYCdyeACbCly2j3WXDP/pl+s+Dqd2GQFC7y99NB+53jrt55CKxYQ==",
"requires": {
"iterall": "^1.2.1"
}
}
}
},
"has": {
......
......@@ -9,7 +9,11 @@ RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSI
&& tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz
<<<<<<< HEAD
ENTRYPOINT [ "dockerize", "-wait", "tcp://root:prisma@mysql:3306/prisma:3306", "-timeout", "120s" ]
=======
ENTRYPOINT [ "dockerize", "-wait", "tcp://root:prisma@mysql:3306/prisma:3306", "-timeout", "60s" ]
>>>>>>> 81d693438b3dd8e67a7daefac47486362f102999
COPY ./ ./prisma/
......
import { prisma, isAuthenticated } from "../../../utils";
import { NEW_MESSAGE } from "../../../topics";
export default {
Mutation: {
createMessage: async (_, args, { request }) => {
createMessage: async (_, args, { request, pubsub }) => {
isAuthenticated(request);
const { user } = request;
const { message, roomId } = args;
......@@ -46,6 +47,11 @@ export default {
} else {
throw new Error("There is no room");
}
if (messageObj !== undefined) {
pubsub.publish(NEW_MESSAGE, { subMessage: messageObj });
}
return messageObj;
},
},
......
import { ONE_TO_ONE_MESSAGE } from "../../../topics";
import { NEW_MESSAGE } from "../../../topics";
export default {
Subscription: {
subMessage: {
subscribe: async (_, __, { pubsub }) => {
return pubsub.asyncIterator(ONE_TO_ONE_MESSAGE);
return pubsub.asyncIterator(NEW_MESSAGE);
},
},
},
......
export const ONE_TO_ONE_MESSAGE = "one-to-one message";
export const NEW_MESSAGE = "new message";
......
import React from "react";
import styled from "styled-components";
//import { parse, format } from "date-fns";
import ProfileIcon from "./ProfileIcon";
const MessageWrapper = styled.div`
display: flex;
justify-content: flex-end;
justify-content: flex-start;
align-items: center;
padding: 20px 10px;
margin-top: 20px;
......@@ -13,6 +13,11 @@ const MessageWrapper = styled.div`
const MsgContainer = styled.div`
display: flex;
flex-direction: row;
`;
const ColumnBox = styled.div`
display: flex;
flex-direction: column;
`;
......@@ -20,9 +25,7 @@ const MsgBox = styled.div`
display: flex;
justify-content: center;
align-items: center;
background-color: #54a0ff;
color: white;
border-radius: 20px;
color: black;
margin-bottom: 10px;
`;
......@@ -42,16 +45,19 @@ const Time = styled.span`
font-size: 15px;
`;
export default ({ text }) => {
export default ({ text, avatar }) => {
return (
<MessageWrapper className="MessageWrapper">
<MsgContainer>
<MsgBox>
<Msg> {text} </Msg>
</MsgBox>
<TimeBox>
<Time></Time>
</TimeBox>
<ProfileIcon avatar={avatar} />
<ColumnBox>
<MsgBox>
<Msg> {text} </Msg>
</MsgBox>
<TimeBox>
<Time>1</Time>
</TimeBox>
</ColumnBox>
</MsgContainer>
</MessageWrapper>
);
......
import React from "react";
import styled from "styled-components";
import defaultProfile from "../imgs/defaultProfile.jpg";
const ProfileIconBox = styled.div`
display: flex;
......@@ -15,10 +14,10 @@ const ProfileIcon = styled.img`
src: ${(props) => props.theme.defaultProfile};
`;
export default () => {
export default ({ avatar }) => {
return (
<ProfileIconBox>
<ProfileIcon src={defaultProfile} />
<ProfileIconBox className="ProfileIconBox">
<ProfileIcon src={avatar} />
</ProfileIconBox>
);
};
......
......@@ -6,20 +6,19 @@ import {
CREATE_MESSAGE,
GET_ROOM_BY_NAME,
SEE_ALL_MESSAGE,
SUBSCRIPTION_MSG,
} from "./ChatQueries";
import useInput from "../../Hooks/useInput";
import { toast } from "react-toastify";
//import defaultProfile from "../imgs/defaultProfile.jpg";
export default withRouter(({ location }) => {
const { pathname } = location;
const roomName = pathname.slice(1, pathname.length);
const [createMsg] = useMutation(CREATE_MESSAGE);
//const { data } = useSubscription(SUBSCRIPTION_MSG);
const message = useInput("");
let messageObj, roomNum, messageText, messageTime, newMsgObj, messageArray;
let messageObj, roomNum, messageArray;
const { data: getRoom } = useQuery(GET_ROOM_BY_NAME, {
variables: { roomName },
......@@ -31,17 +30,26 @@ export default withRouter(({ location }) => {
roomNum = Number(roomId);
}
const { data: messageList } = useQuery(SEE_ALL_MESSAGE, {
const { subscribeToMore, data: messageList } = useQuery(SEE_ALL_MESSAGE, {
variables: { roomId: roomNum },
});
if (messageList !== undefined) {
messageList.seeAllMessage.map((e) => {
if (e.sender.avatarUrl === "") {
e.sender.avatarUrl = "../../imgs/defaultProfile.jpg";
}
});
messageArray = messageList;
}
let resultObj = subscribeToMore({
document: SUBSCRIPTION_MSG,
updateQuery: (prev, { subscriptionData }) => {
if (!subscriptionData.data) return prev;
},
});
const onSubmit = async (e) => {
e.preventDefault();
if (message.value !== undefined || message.value !== "") {
......@@ -54,29 +62,18 @@ export default withRouter(({ location }) => {
});
if (!messageObj) {
toast.error("fail to create new message !, try again");
} else {
const {
data: {
createMessage: { text, createdAt },
},
} = messageObj;
messageText = text;
messageTime = createdAt;
newMsgObj = messageObj;
}
} catch {
toast.error("text must be not empty");
}
}
};
return (
<ChatPresenter
location={location}
message={message}
onSubmit={onSubmit}
messageText={messageText}
messageTime={messageTime}
newMsgObj={newMsgObj}
messageArray={messageArray}
/>
);
......
......@@ -90,17 +90,32 @@ const ChatScreenBox = styled.div`
flex-direction: column;
width: 100%;
height: 100%;
overflow-y: scroll;
&::-webkit-scrollbar {
width: 10px;
}
&::-webkit-scrollbar-track {
background-color: transparent;
}
&::-webkit-scrollbar-thumb {
border-radius: 3px;
background-color: gray;
}
&::-webkit-scrollbar-button {
width: 0;
height: 0;
}
`;
const InputContainer = styled.div`
position: fixed;
bottom: 0;
justify-self: center;
padding: 10px;
margin-bottom: 20px;
justify-content: center;
align-items: center;
width: 70%;
margin: 10px;
display: flex;
flex-direction: row;
width: 70%;
form {
width: 100%;
button {
......@@ -132,20 +147,10 @@ const StyledLink = styled(Link)`
}
`;
export default ({
location,
message,
onSubmit,
messageText,
messageTime,
newMsgObj,
messageArray,
}) => {
export default ({ location, message, onSubmit, messageArray }) => {
const { pathname } = location;
const roomName = pathname.slice(1, pathname.length);
console.log(messageArray);
return (
<Wrapper>
<Header text={"KhuChat"} />
......@@ -169,10 +174,14 @@ export default ({
<ChatScreenBox>
{messageArray &&
messageArray.seeAllMessage.map((e) => (
<Message text={e.text} time={e.createdAt} key={e.id} />
<Message
text={e.text}
time={e.createdAt}
key={e.id}
avatar={e.sender.avatarUrl}
/>
))}
{newMsgObj && <Message text={messageText} time={messageTime} />}
<InputContainer>
<InputContainer className="InputContainer">
<form onSubmit={onSubmit}>
<Input
placeholder={"Enter any words"}
......
import { gql } from "apollo-boost";
export const SUBSCRIPTION_MSG = gql`
subscription subMessage {
subscription {
subMessage {
id
text
room {
id
name
}
sender {
id
username
avatarUrl
}
createdAt
}
......
......@@ -7,6 +7,7 @@ export default createGlobalStyle`
box-sizing: border-box;
}
html, body {
overflow: hidden;
height: 100vh;
}
a {
......