Skip to content

Commit

Permalink
Merge branch 'dev' into #768-rooms-realtime-update
Browse files Browse the repository at this point in the history
  • Loading branch information
predict-woo authored May 14, 2024
2 parents 5364ee0 + 88dcd7a commit d206a3c
Show file tree
Hide file tree
Showing 12 changed files with 141 additions and 83 deletions.
10 changes: 8 additions & 2 deletions packages/web/src/components/Chat/Header/SideMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ const SideMenu = ({ roomInfo, isOpen, setIsOpen }: SideMenuProps) => {
const onClickCallTaxi = useCallback(() => setIsOpenCallTaxi(true), []);
const onClickReport = useCallback(() => setIsOpenReport(true), []);

const isAlone = roomInfo.part.length === 1;

const styleBackground = {
position: "absolute" as any,
top: 0,
Expand Down Expand Up @@ -192,8 +194,12 @@ const SideMenu = ({ roomInfo, isOpen, setIsOpen }: SideMenuProps) => {
<SideMenuButton type="share" onClick={onClikcShare} />
<DottedLine />
<SideMenuButton type="taxi" onClick={onClickCallTaxi} />
<DottedLine />
<SideMenuButton type="report" onClick={onClickReport} />
{!isAlone && (
<>
<DottedLine />
<SideMenuButton type="report" onClick={onClickReport} />
</>
)}
</div>
<DottedLine />
<div css={styleNameSection} onClick={onClickCancel}>
Expand Down
98 changes: 58 additions & 40 deletions packages/web/src/components/Chat/MessagesBody/MessageSet/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { memo, useCallback } from "react";
import { memo, useCallback, useState } from "react";

import type { BotChat, LayoutType, UserChat } from "@/types/chat";

import { useValueRecoilState } from "@/hooks/useFetchRecoilState";

import { ModalChatReport } from "@/components/ModalPopup";
import ProfileImage from "@/components/User/ProfileImage";

import MessageAccount from "./MessageAccount";
Expand Down Expand Up @@ -58,12 +59,19 @@ type MessageSetProps = {
};

const MessageSet = ({ chats, layoutType, roomInfo }: MessageSetProps) => {
const [isOpenReport, setIsOpenReport] = useState<boolean>(false);
const { oid: userOid } = useValueRecoilState("loginInfo") || {};

const onClickProfileImage = useCallback(() => setIsOpenReport(true), []);

const authorId = chats?.[0]?.authorId;
const authorProfileUrl =
"authorProfileUrl" in chats?.[0] ? chats?.[0].authorProfileUrl : "";
const authorName = "authorName" in chats?.[0] ? chats?.[0].authorName : "";

const isBot = authorId === "bot";
const isAlone = roomInfo.part.length === 1;

const style = {
position: "relative" as any,
display: "flex",
Expand Down Expand Up @@ -96,6 +104,7 @@ const MessageSet = ({ chats, layoutType, roomInfo }: MessageSetProps) => {
alignItems: "flex-end",
gap: "4px",
};

const styleChat = useCallback(
(type: (UserChat | BotChat)["type"]) => ({
maxWidth: "max(75%, 210px)",
Expand Down Expand Up @@ -135,48 +144,57 @@ const MessageSet = ({ chats, layoutType, roomInfo }: MessageSetProps) => {
};

return (
<div css={style}>
<div css={styleProfileSection}>
{authorId !== userOid && (
<div
css={styleProfile}
onClick={() => {
/* @fixme @todo */
}}
>
{authorId === "bot" ? (
<TaxiIcon css={{ width: "100%", height: "100%" }} />
) : (
<ProfileImage url={authorProfileUrl} />
)}
</div>
)}
</div>
<div css={styleMessageSection}>
{authorId !== userOid && (
<div css={styleName} className="selectable">
{authorName}
</div>
)}
{chats.map((chat, index) => (
<div key={getChatUniquewKey(chat)} css={styleMessageWrap}>
<div css={styleChat(chat.type)}>
<MessageBody
type={chat.type}
content={chat.content}
roomInfo={roomInfo}
color={authorId === userOid ? theme.white : theme.black}
/>
<>
<div css={style}>
<div css={styleProfileSection}>
{authorId !== userOid && (
<div
css={{
...styleProfile,
cursor: !isBot && !isAlone ? "pointer" : undefined,
}}
onClick={() => !isBot && !isAlone && onClickProfileImage()}
>
{isBot ? (
<TaxiIcon css={{ width: "100%", height: "100%" }} />
) : (
<ProfileImage url={authorProfileUrl} />
)}
</div>
)}
</div>
<div css={styleMessageSection}>
{authorId !== userOid && (
<div css={styleName} className="selectable">
{authorName}
</div>
{index === chats.length - 1 && (
<div css={styleTime} className="selectable">
{dayjs(chat.time).format("H시 mm분")}
)}
{chats.map((chat, index) => (
<div key={getChatUniquewKey(chat)} css={styleMessageWrap}>
<div css={styleChat(chat.type)}>
<MessageBody
type={chat.type}
content={chat.content}
roomInfo={roomInfo}
color={authorId === userOid ? theme.white : theme.black}
/>
</div>
)}
</div>
))}
{index === chats.length - 1 && (
<div css={styleTime} className="selectable">
{dayjs(chat.time).format("H시 mm분")}
</div>
)}
</div>
))}
</div>
</div>
</div>
<ModalChatReport
roomInfo={roomInfo}
isOpen={isOpenReport}
onChangeIsOpen={setIsOpenReport}
userOid={authorId}
/>
</>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {

import type { Report } from "@/types/report";

import { useValueRecoilState } from "@/hooks/useFetchRecoilState";
import useIsTimeOver from "@/hooks/useIsTimeOver";
import { useAxios } from "@/hooks/useTaxiAPI";

Expand All @@ -32,7 +31,7 @@ import EditRoundedIcon from "@mui/icons-material/EditRounded";
type BodyChatReportSelectTypeProps = {
roomInfo: Room;
reportedId: Report["reportedId"];
clearReportedId: () => void;
setIsSelected: Dispatch<SetStateAction<boolean>>;
setIsSubmitted: Dispatch<SetStateAction<boolean>>;
};

Expand All @@ -45,12 +44,11 @@ const selectOptions = [
const BodyChatReportSelectType = ({
roomInfo,
reportedId,
clearReportedId,
setIsSelected,
setIsSubmitted,
}: BodyChatReportSelectTypeProps) => {
const axios = useAxios();
const setAlert = useSetRecoilState(alertAtom);
const { oid: userOid } = useValueRecoilState("loginInfo") || {};
const wrapRef = useRef<HTMLDivElement>(null);
const textareaRef = useRef<HTMLTextAreaElement>(null);
const [height, setHeight] = useState<CSSProperties["height"]>("28px");
Expand All @@ -76,10 +74,8 @@ const BodyChatReportSelectType = ({
? "기타 사유를 입력해주세요."
: type === "etc-reason" && !regExpTest.reportMsg(etcDetail)
? "기타 사유는 1500자 까지 입력이 허용됩니다."
: userOid === reportedUser?._id
? "나 자신은 신고할 수 없습니다."
: null,
[type, etcDetail, isDeparted, userOid, reportedUser]
[type, etcDetail, isDeparted, reportedUser]
);

const resizeEvent = useCallback(() => {
Expand Down Expand Up @@ -228,7 +224,7 @@ const BodyChatReportSelectType = ({
borderRadius: "8px",
...theme.font14,
}}
onClick={clearReportedId}
onClick={() => setIsSelected(false)}
>
이전
</Button>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Dispatch, SetStateAction, useState } from "react";
import { Dispatch, SetStateAction } from "react";

import type { Report } from "@/types/report";

import { useValueRecoilState } from "@/hooks/useFetchRecoilState";
import useIsTimeOver from "@/hooks/useIsTimeOver";

import Button from "@/components/Button";
Expand All @@ -15,17 +16,20 @@ import CheckRoundedIcon from "@mui/icons-material/CheckRounded";

type BodyChatReportSelectUserProps = {
roomInfo: Room;
reportedId: Nullable<Report["reportedId"]>;
setReportedId: Dispatch<SetStateAction<Nullable<Report["reportedId"]>>>;
setIsSelected: Dispatch<SetStateAction<boolean>>;
onChangeIsOpen?: (isOpen: boolean) => void;
};

const BodyChatReportSelectUser = ({
roomInfo,
reportedId,
setReportedId,
setIsSelected,
onChangeIsOpen,
}: BodyChatReportSelectUserProps) => {
const [selectedUser, setSelectedUser] =
useState<Nullable<Report["reportedId"]>>(null);
const { oid: userOid } = useValueRecoilState("loginInfo") || {};
const isDeparted = useIsTimeOver(dayServerToClient(roomInfo.time)); // 방 출발 여부

const styleText = {
Expand Down Expand Up @@ -80,26 +84,31 @@ const BodyChatReportSelectUser = ({
<div css={styleText}>신고할 사용자를 선택해주세요.</div>
<DottedLine />
<div css={styleUsers}>
{roomInfo.part.map((user) => (
<div
key={user._id}
css={styleUser}
onClick={() => setSelectedUser(user._id)}
>
<div
css={{
...styleCheckBox,
background:
selectedUser === user._id ? theme.purple : theme.purple_light,
}}
>
{selectedUser === user._id && (
<CheckRoundedIcon style={styleCheckBoxIcon} />
)}
</div>
<User value={user} isDeparted={isDeparted} />
</div>
))}
{roomInfo.part.map(
(user) =>
user._id !== userOid && (
<div
key={user._id}
css={styleUser}
onClick={() => setReportedId(user._id)}
>
<div
css={{
...styleCheckBox,
background:
reportedId === user._id
? theme.purple
: theme.purple_light,
}}
>
{reportedId === user._id && (
<CheckRoundedIcon style={styleCheckBoxIcon} />
)}
</div>
<User value={user} isDeparted={isDeparted} />
</div>
)
)}
</div>
<div css={styleButtons}>
<Button
Expand All @@ -122,8 +131,8 @@ const BodyChatReportSelectUser = ({
borderRadius: "8px",
...theme.font14_bold,
}}
onClick={() => setReportedId(selectedUser)}
disabled={!selectedUser}
onClick={() => setIsSelected(true)}
disabled={!reportedId}
>
다음
</Button>
Expand Down
14 changes: 10 additions & 4 deletions packages/web/src/components/ModalPopup/Body/BodyRoomSelection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,12 @@ const BodyRoomSelection = ({ roomInfo }: BodyRoomSelectionProps) => {
const isDepart = useIsTimeOver(dayServerToClient(roomInfo.time)); // 방 출발 여부

const requestJoin = useCallback(async () => {
if (isAlreadyPart) {
// 이미 참여 중인 방에서 버튼을 누르면 API 호출 관련 로직을 건너뛰고 해당 방으로 이동합니다.
history.push(`/myroom/${roomInfo._id}`);
return;
}
// 여기부터는 이미 참여 중인 방이 아닌 경우의 로직입니다.
if (onCall.current) return;
onCall.current = true;
await axios({
Expand Down Expand Up @@ -204,18 +210,18 @@ const BodyRoomSelection = ({ roomInfo }: BodyRoomSelectionProps) => {
{isLogin || isRoomFull || isDepart ? (
<Button
type="purple"
disabled={isRoomFull || isDepart || isAlreadyPart || isMaxPart}
disabled={(isRoomFull || isDepart || isMaxPart) && !isAlreadyPart}
css={{
padding: "10px 0 9px",
borderRadius: "8px",
...theme.font14_bold,
}}
onClick={requestJoin}
>
{isAlreadyPart
? "이미 참여 중입니다"
: isDepart
{isDepart && !isAlreadyPart
? "출발 시각이 현재 이전인 방은 참여할 수 없습니다"
: isAlreadyPart
? "이미 참여 중입니다 : 바로가기"
: isRoomFull
? "남은 인원이 0명인 방은 참여할 수 없습니다"
: isMaxPart
Expand Down
9 changes: 7 additions & 2 deletions packages/web/src/components/ModalPopup/ModalChatReport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,17 @@ const ModalChatReport = ({
}: ModalChatReportProps) => {
const [reportedId, setReportedId] =
useState<Nullable<Report["reportedId"]>>();
const [isSelected, setIsSelected] = useState<boolean>(false);
const [isSubmitted, setIsSubmitted] = useState<boolean>(false);

useEffect(() => {
if (userOid && roomInfo.part.find((user) => user._id === userOid)) {
setReportedId(userOid);
setIsSelected(true);
setIsSubmitted(false);
} else {
setReportedId(undefined);
setIsSelected(false);
setIsSubmitted(false);
}
}, [roomInfo, userOid, modalProps.isOpen]);
Expand All @@ -53,17 +56,19 @@ const ModalChatReport = ({
<ReportGmailerrorredRoundedIcon style={styleIcon} />
신고하기
</div>
{!reportedId ? (
{!reportedId || !isSelected ? (
<BodyChatReportSelectUser
roomInfo={roomInfo}
reportedId={reportedId}
setReportedId={setReportedId}
setIsSelected={setIsSelected}
onChangeIsOpen={modalProps?.onChangeIsOpen}
/>
) : !isSubmitted ? (
<BodyChatReportSelectType
roomInfo={roomInfo}
reportedId={reportedId}
clearReportedId={() => setReportedId(undefined)}
setIsSelected={setIsSelected}
setIsSubmitted={setIsSubmitted}
/>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class ChannelService {
updateUser(options) {
window.ChannelIO("updateUser", options);
}
openChat(message) {
window.ChannelIO("openChat", undefined, message);
}
shutdown() {
window.ChannelIO("shutdown");
}
Expand Down
Loading

0 comments on commit d206a3c

Please sign in to comment.