Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#625 create quest completion system #647

Merged
merged 16 commits into from
Sep 19, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/atoms/event2023FallInfo.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { Quest, QuestId } from "types/event2023fall";

import { atom } from "recoil";

export type Event2023FallInfoType = Nullable<{
creditAmount: number;
eventStatus: string[];
completedQuests: QuestId[];
ticket1Amount: number;
ticket2Amount: number;
quests: Quest[];
}>;

const event2023FallInfoAtom = atom<Event2023FallInfoType>({
Expand Down
62 changes: 61 additions & 1 deletion src/components/Event/EventProvider/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,65 @@
import { useEffect, useRef, useState } from "react";

import { QuestId } from "types/event2023fall";
import { PopupInAppNotification } from "types/notification";

import { useValueRecoilState } from "hooks/useFetchRecoilState";

import { ModalEvent2023FallMissionComplete } from "components/ModalPopup";

import { sendPopupInAppNotificationEventToFlutter } from "tools/sendEventToFlutter";

const EventProvider = () => {
return null;
const [isOpen, setIsOpen] = useState(false);

const { completedQuests, quests } =
useValueRecoilState("event2023FallInfo") || {};

const prevEventStatusRef = useRef<QuestId[]>();

useEffect(() => {
if (completedQuests && !prevEventStatusRef.current) {
prevEventStatusRef.current = completedQuests;
}
if (
!completedQuests ||
!prevEventStatusRef.current ||
!quests ||
prevEventStatusRef.current.length === completedQuests?.length
)
return;

let currentEventStatus = [...completedQuests];

prevEventStatusRef.current.forEach((event) => {
const ind = currentEventStatus.indexOf(event);
if (ind === -1) return;
currentEventStatus.splice(ind, 1);
});

currentEventStatus.forEach((id) => {
const event = quests.find((e) => e.id === id);
if (!event) return;
const popup: PopupInAppNotification = {
type: "default",
imageUrl: event.imageUrl,
title: event.name,
subtitle: event.description,
content: undefined,
button: undefined,
};
sendPopupInAppNotificationEventToFlutter(popup);
});

prevEventStatusRef.current = completedQuests;
predict-woo marked this conversation as resolved.
Show resolved Hide resolved
}, [completedQuests]);

return (
<ModalEvent2023FallMissionComplete
isOpen={isOpen}
onChangeIsOpen={setIsOpen}
/>
predict-woo marked this conversation as resolved.
Show resolved Hide resolved
);
};

export default EventProvider;
18 changes: 14 additions & 4 deletions src/components/ModalPopup/ModalChatPayment.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useCallback, useEffect, useMemo, useRef, useState } from "react";

import useAccountFromChats from "hooks/chat/useAccountFromChats";
import { useEvent2023FallQuestComplete } from "hooks/event/useEvent2023FallQuestComplete";
import { useValueRecoilState } from "hooks/useFetchRecoilState";
import { useAxios } from "hooks/useTaxiAPI";

Expand All @@ -22,7 +23,7 @@ import LocalAtmRoundedIcon from "@mui/icons-material/LocalAtmRounded";
import { ReactComponent as KakaoPayLogo } from "static/assets/serviceLogos/KakaoPayLogo.svg";
import { ReactComponent as TossLogo } from "static/assets/serviceLogos/TossLogo.svg";

type ModalChatSettlementProps = Omit<
type ModalChatPaymentProps = Omit<
14KGun marked this conversation as resolved.
Show resolved Hide resolved
Parameters<typeof Modal>[0],
"padding" | "children" | "onEnter"
> & {
Expand All @@ -31,12 +32,12 @@ type ModalChatSettlementProps = Omit<
account: ReturnType<typeof useAccountFromChats>;
};

const ModalChatSettlement = ({
const ModalChatPayment = ({
roomInfo,
account,
onRecall,
...modalProps
}: ModalChatSettlementProps) => {
}: ModalChatPaymentProps) => {
const axios = useAxios();
const setAlert = useSetRecoilState(alertAtom);
const { oid: userOid } = useValueRecoilState("loginInfo") || {};
Expand All @@ -49,6 +50,11 @@ const ModalChatSettlement = ({
[userOid, roomInfo]
);
const onCopy = useCallback(() => setIsCopied(true), [setIsCopied]);
//#region event2023Fall
const event2023FallQuestCompletePS =
useEvent2023FallQuestComplete("payingAndSending");
const event2023FallQuestCompleteP = useEvent2023FallQuestComplete("paying");
//#endregion

useEffect(() => {
if (isCopied) {
Expand All @@ -65,6 +71,10 @@ const ModalChatSettlement = ({
method: "post",
data: { roomId: roomInfo._id },
onSuccess: () => {
//#region event2023Fall
event2023FallQuestCompletePS();
event2023FallQuestCompleteP();
//#endregion
predict-woo marked this conversation as resolved.
Show resolved Hide resolved
modalProps.onChangeIsOpen?.(false);
onRecall?.();
},
Expand Down Expand Up @@ -209,4 +219,4 @@ const ModalChatSettlement = ({
);
};

export default ModalChatSettlement;
export default ModalChatPayment;
14 changes: 12 additions & 2 deletions src/components/ModalPopup/ModalChatSaveAccount.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useCallback, useEffect, useState } from "react";

import { useEvent2023FallQuestComplete } from "hooks/event/useEvent2023FallQuestComplete";
import {
useFetchRecoilState,
useValueRecoilState,
Expand Down Expand Up @@ -31,6 +32,10 @@ const ModalChatSaveAcount = ({
const { account: accountOrigin } = useValueRecoilState("loginInfo") || {};
const [account, setAccount] = useState<string>(accountDefault || "");
const fetchLoginInfo = useFetchRecoilState("loginInfo");
//#region event2023Fall
const event2023FallQuestComplete =
useEvent2023FallQuestComplete("accountChanging");
//#endregion

useEffect(() => setAccount(accountDefault || ""), [accountDefault]);

Expand All @@ -40,10 +45,15 @@ const ModalChatSaveAcount = ({
url: "/users/editAccount",
method: "post",
data: { account },
onSuccess: () => fetchLoginInfo(),
onSuccess: () => {
//#region event2023Fall
event2023FallQuestComplete();
//#endregion
fetchLoginInfo();
},
onError: () => setAlert("계좌번호 저장을 실패하였습니다."),
});
}, [account]);
}, [account, event2023FallQuestComplete]);

const styleTitle = {
...theme.font18,
Expand Down
8 changes: 8 additions & 0 deletions src/components/ModalPopup/ModalChatSettlement.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useMemo, useRef, useState } from "react";

import useSendMessage from "hooks/chat/useSendMessage";
import { useEvent2023FallQuestComplete } from "hooks/event/useEvent2023FallQuestComplete";
import { useValueRecoilState } from "hooks/useFetchRecoilState";
import { useAxios } from "hooks/useTaxiAPI";

Expand Down Expand Up @@ -39,6 +40,9 @@ const ModalChatSettlement = ({
const isValidAccount = useMemo(() => regExpTest.account(account), [account]);
const isRequesting = useRef<boolean>(false);
const sendMessage = useSendMessage(roomInfo._id, isRequesting);
const event2023FallQuestCompletePS =
useEvent2023FallQuestComplete("payingAndSending");
const event2023FallQuestCompleteS = useEvent2023FallQuestComplete("sending");

const onClickOk = () => {
if (isRequesting.current || !isValidAccount) return;
Expand All @@ -55,6 +59,10 @@ const ModalChatSettlement = ({
isRequesting.current = false;
if (account !== defaultAccount) openSaveAccountModal?.(account);
}
//#region event2023Fall
event2023FallQuestCompletePS();
event2023FallQuestCompleteS();
//#endregion
modalProps.onChangeIsOpen?.(false);
},
onError: () => {
Expand Down
7 changes: 6 additions & 1 deletion src/components/ModalPopup/ModalEvent2023FallItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,12 @@ const ModalEvent2023FallItem = ({
},
onError: () => setAlert("구매를 실패하였습니다."),
}),
[itemInfo._id, fetchItems, modalProps.onChangeIsOpen]
[
itemInfo._id,
fetchItems,
modalProps.onChangeIsOpen,
fetchEvent2023FallInfo,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

디펜던시 배열에 추가된 이유가 있을까요?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

초기에 initializalize 되기 전의 event2023FallInfo가 들어가버린 채로 memoization 될 수도 있을 것 같아 추가 했어요

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다른 useCallback 내에 있는 훅들도 모두 같은 방식으로 처리했습니다

]
);

const [isDisabled, buttonText] = useMemo(
Expand Down
9 changes: 9 additions & 0 deletions src/components/ModalPopup/ModalMypageModify.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import axiosOri from "axios";
import { useCallback, useEffect, useRef, useState } from "react";
import { useTranslation } from "react-i18next";

import { useEvent2023FallQuestComplete } from "hooks/event/useEvent2023FallQuestComplete";
import {
useFetchRecoilState,
useValueRecoilState,
Expand Down Expand Up @@ -152,6 +153,12 @@ const ModalMypageModify = ({

const loginInfo = useValueRecoilState("loginInfo");
const fetchLoginInfo = useFetchRecoilState("loginInfo");
//#region event2023Fall
const event2023FallQuestCompleteN =
useEvent2023FallQuestComplete("nicknameChanging");
const event2023FallQuestCompleteA =
useEvent2023FallQuestComplete("accountChanging");
//#endregion
const setAlert = useSetRecoilState(alertAtom);

useEffect(() => {
Expand All @@ -174,6 +181,7 @@ const ModalMypageModify = ({
method: "post",
data: { nickname },
onError: () => setAlert(t("page_modify.nickname_failed")),
onSuccess: () => event2023FallQuestCompleteN(),
predict-woo marked this conversation as resolved.
Show resolved Hide resolved
});
}
if (account !== loginInfo?.account) {
Expand All @@ -183,6 +191,7 @@ const ModalMypageModify = ({
method: "post",
data: { account },
onError: () => setAlert(t("page_modify.account_failed")),
onSuccess: () => event2023FallQuestCompleteA(),
predict-woo marked this conversation as resolved.
Show resolved Hide resolved
});
}
if (isNeedToUpdateLoginInfo) {
Expand Down
14 changes: 13 additions & 1 deletion src/components/ModalPopup/ModalRoomShare.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { useEvent2023FallQuestComplete } from "hooks/event/useEvent2023FallQuestComplete";

import Modal from "components/Modal";

import BodyRoomShare, { BodyRoomShareProps } from "./Body/BodyRoomShare";
Expand All @@ -17,6 +19,10 @@ const ModalRoomShare = ({
onChangeIsOpen,
roomInfo,
}: ModalRoomShareProps) => {
//#region event2023Fall
const event2023FallQuestComplete =
useEvent2023FallQuestComplete("roomSharing");
//#endregion
const styleTitle = {
...theme.font18,
display: "flex",
Expand All @@ -27,11 +33,17 @@ const ModalRoomShare = ({
fontSize: "21px",
margin: "0 4px 0 0",
};
//#region Event2023Fall
const onChangeIsOpenWithEvent2023Fall = (isOpen: boolean) => {
onChangeIsOpen?.(isOpen);
event2023FallQuestComplete();
};
//#endregion

return (
<Modal
isOpen={isOpen}
onChangeIsOpen={onChangeIsOpen}
onChangeIsOpen={onChangeIsOpenWithEvent2023Fall}
padding="16px 12px 12px"
>
<div css={styleTitle}>
Expand Down
24 changes: 24 additions & 0 deletions src/hooks/event/useEvent2023FallQuestComplete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { useCallback } from "react";

import { QuestId } from "types/event2023fall";
predict-woo marked this conversation as resolved.
Show resolved Hide resolved

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

export const useEvent2023FallQuestComplete = (id: QuestId) => {
const fetchEvent2023FallInfo = useFetchRecoilState("event2023FallInfo");

const { completedQuests, quests } =
useValueRecoilState("event2023FallInfo") || {};

return useCallback(() => {
predict-woo marked this conversation as resolved.
Show resolved Hide resolved
if (!completedQuests || !quests) return;
const questMaxCount =
quests?.find((quest) => quest.id === id)?.maxCount || 0;
const questCompletedCount =
completedQuests?.filter((questId) => questId === id).length || 0;
predict-woo marked this conversation as resolved.
Show resolved Hide resolved
questCompletedCount < questMaxCount && fetchEvent2023FallInfo();
}, [completedQuests, id, fetchEvent2023FallInfo]);
predict-woo marked this conversation as resolved.
Show resolved Hide resolved
};
19 changes: 18 additions & 1 deletion src/hooks/skeleton/useFlutterEventCommunicationEffect.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { useEffect, useState } from "react";

import { PopupInAppNotification } from "types/notification";

import {
useFetchRecoilState,
useValueRecoilState,
Expand Down Expand Up @@ -154,12 +156,27 @@ export const sendClipboardCopyEventToFlutter = async (value: string) => {
}
};

export const sendPopupInAppNotificationEventToFlutter = async (
value: PopupInAppNotification
) => {
console.log("fake notification call", value);
predict-woo marked this conversation as resolved.
Show resolved Hide resolved
if (!isWebViewInFlutter) return true;
try {
await window.flutter_inappwebview.callHandler(
"popup_inAppNotification",
value
);
} catch (e) {
console.error(e);
}
};

// 알림을 "on"으로 설정 시 Flutter에게 이벤트를 전달하고 앱의 알림 설정 여부를 반환받습니다.
export const sendPopupInstagramStoryShareToFlutter = async (value: {
backgroundLayerUrl: string;
stickerLayerUrl: string;
}) => {
console.log(value);
console.log("fake instagram call", value);
predict-woo marked this conversation as resolved.
Show resolved Hide resolved
if (!isWebViewInFlutter) return true;
try {
await window.flutter_inappwebview.callHandler(
Expand Down
8 changes: 8 additions & 0 deletions src/pages/Addroom/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { useEffect, useMemo, useRef, useState } from "react";
import { useCookies } from "react-cookie";
import { useHistory } from "react-router-dom";

import { useEvent2023FallQuestComplete } from "hooks/event/useEvent2023FallQuestComplete";
import {
useFetchRecoilState,
useValueRecoilState,
Expand Down Expand Up @@ -59,6 +60,10 @@ const AddRoom = () => {
const isLogin = !!useValueRecoilState("loginInfo")?.id;
const myRooms = useValueRecoilState("myRooms");
const fetchMyRooms = useFetchRecoilState("myRooms");
//#region event2023Fall
const event2023FallQuestComplete =
useEvent2023FallQuestComplete("firstRoomCreation");
//#endregion

useEffect(() => {
const expirationDate = new Date();
Expand Down Expand Up @@ -111,6 +116,9 @@ const AddRoom = () => {
},
onSuccess: () => {
fetchMyRooms();
//#region event2023Fall
event2023FallQuestComplete();
//#endregion
history.push("/myroom");
},
onError: () => setAlert("방 개설에 실패하였습니다."),
Expand Down
1 change: 1 addition & 0 deletions src/tools/sendEventToFlutter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export {
sendAuthLogoutEventToFlutter,
sendTryNotificationEventToFlutter,
sendClipboardCopyEventToFlutter,
sendPopupInAppNotificationEventToFlutter,
} from "hooks/skeleton/useFlutterEventCommunicationEffect";
Loading