Skip to content

Commit

Permalink
๐Ÿ”€ Merge pull request #31 from GleamingStar/dev/1.0.2
Browse files Browse the repository at this point in the history
1.0.2 ๋ฐฐํฌ
  • Loading branch information
GleamingStar authored Mar 28, 2022
2 parents c0a7c08 + 606d284 commit ae30b16
Show file tree
Hide file tree
Showing 30 changed files with 481 additions and 95 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
- [ ] ๋ฌธ์ œ ๋ชฉ๋ก ์ถ”๊ฐ€
- [ ] [`<Entrance />`](https://github.com/GleamingStar/web-catchmind/issues/13) ๊ธฐ๋Šฅ ๋ฐ ๋””์ž์ธ ๊ฐœ์„ 
- [ ] [`<Lobby />`](https://github.com/GleamingStar/web-catchmind/issues/11) ๋””์ž์ธ ๊ฐœ์„ 
- [ ] [`<Game />`](https://github.com/GleamingStar/web-catchmind/issues/17) ๊ธฐ๋Šฅ ๋ฐ ๋””์ž์ธ ๊ฐœ์„ 
- [ ] [์ตœ์ ํ™”](https://github.com/GleamingStar/web-catchmind/issues/15)
- [ ] ๋ฆฌํŒฉํ† ๋ง
- [ ] README ๊ฐœ์„ 
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "catch-mind",
"version": "1.0.1",
"version": "1.0.2",
"description": "drawing and guessing game web application",
"scripts": {
"start": "webpack --mode development --config ./webpack.server.js && node dist/server.js",
Expand Down
18 changes: 17 additions & 1 deletion src/client/atom/canvasAtom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import socket from 'client/config/socket';
import { CANVAS_SIZE } from 'shared/constant';
import { TCanvas, TColor } from 'shared/types';

const isMobileChrome = /Chrome/g.test(navigator.userAgent) && /Mobile Safari/g.test(navigator.userAgent);

export const contextAtom = atom<CanvasRenderingContext2D>({
key: 'canvasContext',
default: null,
Expand All @@ -25,7 +27,21 @@ export const contextAtom = atom<CanvasRenderingContext2D>({
ctx.closePath();
});

socket.on('canvas/reset', () => ctx.clearRect(0, 0, CANVAS_SIZE, CANVAS_SIZE));
const reset = () => ctx.clearRect(0, 0, CANVAS_SIZE, CANVAS_SIZE);

const MobileChromeReset = () => {
reset();
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(0, 0);
ctx.globalCompositeOperation = 'destination-out';
ctx.stroke();
ctx.closePath();
};

const resetHandler = isMobileChrome ? MobileChromeReset : reset;

socket.on('canvas/reset', resetHandler);

socket.on('canvas/update/response', (canvas: string) => {
const img = new Image();
Expand Down
42 changes: 42 additions & 0 deletions src/client/atom/gameAtom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,45 @@ export const isPainterSelector = selector({
key: 'isPainter',
get: ({ get }) => (get(accountAtom)?.id === get(gameAtom)?.painter.id) === (get(gameAtom) !== null),
});

export const resultAtom = atom<TGame['score']>({
key: 'result',
default: [],
effects: [
({ setSelf }) => {
socket.on('game/result', setSelf);

return () => {
socket.off('game/result', setSelf);
};
},
],
});

export const isEndAtom = atom({
key: 'isEnd',
default: false,
effects: [
({ setSelf, resetSelf }) => {
const RESET_TIMER = 5000;

let timer;

const endHandler = () => {
clearTimeout(timer);
setSelf(true);
timer = setTimeout(resetSelf, RESET_TIMER);
};

socket.on('game/end', endHandler);
socket.on('room/leave', resetSelf)
socket.on('game/set/start', resetSelf);

return () => {
socket.off('game/end', endHandler);
socket.off('room/leave', resetSelf)
socket.off('game/set/start', resetSelf);
};
},
],
});
91 changes: 80 additions & 11 deletions src/client/atom/miscAtom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,21 @@ export const roomAlertAtom = atom({
],
});

export const userCountAtom = atom({
key: 'userCount',
default: 0,
effects: [
({ setSelf }) => {
socket.on('usercount', setSelf);
socket.emit('usercount');

return () => {
socket.off('usercount', setSelf);
};
},
],
});

export const disconnectAlertAtom = atom({
key: 'disconnectAlert',
default: false,
Expand All @@ -50,25 +65,79 @@ export const disconnectAlertAtom = atom({
],
});

const throttle = (callback, delay) => {
let previousCall = new Date().getTime();
export const zoomOutAlertAtom = atom({
key: 'zoomOutAlert',
default: visualViewport.width < 499,
effects: [
({ setSelf }) => {
const evCache: Array<PointerEvent> = [];
let prevDiff = -1;

return (...args) => {
const time = new Date().getTime();
const donwHandler = (e: PointerEvent) => evCache.push(e);

if (time - previousCall >= delay) {
previousCall = time;
callback(...args);
}
};
};
const moveHandler = (e: PointerEvent) => {
for (let i = 0; i < evCache.length; i++) {
if (e.pointerId == evCache[i].pointerId) {
evCache[i] = e;
break;
}
}

if (evCache.length == 2) {
const curDiff = Math.abs(evCache[0].clientX - evCache[1].clientX);

if (prevDiff > 0 && curDiff < prevDiff) {
setSelf(false);
cancel();
}

prevDiff = curDiff;
}
};

const resetHandler = ({ pointerId }: PointerEvent) => {
for (let i = 0; i < evCache.length; i++) {
if (evCache[i].pointerId == pointerId) {
evCache.splice(i, 1);
break;
}
}
if (evCache.length < 2) prevDiff = -1;
};

const cancel = () => {
window.removeEventListener('pointerdown', donwHandler);
window.removeEventListener('pointermove', moveHandler);
window.removeEventListener('pointerup', resetHandler);
window.removeEventListener('pointercancel', resetHandler);
window.removeEventListener('pointerout', resetHandler);
window.removeEventListener('pointerleave', resetHandler);
};

window.addEventListener('pointerdown', donwHandler);
window.addEventListener('pointermove', moveHandler);
window.addEventListener('pointerup', resetHandler);
window.addEventListener('pointercancel', resetHandler);
window.addEventListener('pointerout', resetHandler);
window.addEventListener('pointerleave', resetHandler);

return () => {
cancel();
};
},
],
});

export const isPortraitAtom = atom({
key: 'isPortrait',
default: window.innerWidth < 800,
effects: [
({ setSelf }) => {
const resizeHandler = throttle(() => setSelf(window.innerWidth < 800), 100);
let timer;
const resizeHandler = () => {
clearTimeout(timer);
timer = setTimeout(() => setSelf(window.innerWidth < 800), 100);
};
window.addEventListener('resize', resizeHandler);

return () => {
Expand Down
38 changes: 5 additions & 33 deletions src/client/components/entrance/Entrance.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import styled from 'styled-components';
import { ChangeEvent, useState } from 'react';
import { useRecoilState, useRecoilValue } from 'recoil';
import { useRecoilState } from 'recoil';
import { BsFillPersonPlusFill, BsGithub } from 'react-icons/bs';
import { disconnectAlertAtom, loginAlertAtom } from 'client/atom/miscAtom';
import { loginAlertAtom } from 'client/atom/miscAtom';
import socket from 'client/config/socket';
import { LOGIN_ALERT_MESSAGE, MAX_USER_NAME_LENGTH } from 'shared/constant';
import DisconnectAlert from './alert/DisconnectAlert';
import ZoomOutAlert from './alert/ZoomOutAlert';

const EntranceWrapper = styled.div`
display: flex;
Expand Down Expand Up @@ -78,25 +80,6 @@ const GitHubButton = styled.div`
cursor: pointer;
`;
const DisconnectAlertWrapper = styled.div<{ isActivated: boolean }>`
position: absolute;
top: 50px;
left: 50%;
padding: 10px;
border-radius: 12px;
border: solid 2px #cdb699;
transform: ${({ isActivated }) => `translate(-50%,${isActivated ? 0 : -140}px)`};
white-space: pre-line;
transition: 1s;
`;
const DisconnectAlertParagraph = styled.div`
color: #596e79;
white-space: nowrap;
& + & {
margin-top: 5px;
}
`;

const Entrance = () => {
const [inputValue, setInputValue] = useState('');
Expand Down Expand Up @@ -137,23 +120,12 @@ const Entrance = () => {
</Login>
<LoginAlert>{alert}</LoginAlert>
<DisconnectAlert />
<ZoomOutAlert />
<GitHubButton>
<BsGithub size={30} onClick={() => window.open('https://github.com/GleamingStar/web-catchmind')} />
</GitHubButton>
</EntranceWrapper>
);
};

const DisconnectAlert = () => {
const isDisconnected = useRecoilValue(disconnectAlertAtom);

return (
<DisconnectAlertWrapper isActivated={isDisconnected}>
<DisconnectAlertParagraph>์†Œ์ผ“ ์—ฐ๊ฒฐ์ด ์ข…๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.</DisconnectAlertParagraph>
<DisconnectAlertParagraph>๋„คํŠธ์›Œํฌ ์ด์ƒ ํ˜น์€ ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•œ ์„œ๋ฒ„์ข…๋ฃŒ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.</DisconnectAlertParagraph>
<DisconnectAlertParagraph>๋ฌธ์ œ๊ฐ€ ์ง€์†๋  ์‹œ ์šฐ์ธกํ•˜๋‹จ ๊นƒํ—ˆ๋ธŒ๋กœ ์ œ๋ณดํ•ด์ฃผ์„ธ์š”.</DisconnectAlertParagraph>
</DisconnectAlertWrapper>
);
};

export default Entrance;
36 changes: 36 additions & 0 deletions src/client/components/entrance/alert/DisconnectAlert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import styled from 'styled-components';
import { useRecoilValue } from 'recoil';
import { disconnectAlertAtom } from 'client/atom/miscAtom';

const DisconnectAlertWrapper = styled.div<{ isActivated: boolean }>`
position: absolute;
top: 50px;
left: 50%;
padding: 10px;
border-radius: 12px;
border: solid 2px #cdb699;
transform: ${({ isActivated }) => `translate(-50%,${isActivated ? 0 : -140}px)`};
transition: transform 1s ease-out;
`;
const Paragraph = styled.div`
color: #596e79;
white-space: nowrap;
& + & {
margin-top: 5px;
}
`;

const DisconnectAlert = () => {
const isDisconnected = useRecoilValue(disconnectAlertAtom);

return (
<DisconnectAlertWrapper isActivated={isDisconnected}>
<Paragraph>์†Œ์ผ“ ์—ฐ๊ฒฐ์ด ์ข…๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.</Paragraph>
<Paragraph>๋„คํŠธ์›Œํฌ ์ด์ƒ ํ˜น์€ ์—…๋ฐ์ดํŠธ๋ฅผ ์œ„ํ•œ ์„œ๋ฒ„์ข…๋ฃŒ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.</Paragraph>
<Paragraph>๋ฌธ์ œ๊ฐ€ ์ง€์†๋  ์‹œ ์šฐ์ธกํ•˜๋‹จ ๊นƒํ—ˆ๋ธŒ๋กœ ์ œ๋ณดํ•ด์ฃผ์„ธ์š”.</Paragraph>
</DisconnectAlertWrapper>
);
};

export default DisconnectAlert;
41 changes: 41 additions & 0 deletions src/client/components/entrance/alert/ZoomOutAlert.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import styled from 'styled-components';
import { useRecoilValue } from 'recoil';
import { zoomOutAlertAtom } from 'client/atom/miscAtom';

const ratio = visualViewport.width / 500;

const ZoomOutAlertWrapper = styled.div<{ isActivated: boolean }>`
position: fixed;
top: ${ratio * 15}px;
left: ${ratio * 250}px;
padding: ${ratio * 10}px;
border-radius: 10px;
border: solid 2px #cdb699;
font-size: ${ratio * 15}px;
transform: ${({ isActivated }) => `translate(-50%, ${isActivated ? 0 : -105 * ratio}px)`};
transition: transform 0.8s ease-out;
`;
const Paragraph = styled.div`
color: #596e79;
white-space: nowrap;
& + & {
margin-top: 5px;
}
`;

const ZoomOutAlert = () => {
const isActivated = useRecoilValue(zoomOutAlertAtom);

return (
<ZoomOutAlertWrapper isActivated={isActivated}>
<Paragraph>์ด ์‚ฌ์ดํŠธ๋Š” ๋ชจ๋ฐ”์ผ ํ™˜๊ฒฝ์—์„œ ๊ฐ€๋กœ 500px์— ๋งž์ถฐ ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค.</Paragraph>
<Paragraph>ํ™”๋ฉด์„ ์ถ•์†Œํ•ด ์›์น˜์•Š๋Š” ์Šคํฌ๋กค์„ ๋ฐฉ์ง€ํ•ด์ฃผ์„ธ์š”.</Paragraph>
<Paragraph>๊ทธ๋ฆผ์„ ๊ทธ๋ฆฌ๋Š” ๊ณผ์ •์—์„œ ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.</Paragraph>
</ZoomOutAlertWrapper>
);
};

export default ZoomOutAlert;
6 changes: 4 additions & 2 deletions src/client/components/game/chattingRoom/ChattingRoom.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ const ChattingRoomWrapper = styled.div`
right: 0;
height: 100%;
@media screen and (max-width: 800px) {
top: 500px;
@media screen and (max-width: 800px) and (max-height: 645px) {
opacity: 0.5;
}
display: flex;
flex-direction: column;
transition: opacity 0.5s;
`;

const ChattingRoom = () => (
Expand Down
Loading

0 comments on commit ae30b16

Please sign in to comment.