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 all 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
5 changes: 0 additions & 5 deletions src/components/Event/EventProvider/index.tsx

This file was deleted.

16 changes: 12 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,9 @@ const ModalChatSettlement = ({
[userOid, roomInfo]
);
const onCopy = useCallback(() => setIsCopied(true), [setIsCopied]);
//#region event2023Fall
const event2023FallQuestComplete = useEvent2023FallQuestComplete();
//#endregion

useEffect(() => {
if (isCopied) {
Expand All @@ -65,6 +69,10 @@ const ModalChatSettlement = ({
method: "post",
data: { roomId: roomInfo._id },
onSuccess: () => {
//#region event2023Fall
event2023FallQuestComplete("payingAndSending");
event2023FallQuestComplete("paying");
//#endregion
modalProps.onChangeIsOpen?.(false);
onRecall?.();
},
Expand Down Expand Up @@ -209,4 +217,4 @@ const ModalChatSettlement = ({
);
};

export default ModalChatSettlement;
export default ModalChatPayment;
13 changes: 11 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,9 @@ const ModalChatSaveAcount = ({
const { account: accountOrigin } = useValueRecoilState("loginInfo") || {};
const [account, setAccount] = useState<string>(accountDefault || "");
const fetchLoginInfo = useFetchRecoilState("loginInfo");
//#region event2023Fall
const event2023FallQuestComplete = useEvent2023FallQuestComplete();
//#endregion

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

Expand All @@ -40,10 +44,15 @@ const ModalChatSaveAcount = ({
url: "/users/editAccount",
method: "post",
data: { account },
onSuccess: () => fetchLoginInfo(),
onSuccess: () => {
//#region event2023Fall
event2023FallQuestComplete("accountChanging");
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
event2023FallQuestComplete("accountChanging");
if (account !== "") event2023FallQuestComplete("accountChanging");

//#endregion
fetchLoginInfo();
},
onError: () => setAlert("계좌번호 저장을 실패하였습니다."),
});
}, [account]);
}, [account, event2023FallQuestComplete]);

const styleTitle = {
...theme.font18,
Expand Down
6 changes: 6 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,7 @@ const ModalChatSettlement = ({
const isValidAccount = useMemo(() => regExpTest.account(account), [account]);
const isRequesting = useRef<boolean>(false);
const sendMessage = useSendMessage(roomInfo._id, isRequesting);
const event2023FallQuestComplete = useEvent2023FallQuestComplete();
Copy link
Member

Choose a reason for hiding this comment

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

주석 !


const onClickOk = () => {
if (isRequesting.current || !isValidAccount) return;
Expand All @@ -55,6 +57,10 @@ const ModalChatSettlement = ({
isRequesting.current = false;
if (account !== defaultAccount) openSaveAccountModal?.(account);
}
//#region event2023Fall
event2023FallQuestComplete("payingAndSending");
event2023FallQuestComplete("sending");
//#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
6 changes: 6 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,9 @@ const ModalMypageModify = ({

const loginInfo = useValueRecoilState("loginInfo");
const fetchLoginInfo = useFetchRecoilState("loginInfo");
//#region event2023Fall
const event2023FallQuestComplete = useEvent2023FallQuestComplete();
//#endregion
const setAlert = useSetRecoilState(alertAtom);

useEffect(() => {
Expand All @@ -174,6 +178,7 @@ const ModalMypageModify = ({
method: "post",
data: { nickname },
onError: () => setAlert(t("page_modify.nickname_failed")),
onSuccess: () => event2023FallQuestComplete("nicknameChanging"), // event2023Fall
Copy link
Member

Choose a reason for hiding this comment

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

이거 주석 //#region Event2023Fall 사용해주세요

});
}
if (account !== loginInfo?.account) {
Expand All @@ -183,6 +188,7 @@ const ModalMypageModify = ({
method: "post",
data: { account },
onError: () => setAlert(t("page_modify.account_failed")),
onSuccess: () => event2023FallQuestComplete("accountChanging"), // event2023Fall
Copy link
Member

Choose a reason for hiding this comment

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

동일합니다

});
}
if (isNeedToUpdateLoginInfo) {
Expand Down
13 changes: 12 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,9 @@ const ModalRoomShare = ({
onChangeIsOpen,
roomInfo,
}: ModalRoomShareProps) => {
//#region event2023Fall
const event2023FallQuestComplete = useEvent2023FallQuestComplete();
//#endregion
const styleTitle = {
...theme.font18,
display: "flex",
Expand All @@ -27,11 +32,17 @@ const ModalRoomShare = ({
fontSize: "21px",
margin: "0 4px 0 0",
};
//#region Event2023Fall
const onChangeIsOpenWithEvent2023Fall = (isOpen: boolean) => {
onChangeIsOpen?.(isOpen);
!isOpen && event2023FallQuestComplete("roomSharing");
};
//#endregion

return (
<Modal
isOpen={isOpen}
onChangeIsOpen={onChangeIsOpen}
onChangeIsOpen={onChangeIsOpenWithEvent2023Fall}
padding="16px 12px 12px"
>
<div css={styleTitle}>
Expand Down
4 changes: 4 additions & 0 deletions src/components/Skeleton/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ReactNode, useMemo } from "react";
import { useLocation } from "react-router-dom";

import { useEventEffect } from "hooks/event/useEventEffect";
import useCSSVariablesEffect from "hooks/skeleton/useCSSVariablesEffect";
import useChannelTalkEffect from "hooks/skeleton/useChannelTalkEffect";
import useFirebaseMessagingEffect from "hooks/skeleton/useFirebaseMessagingEffect";
Expand Down Expand Up @@ -63,6 +64,9 @@ const Skeleton = ({ children }: SkeletonProps) => {
[pathname]
);

//#region event2023Fall
useEventEffect();
//#endregion
useSyncRecoilStateEffect(); // loginIngo, taxiLocations, myRooms, notificationOptions 초기화 및 동기화
useI18nextEffect();
useScrollRestorationEffect();
Expand Down
28 changes: 28 additions & 0 deletions src/hooks/event/useEvent2023FallQuestComplete.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useCallback } from "react";

import type { QuestId } from "types/event2023fall";

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

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

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

return useCallback(
(id: QuestId) => {
if (!completedQuests || !quests) return;
const questMaxCount =
quests?.find((quest) => quest.id === id)?.maxCount || 0;
const questCompletedCount = completedQuests?.filter(
(questId) => questId === id
).length;
questCompletedCount < questMaxCount && fetchEvent2023FallInfo();
},
[completedQuests, fetchEvent2023FallInfo, quests]
);
};
40 changes: 40 additions & 0 deletions src/hooks/event/useEventEffect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { useEffect, useRef } from "react";

import type { QuestId } from "types/event2023fall";

import { useValueRecoilState } from "hooks/useFetchRecoilState";

import { sendPopupInAppNotificationEventToFlutter } from "tools/sendEventToFlutter";

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

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

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

const questsForCompare = [...completedQuests];
prevEventStatusRef.current.forEach((questId) => {
const index = questsForCompare.indexOf(questId);
if (index < 0) return;
questsForCompare.splice(index, 1);
});
questsForCompare.forEach((questId) => {
const quest = quests.find(({ id }) => id === questId);
if (!quest) return;
sendPopupInAppNotificationEventToFlutter({
type: "default",
imageUrl: quest.imageUrl,
title: "퀘스트 완료",
subtitle: quest.name,
content: quest.description,
button: { text: "확인하기", path: "/event/2023fall-missions" },
});
});
prevEventStatusRef.current = completedQuests;
}, [completedQuests]);
};
25 changes: 24 additions & 1 deletion src/hooks/skeleton/useFlutterEventCommunicationEffect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,12 +154,35 @@ export const sendClipboardCopyEventToFlutter = async (value: string) => {
}
};

export const sendPopupInAppNotificationEventToFlutter = async (
value: (
| { type: "chat"; profileUrl?: string; imageUrl?: never }
| { type: "default"; imageUrl?: string; profileUrl?: never }
) & {
title?: string;
subtitle?: string;
content?: string;
button?: { text: string; path: string };
}
) => {
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
2 changes: 0 additions & 2 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { CookiesProvider } from "react-cookie";
import { createRoot } from "react-dom/client";
import { BrowserRouter as Router } from "react-router-dom";

import EventProvider from "components/Event/EventProvider";
import Loading from "components/Loading";
import ModalProvider from "components/Modal/ModalProvider";
import Skeleton from "components/Skeleton";
Expand All @@ -23,7 +22,6 @@ const App = () => (
<SocketToastProvider />
<AlertProvider />
<ModalProvider />
<EventProvider />
<Skeleton>
<Suspense fallback={<Loading center />}>
<Routes />
Expand Down
7 changes: 7 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,9 @@ const AddRoom = () => {
const isLogin = !!useValueRecoilState("loginInfo")?.id;
const myRooms = useValueRecoilState("myRooms");
const fetchMyRooms = useFetchRecoilState("myRooms");
//#region event2023Fall
const event2023FallQuestComplete = useEvent2023FallQuestComplete();
//#endregion

useEffect(() => {
const expirationDate = new Date();
Expand Down Expand Up @@ -111,6 +115,9 @@ const AddRoom = () => {
},
onSuccess: () => {
fetchMyRooms();
//#region event2023Fall
event2023FallQuestComplete("firstRoomCreation");
//#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
Loading