Skip to content

Commit d9730b4

Browse files
authored
Merge pull request #124 from rnjshippo/dev
맥북 버그 해결 및 이모지 작업
2 parents ffa5167 + 2fae409 commit d9730b4

File tree

4 files changed

+129
-58
lines changed

4 files changed

+129
-58
lines changed

client/src/components/common/EmojiListModal/EmojiListModal.tsx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,31 @@
11
import React from 'react';
22
import styled from 'styled-components';
33
import { Thread } from '@/types/thread';
4-
import { flex } from '@/styles/mixin';
54
import { useChannelState, useEmojiState, useUserState } from '@/hooks';
65
import { useDispatch } from 'react-redux';
76
import { sendMessageRequest } from '@/store/modules/socket.slice';
87
import { SOCKET_MESSAGE_TYPE } from '@/utils/constants';
98

109
const Container = styled.div`
11-
${flex('center', 'flex-start', 'row')};
10+
display: grid;
11+
grid-template-columns: repeat(6, 1fr);
12+
`;
13+
14+
const EmojiBox = styled.div`
15+
cursor: pointer;
16+
transition: 0.3;
17+
&:hover {
18+
transition: 0.3;
19+
background-color: #b5e0fe;
20+
}
21+
border-radius: 5px;
1222
`;
1323

1424
const Emoji = styled.img`
1525
width: 22px;
1626
height: 22px;
27+
margin: 0.2rem;
28+
border-radius: 5px;
1729
user-select: none;
1830
cursor: pointer;
1931
`;
@@ -46,12 +58,9 @@ const EmojiListModal: React.FC<EmojiListModalProps> = ({ thread }: EmojiListModa
4658
<Container>
4759
{emojiList?.map((emoji) => {
4860
return (
49-
<Emoji
50-
key={emoji.id}
51-
src={emoji.url}
52-
alt="emoji url"
53-
onClick={() => clickEmojiHandler(Number(emoji.id))}
54-
/>
61+
<EmojiBox key={emoji.id}>
62+
<Emoji src={emoji.url} onClick={() => clickEmojiHandler(Number(emoji.id))} />
63+
</EmojiBox>
5564
);
5665
})}
5766
</Container>

client/src/components/common/ThreadInputBox/ThreadInputBox.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ const ThreadInputBox: React.FC<ThreadInputBoxProps> = ({ inputBoxType }: ThreadI
202202

203203
<TextArea
204204
onChange={handleChange}
205-
onKeyDown={handleKey}
205+
onKeyPress={handleKey}
206206
placeholder={parentId ? 'Reply...' : `Send a message ${current?.name}`}
207207
ref={commentRef}
208208
value={comment}

client/src/components/common/ThreadItem/EmojiBox/EmojiBoxItem/EmojiBoxItem.tsx

Lines changed: 68 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,43 +1,62 @@
1-
import React, { useEffect, useState } from 'react';
1+
import React, { useEffect, useRef, useState } from 'react';
22
import styled from 'styled-components';
33
import { EmojiOfThread, Thread } from '@/types/thread';
44
import { flex } from '@/styles/mixin';
55
import { useChannelState, useEmojiState, useUserState } from '@/hooks';
66
import { useDispatch } from 'react-redux';
77
import { SOCKET_MESSAGE_TYPE } from '@/utils/constants';
88
import { sendMessageRequest } from '@/store/modules/socket.slice';
9-
import { JoinedUser } from '@/types';
9+
import TooltipPopup from './TooltipPopup/TooltipPopup';
1010

11-
const Container = styled.div`
12-
background-color: ${(props) => props.color};
13-
box-shadow: inset 0 0 0 1px rgba(29, 155, 209);
14-
${flex('center', 'flex-start', 'row')};
11+
interface ContainerProps {
12+
isMine: boolean;
13+
}
14+
15+
const Container = styled.div<ContainerProps>`
16+
background-color: ${(props) => (props.isMine ? '#E2EFF4' : '#EFEFEF')};
17+
box-shadow: inset 0 0 0 1px ${(props) => (props.isMine ? '#1D9BD1' : '#EFEFEF')};
18+
${flex()};
1519
position: relative;
1620
cursor: pointer;
17-
padding: 0.15rem 0.4rem;
21+
width: 2.6rem;
22+
height: 1.6rem;
1823
border-radius: 999em;
1924
margin-right: 0.2rem;
2025
`;
21-
// EFEFEF
2226

2327
const EmojiToolTip = styled.div`
28+
width: 12rem;
29+
${flex('center', 'center', 'column')};
30+
padding: 0.8rem;
2431
background-color: black;
25-
/* color: #505050; */
2632
color: white;
2733
border: 1px solid black;
28-
visibility: hidden;
29-
position: absolute;
30-
z-index: 1;
31-
bottom: 2rem;
32-
width: 10rem;
33-
${Container}:hover & {
34-
visibility: visible;
35-
}
34+
border-radius: 8px;
3635
`;
3736

38-
const EmojiItem = styled.div``;
37+
const EmojiItem = styled.div`
38+
${flex()};
39+
`;
40+
const TooltipImg = styled.img`
41+
width: 36px;
42+
height: 36px;
43+
margin-bottom: 0.4rem;
44+
background-color: white;
45+
border-radius: 8px;
46+
padding: 4px;
47+
`;
3948

40-
const ToolTipDescribe = styled.div``;
49+
const ToolTipDescribe = styled.div`
50+
font-size: 0.9rem;
51+
word-break: break-all;
52+
`;
53+
54+
const EmojiCount = styled.span`
55+
font-size: 0.8rem;
56+
font-weight: 800;
57+
margin: 0 3px;
58+
color: ${(props) => props.theme.color.blue1};
59+
`;
4160

4261
interface EmojiBoxItemProps {
4362
emoji: EmojiOfThread;
@@ -49,13 +68,15 @@ const EmojiBoxItem: React.FC<EmojiBoxItemProps> = ({ emoji, thread }: EmojiBoxIt
4968
const { users, current } = useChannelState();
5069
const { emojiList } = useEmojiState();
5170
const dispatch = useDispatch();
52-
const [backgroundColor, setbackgroundColor] = useState('#EFEFEF');
71+
const [isMine, setIsMine] = useState(false);
5372

5473
useEffect(() => {
5574
if (userInfo && emoji.userList.includes(userInfo.id)) {
56-
setbackgroundColor('#E2EFF4');
75+
setIsMine(true);
76+
} else {
77+
setIsMine(false);
5778
}
58-
}, []);
79+
}, [emoji]);
5980

6081
const getUserListNameInEmoji = (emojiProp: EmojiOfThread) => {
6182
return emojiProp.userList.reduce((acc, userIdInEmojiOfThread, idx, arr) => {
@@ -83,7 +104,7 @@ const EmojiBoxItem: React.FC<EmojiBoxItemProps> = ({ emoji, thread }: EmojiBoxIt
83104
};
84105

85106
const getToolTipDescribe = (emojiId: number) => {
86-
return `reacted width ${getEmojiName(emojiId)}`;
107+
return `${getEmojiName(emojiId)}`;
87108
};
88109

89110
const getEmojiUrl = (emojiId: number) => {
@@ -104,36 +125,34 @@ const EmojiBoxItem: React.FC<EmojiBoxItemProps> = ({ emoji, thread }: EmojiBoxIt
104125
}),
105126
);
106127
}
107-
if (backgroundColor === '#EFEFEF') {
108-
return setbackgroundColor('#E2EFF4');
109-
}
110-
return setbackgroundColor('#EFEFEF');
128+
setIsMine((mine) => !mine);
111129
};
112130

131+
const ref = useRef<HTMLDivElement>(null);
132+
const [tooltipVisible, setTooltipVisible] = useState(false);
133+
113134
return (
114-
<Container color={backgroundColor} onClick={clickEmojiHandler}>
115-
<EmojiToolTip>
116-
<img
117-
key={`${emoji.id}ToolTip`}
118-
src={getEmojiUrl(emoji.id)}
119-
alt="emoji url"
120-
width="36px"
121-
height="36px"
122-
/>
123-
<ToolTipDescribe>
124-
{getUserListNameInEmoji(emoji)}
125-
{getToolTipDescribe(emoji.id)}
126-
</ToolTipDescribe>
127-
</EmojiToolTip>
135+
<Container
136+
isMine={isMine}
137+
onClick={clickEmojiHandler}
138+
ref={ref}
139+
onMouseEnter={() => setTooltipVisible(true)}
140+
onMouseLeave={() => setTooltipVisible(false)}
141+
>
142+
{ref.current && tooltipVisible && (
143+
<TooltipPopup anchorEl={ref.current} top={-10} left={-30}>
144+
<EmojiToolTip>
145+
<TooltipImg src={getEmojiUrl(emoji.id)} />
146+
<ToolTipDescribe>
147+
{getUserListNameInEmoji(emoji)}
148+
{`reacted with :${getToolTipDescribe(emoji.id)}:`}
149+
</ToolTipDescribe>
150+
</EmojiToolTip>
151+
</TooltipPopup>
152+
)}
128153
<EmojiItem>
129-
<img
130-
key={emoji.id}
131-
src={getEmojiUrl(emoji.id)}
132-
alt="emoji url"
133-
width="16px"
134-
height="16px"
135-
/>
136-
{emoji.userList && <span key={`${emoji.id}length`}>{emoji.userList.length}</span>}
154+
<img src={getEmojiUrl(emoji.id)} alt="emoji url" width="16px" height="16px" />
155+
{emoji.userList && <EmojiCount>{emoji.userList.length}</EmojiCount>}
137156
</EmojiItem>
138157
</Container>
139158
);
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React, { FC, PropsWithChildren } from 'react';
2+
import styled from 'styled-components';
3+
4+
interface ContainerProps {
5+
top?: string;
6+
left?: string;
7+
}
8+
9+
const Container = styled.div<ContainerProps>`
10+
position: fixed;
11+
top: ${(props) => props.top ?? 0};
12+
left: ${(props) => props.left ?? 0};
13+
border-radius: 5px;
14+
outline: 0;
15+
z-index: 15;
16+
transform: translateY(-100%);
17+
`;
18+
19+
interface TooltipProps {
20+
anchorEl: HTMLElement;
21+
top?: number;
22+
left?: number;
23+
}
24+
25+
const TooltipPopup: FC<PropsWithChildren<TooltipProps>> = ({
26+
children,
27+
anchorEl,
28+
top = 0,
29+
left = 0,
30+
}: PropsWithChildren<TooltipProps>) => {
31+
const parentBox = anchorEl.getBoundingClientRect();
32+
33+
const TOP = top + parentBox.top;
34+
const LEFT = left + parentBox.left;
35+
36+
return (
37+
<Container top={`${TOP}px`} left={`${LEFT}px`}>
38+
{children}
39+
</Container>
40+
);
41+
};
42+
43+
export default TooltipPopup;

0 commit comments

Comments
 (0)