From ee67570d2861c5302adf0e8c12165f992803fb8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9A=94=EC=88=A0=ED=86=A0=EB=81=BC?= Date: Thu, 3 Oct 2024 14:07:44 +0900 Subject: [PATCH] =?UTF-8?q?[FIX]=20=EB=A7=88=EC=9D=B4=EA=B7=B8=EB=A0=88?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EC=9D=B4=ED=9B=84=20=ED=83=80=EC=9E=85?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A6=BD=ED=8A=B8=20=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=20=EB=B0=8F=20=EC=84=9C=EB=B9=84=EC=8A=A4?= =?UTF-8?q?=EC=9B=8C=EC=BB=A4=20=EC=97=90=EB=9F=AC=EB=A5=BC=20=ED=95=B4?= =?UTF-8?q?=EA=B2=B0=20(#100)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * ♻ refactor: 랜덤 디펜스 컴포넌트에서 메시지를 보내는 대신 데이터 업데이트 함수를 직접 사용하도록 변경 * 🛠 fix: 잘못된 public 리소스들의 경로를 올바르게 변경 * 🛠 fix: 스토리지 변경을 감지하는 로직의 타입이 잘못된 부분을 수정 * 🛠 fix: 서비스워커가 메시지를 비동기적으로 응답해야 하는 상황에서만 true를 리턴하도록 수정 * 🛠 fix: 마이그레이션 이후 TypeScript 변경에 따른 타입 에러를 해결 # Conflicts: # components/RandomDefenseCreateMenu/DifficultyAdjustMenu/TierSlider/TierSlider.stories.tsx --- .../AppearanceFieldsetMenu.styled.ts | 2 +- .../AppearanceFieldsetMenu.tsx | 4 +-- components/HiderMenu/HiderFieldsetMenu.tsx | 2 +- .../InspectResultIcon/InspectResultIcon.tsx | 4 +-- .../LeftSlideToast/LeftSlideToast.stories.tsx | 10 +++--- components/LeftSlideToast/LeftSlideToast.tsx | 8 ++--- components/MenuTitle/MenuTitle.tsx | 4 +-- .../OptionsDataManageMenu.stories.tsx | 5 +-- .../OptionsDataResetModal.stories.tsx | 6 ++-- .../OptionsDataUploadModal.stories.tsx | 6 ++-- .../OptionsDataUploadModal.tsx | 4 +-- .../TierPresetButton/TierPresetButton.tsx | 4 +-- components/Widget/Widget.tsx | 14 ++++---- components/common/Fieldset/Fieldset.tsx | 2 +- .../common/IconButton/IconButton.styled.ts | 2 +- components/common/IconButton/IconButton.tsx | 4 +-- components/common/Input/Input.tsx | 2 +- components/common/Modal/Modal.stories.tsx | 19 +++++----- components/common/Modal/Modal.tsx | 2 +- components/common/Radio/Radio.tsx | 2 +- components/common/Textarea/Textarea.tsx | 30 ++++++++-------- .../RandomDefenseSection.tsx | 2 +- entrypoints/background/main.ts | 14 ++++++-- hooks/useRandomDefenseSection.ts | 35 +++++++------------ hooks/useTotamjungThemeState.ts | 5 +-- hooks/widget/useRandomDefense.ts | 11 +++--- hooks/widget/useWidget.ts | 4 +-- types/toast.ts | 4 +-- wxt.config.ts | 1 + 29 files changed, 107 insertions(+), 105 deletions(-) diff --git a/components/AppearanceFieldsetMenu/AppearanceFieldsetMenu.styled.ts b/components/AppearanceFieldsetMenu/AppearanceFieldsetMenu.styled.ts index 473ff680..994df8c5 100644 --- a/components/AppearanceFieldsetMenu/AppearanceFieldsetMenu.styled.ts +++ b/components/AppearanceFieldsetMenu/AppearanceFieldsetMenu.styled.ts @@ -13,6 +13,6 @@ export const Container = styled.div` export const FontText = styled.p<{ $fontFamily: string; $fontSize: string }>` color: ${({ theme }) => theme.color.LEMON}; - font-size: ${({ $fontSize }) => $fontSize ?? '16px'}; + font-size: ${({ $fontSize }) => $fontSize}; font-family: ${({ $fontFamily }) => $fontFamily}; `; diff --git a/components/AppearanceFieldsetMenu/AppearanceFieldsetMenu.tsx b/components/AppearanceFieldsetMenu/AppearanceFieldsetMenu.tsx index 45d91268..e29ffb01 100644 --- a/components/AppearanceFieldsetMenu/AppearanceFieldsetMenu.tsx +++ b/components/AppearanceFieldsetMenu/AppearanceFieldsetMenu.tsx @@ -50,7 +50,7 @@ const AppearanceFieldsetMenu = () => {
{ name="shouldHideTier" options={FONT_INFOS.map(({ name, fontFamily, fontSize }, index) => ({ label: ( - + {name} ), diff --git a/components/HiderMenu/HiderFieldsetMenu.tsx b/components/HiderMenu/HiderFieldsetMenu.tsx index 1fa9810d..c11b8272 100644 --- a/components/HiderMenu/HiderFieldsetMenu.tsx +++ b/components/HiderMenu/HiderFieldsetMenu.tsx @@ -30,7 +30,7 @@ const HiderFieldsetMenu = () => { { const { theme, icon } = props; const iconSrc = icon === 'check' - ? browser.runtime.getURL('inspect-result-check.png') - : browser.runtime.getURL('inspect-result-question.png'); + ? browser.runtime.getURL('/inspect-result-check.png') + : browser.runtime.getURL('/inspect-result-question.png'); const alt = icon === 'check' ? '이 문제는 알고 있는 알고리즘만으로 풀 수 있는 문제입니다.' diff --git a/components/LeftSlideToast/LeftSlideToast.stories.tsx b/components/LeftSlideToast/LeftSlideToast.stories.tsx index a6429882..8dd87e78 100644 --- a/components/LeftSlideToast/LeftSlideToast.stories.tsx +++ b/components/LeftSlideToast/LeftSlideToast.stories.tsx @@ -56,7 +56,7 @@ export const Default: Story = { ), ], args: { - mainIconSrc: browser.runtime.getURL('dice.png'), + mainIconSrc: browser.runtime.getURL('/dice.png'), theme: 'none', progress: 65, title: '테스트 제목입니다.', @@ -96,7 +96,7 @@ export const TotamjungTheme: Story = { ), ], args: { - mainIconSrc: browser.runtime.getURL('dice.png'), + mainIconSrc: browser.runtime.getURL('/dice.png'), theme: 'totamjung', progress: 65, title: '테스트 제목입니다.', @@ -136,7 +136,7 @@ export const MultipleDescriptions: Story = { ), ], args: { - mainIconSrc: browser.runtime.getURL('dice.png'), + mainIconSrc: browser.runtime.getURL('/dice.png'), theme: 'none', progress: 65, title: '필요할 경우 여러 개의 설명을 사용할 수도 있습니다.', @@ -158,7 +158,7 @@ export const NoDescription: Story = { ), ], args: { - mainIconSrc: browser.runtime.getURL('dice.png'), + mainIconSrc: browser.runtime.getURL('/dice.png'), theme: 'none', progress: 65, title: '설명이 필요 없다고요? 그럼 메시지만 간결하게 전달해도 문제 없죠.', @@ -179,7 +179,7 @@ export const VeryLongDescription: Story = { ), ], args: { - mainIconSrc: browser.runtime.getURL('dice.png'), + mainIconSrc: browser.runtime.getURL('/dice.png'), theme: 'none', progress: 65, title: '매우 긴 설명', diff --git a/components/LeftSlideToast/LeftSlideToast.tsx b/components/LeftSlideToast/LeftSlideToast.tsx index 1b988723..04ff82d5 100644 --- a/components/LeftSlideToast/LeftSlideToast.tsx +++ b/components/LeftSlideToast/LeftSlideToast.tsx @@ -1,11 +1,11 @@ import * as S from './LeftSlideToast.styled'; import { CheckIcon, CloseIcon } from '@/assets/svg'; -import type { SVGProps } from 'react'; +import type { SVGProps, ReactElement } from 'react'; import { TotamjungTheme } from '@/types/totamjungTheme'; import CircleProgressBar from '@/components/common/CircleProgressBar'; interface LeftSlideToastProps { - mainIconSrc: string | SVGProps; + mainIconSrc: string | ReactElement>; theme: TotamjungTheme; progress: number; title: string; @@ -47,9 +47,7 @@ const LeftSlideToast = (props: LeftSlideToastProps) => { {listedDescriptions.map((description, index) => ( - - {description} - + {description} ))} diff --git a/components/MenuTitle/MenuTitle.tsx b/components/MenuTitle/MenuTitle.tsx index 1ad4aba4..c378ae9d 100644 --- a/components/MenuTitle/MenuTitle.tsx +++ b/components/MenuTitle/MenuTitle.tsx @@ -1,8 +1,8 @@ -import type { SVGProps } from 'react'; +import type { SVGProps, ReactElement } from 'react'; import * as S from './MenuTitle.styled'; interface MenuTitleProps { - iconSrc: string | SVGProps; + iconSrc: string | ReactElement>; title: string; } diff --git a/components/OptionsDataManageMenu/OptionsDataManageMenu.stories.tsx b/components/OptionsDataManageMenu/OptionsDataManageMenu.stories.tsx index aea76aef..6d490670 100644 --- a/components/OptionsDataManageMenu/OptionsDataManageMenu.stories.tsx +++ b/components/OptionsDataManageMenu/OptionsDataManageMenu.stories.tsx @@ -7,7 +7,6 @@ import OptionsDataManageMenu from './OptionsDataManageMenu'; const meta = { title: 'components/OptionsDataManageMenu', component: OptionsDataManageMenu, - argTypes: {}, } satisfies Meta; export default meta; @@ -15,7 +14,5 @@ export default meta; type Story = StoryObj; export const Default: Story = { - args: { - onChange: () => {}, - }, + args: {}, }; diff --git a/components/OptionsDataManageMenu/OptionsDataResetModal/OptionsDataResetModal.stories.tsx b/components/OptionsDataManageMenu/OptionsDataResetModal/OptionsDataResetModal.stories.tsx index ed86f013..3f0ce9bb 100644 --- a/components/OptionsDataManageMenu/OptionsDataResetModal/OptionsDataResetModal.stories.tsx +++ b/components/OptionsDataManageMenu/OptionsDataResetModal/OptionsDataResetModal.stories.tsx @@ -42,7 +42,7 @@ export const Default: Story = { disabled={false} ariaLabel="모달 열기" onClick={() => { - setIsOpen(() => true); + setIsOpen(true); }} /> false); + setIsOpen(false); }} onReset={() => { alert( 'onReset()을 실행시켰습니다. 이는 사용자가 초기화를 수락한 경우입니다.', ); - setIsOpen(() => false); + setIsOpen(false); }} /> diff --git a/components/OptionsDataManageMenu/OptionsDataUploadModal/OptionsDataUploadModal.stories.tsx b/components/OptionsDataManageMenu/OptionsDataUploadModal/OptionsDataUploadModal.stories.tsx index d1fff662..308aad64 100644 --- a/components/OptionsDataManageMenu/OptionsDataUploadModal/OptionsDataUploadModal.stories.tsx +++ b/components/OptionsDataManageMenu/OptionsDataUploadModal/OptionsDataUploadModal.stories.tsx @@ -42,7 +42,7 @@ export const Default: Story = { disabled={false} ariaLabel="모달 열기" onClick={() => { - setIsOpen(() => true); + setIsOpen(true); }} /> false); + setIsOpen(false); }} onUpload={() => { alert( 'onUpload()을 실행시켰습니다. 이는 사용자가 초기화를 수락한 경우입니다.', ); - setIsOpen(() => false); + setIsOpen(false); }} /> diff --git a/components/OptionsDataManageMenu/OptionsDataUploadModal/OptionsDataUploadModal.tsx b/components/OptionsDataManageMenu/OptionsDataUploadModal/OptionsDataUploadModal.tsx index aa8f755c..deea8f02 100644 --- a/components/OptionsDataManageMenu/OptionsDataUploadModal/OptionsDataUploadModal.tsx +++ b/components/OptionsDataManageMenu/OptionsDataUploadModal/OptionsDataUploadModal.tsx @@ -15,7 +15,7 @@ interface OptionsDataUploadModalProps { const DATA_UPLOAD_CONFIRM_TEXT = '숙지했습니다'; -const OptionsDataResetModal = (props: OptionsDataUploadModalProps) => { +const OptionsDataUploadModal = (props: OptionsDataUploadModalProps) => { const { open, onClose, onUpload } = props; const { inputValue, isSameWithConfirmText, updateInputValue } = useConfirmInput({ @@ -85,4 +85,4 @@ const OptionsDataResetModal = (props: OptionsDataUploadModalProps) => { ); }; -export default OptionsDataResetModal; +export default OptionsDataUploadModal; diff --git a/components/RandomDefenseCreateMenu/DifficultyAdjustMenu/TierPresetButtonList/TierPresetButton/TierPresetButton.tsx b/components/RandomDefenseCreateMenu/DifficultyAdjustMenu/TierPresetButtonList/TierPresetButton/TierPresetButton.tsx index c73c7cd6..e7b1ffbb 100644 --- a/components/RandomDefenseCreateMenu/DifficultyAdjustMenu/TierPresetButtonList/TierPresetButton/TierPresetButton.tsx +++ b/components/RandomDefenseCreateMenu/DifficultyAdjustMenu/TierPresetButtonList/TierPresetButton/TierPresetButton.tsx @@ -38,7 +38,7 @@ const TIER_RANGE = { }, } as const; -const TierPresetButtonProps = (props: TierPresetButtonProps) => { +const TierPresetButton = (props: TierPresetButtonProps) => { const { rank, onClick } = props; return ( @@ -57,4 +57,4 @@ const TierPresetButtonProps = (props: TierPresetButtonProps) => { ); }; -export default TierPresetButtonProps; +export default TierPresetButton; diff --git a/components/Widget/Widget.tsx b/components/Widget/Widget.tsx index 01cf2dde..0a8e8bf2 100644 --- a/components/Widget/Widget.tsx +++ b/components/Widget/Widget.tsx @@ -60,7 +60,7 @@ const Widget = (props: WidgetProps) => { onClick={openOptionsPage} > @@ -74,7 +74,7 @@ const Widget = (props: WidgetProps) => { onClick={toggleTotamjungTheme} > @@ -87,7 +87,7 @@ const Widget = (props: WidgetProps) => { onClick={performRandomDefenseByClick} > @@ -102,9 +102,9 @@ const Widget = (props: WidgetProps) => { src={ shouldShowInspectIcon ? hasUnknownAlgorithms - ? browser.runtime.getURL('inspect-result-question.png') - : browser.runtime.getURL('inspect-result-check.png') - : browser.runtime.getURL('search.png') + ? browser.runtime.getURL('/inspect-result-question.png') + : browser.runtime.getURL('/inspect-result-check.png') + : browser.runtime.getURL('/search.png') } /> @@ -117,7 +117,7 @@ const Widget = (props: WidgetProps) => { $widgetTheme={theme} > diff --git a/components/common/Fieldset/Fieldset.tsx b/components/common/Fieldset/Fieldset.tsx index 0b16b342..01e9c6e8 100644 --- a/components/common/Fieldset/Fieldset.tsx +++ b/components/common/Fieldset/Fieldset.tsx @@ -25,7 +25,7 @@ const Fieldset = (props: FieldsetProps) => { options, checkedValue, disabled, - isVertical, + isVertical = false, onChange, } = props; diff --git a/components/common/IconButton/IconButton.styled.ts b/components/common/IconButton/IconButton.styled.ts index bc5df479..aa3a1787 100644 --- a/components/common/IconButton/IconButton.styled.ts +++ b/components/common/IconButton/IconButton.styled.ts @@ -33,7 +33,7 @@ export const Button = styled.button<{ transition: 0.2s; `; -export const Text = styled.span<{ $size: 'large' | 'medium'; $color: string }>` +export const Text = styled.span<{ $size: 'large' | 'medium' }>` font-size: ${({ $size }) => ($size === 'large' ? '20px' : '16px')}; font-weight: 600; text-align: center; diff --git a/components/common/IconButton/IconButton.tsx b/components/common/IconButton/IconButton.tsx index 9fd8ace0..7191580b 100644 --- a/components/common/IconButton/IconButton.tsx +++ b/components/common/IconButton/IconButton.tsx @@ -1,12 +1,12 @@ import * as S from './IconButton.styled'; -import { SVGProps } from 'react'; +import type { ReactElement, SVGProps } from 'react'; interface CommonIconButtonProps { name: string; size: 'large' | 'medium'; width?: string; color: string; - iconSrc?: string | SVGProps; + iconSrc?: string | ReactElement>; disabled: boolean; ariaLabel: string; autoFocus?: boolean; diff --git a/components/common/Input/Input.tsx b/components/common/Input/Input.tsx index 84dd949b..81a1e031 100644 --- a/components/common/Input/Input.tsx +++ b/components/common/Input/Input.tsx @@ -17,7 +17,7 @@ interface InputProps { onChange: (event: ChangeEvent) => void; } -const Input = forwardRef((props: InputProps, ref) => { +const Input = forwardRef((props, ref) => { const { width, hasError, textAlign, ariaLabel, ...rest } = props; return ( diff --git a/components/common/Modal/Modal.stories.tsx b/components/common/Modal/Modal.stories.tsx index 45cf0b9a..12656ce3 100644 --- a/components/common/Modal/Modal.stories.tsx +++ b/components/common/Modal/Modal.stories.tsx @@ -76,7 +76,7 @@ export const TextModal: Story = { disabled={false} ariaLabel="모달 열기" onClick={() => { - setIsOpen(() => true); + setIsOpen(true); }} /> @@ -85,6 +85,7 @@ export const TextModal: Story = { args: { open: false, title: '테스트용 알림창', + onClose: () => {}, }, }; @@ -123,7 +124,7 @@ export const TextModal: Story = { * ariaLabel="취소" * onClick={() => { * alert('민트초코의 위대함을 모르는 당신이 불쌍해'); - * setIsOpen(() => false); + * setIsOpen(false); * }} * /> * { * alert('그럴 바엔 치약을 3,000개 구매하는 게 낫지 않나요?'); - * setIsOpen(() => false); + * setIsOpen(false); * }} * /> * @@ -178,7 +179,7 @@ export const TextWithControlButtons: Story = { ariaLabel="취소" onClick={() => { alert('민트초코의 위대함을 모르는 당신이 불쌍해'); - setIsOpen(() => false); + setIsOpen(false); }} /> { alert('그럴 바엔 치약을 3,000개 구매하는 게 낫지 않나요?'); - setIsOpen(() => false); + setIsOpen(false); }} /> @@ -204,7 +205,7 @@ export const TextWithControlButtons: Story = { disabled={false} ariaLabel="모달 열기" onClick={() => { - setIsOpen(() => true); + setIsOpen(true); }} /> @@ -213,6 +214,7 @@ export const TextWithControlButtons: Story = { args: { open: false, title: '테스트용 알림창', + onClose: () => {}, }, }; @@ -256,7 +258,7 @@ export const VeryLongTitle: Story = { disabled={false} ariaLabel="전혀 안 궁금하지만 이해했다고 대충 대답하기" onClick={() => { - setIsOpen(() => false); + setIsOpen(false); }} /> @@ -269,7 +271,7 @@ export const VeryLongTitle: Story = { disabled={false} ariaLabel="모달 열기" onClick={() => { - setIsOpen(() => true); + setIsOpen(true); }} /> @@ -278,5 +280,6 @@ export const VeryLongTitle: Story = { args: { open: false, title: '테스트용 알림창', + onClose: () => {}, }, }; diff --git a/components/common/Modal/Modal.tsx b/components/common/Modal/Modal.tsx index d4a7e69a..c8d46bff 100644 --- a/components/common/Modal/Modal.tsx +++ b/components/common/Modal/Modal.tsx @@ -19,7 +19,7 @@ const Modal = (props: PropsWithChildren) => { createPortal( - + {title} diff --git a/components/common/Radio/Radio.tsx b/components/common/Radio/Radio.tsx index 8e4c4803..f81dad42 100644 --- a/components/common/Radio/Radio.tsx +++ b/components/common/Radio/Radio.tsx @@ -18,7 +18,7 @@ interface RadioWithoutValue { } const Radio = (props: RadioProps) => { - const { checked, disabled } = props; + const { checked, disabled = false } = props; return ( diff --git a/components/common/Textarea/Textarea.tsx b/components/common/Textarea/Textarea.tsx index 2d340dad..63221cd0 100644 --- a/components/common/Textarea/Textarea.tsx +++ b/components/common/Textarea/Textarea.tsx @@ -16,20 +16,22 @@ interface TextareaProps { onChange: (event: ChangeEvent) => void; } -const Textarea = forwardRef((props: TextareaProps, ref) => { - const { width, height, hasError, ariaLabel, ...rest } = props; +const Textarea = forwardRef( + (props, ref) => { + const { width, height, hasError, ariaLabel, ...rest } = props; - return ( - - ); -}); + return ( + + ); + }, +); export default Textarea; diff --git a/components/sections/RandomDefenseSection/RandomDefenseSection.tsx b/components/sections/RandomDefenseSection/RandomDefenseSection.tsx index f9d4c591..3b54da57 100644 --- a/components/sections/RandomDefenseSection/RandomDefenseSection.tsx +++ b/components/sections/RandomDefenseSection/RandomDefenseSection.tsx @@ -24,7 +24,7 @@ const RandomDefenseSection = (props: OptionsSectionProps) => { diff --git a/entrypoints/background/main.ts b/entrypoints/background/main.ts index 290b384e..bd23f419 100644 --- a/entrypoints/background/main.ts +++ b/entrypoints/background/main.ts @@ -1,5 +1,6 @@ import { isObject } from '@/types/typeGuards'; import { COMMANDS } from '@/constants/commands'; +import { browser } from 'wxt/browser/chrome'; import { fetchCheckedAlgorithmIds, saveCheckedAlgorithmIds, @@ -70,6 +71,7 @@ const executeBackground = () => { fetchCheckedAlgorithmIds().then((result) => { sendResponse(result); }); + return true; } if (command === COMMANDS.SAVE_CHECKED_ALGORITHM_IDS) { @@ -84,6 +86,7 @@ const executeBackground = () => { fetchRandomDefenseHistory().then((result) => { sendResponse(result); }); + return true; } if (command === COMMANDS.SAVE_RANDOM_DEFENSE_HISTORY) { @@ -100,6 +103,7 @@ const executeBackground = () => { fetchQuickSlots().then((result) => { sendResponse(result); }); + return true; } if (command === COMMANDS.SAVE_QUICK_SLOTS) { @@ -120,6 +124,7 @@ const executeBackground = () => { fetchTotamjungTheme().then((result) => { sendResponse(result); }); + return true; } if (command === COMMANDS.SAVE_TOTAMJUNG_THEME) { @@ -134,6 +139,7 @@ const executeBackground = () => { fetchHiderOptions().then((result) => { sendResponse(result); }); + return true; } if (command === COMMANDS.SAVE_HIDER_OPTIONS) { @@ -148,6 +154,7 @@ const executeBackground = () => { fetchFontNo().then((result) => { sendResponse(result); }); + return true; } if (command === COMMANDS.SAVE_FONT_NO) { @@ -163,6 +170,7 @@ const executeBackground = () => { fetchTimers().then((result) => { sendResponse(result); }); + return true; } if (command === COMMANDS.SAVE_TIMERS) { @@ -178,6 +186,7 @@ const executeBackground = () => { fetchOptionsData().then((result) => { sendResponse(result); }); + return true; } if (command === COMMANDS.GET_REMAINING_LOCK_TIME) { @@ -194,6 +203,7 @@ const executeBackground = () => { getRemainingLockTimeByProblemId(problemId).then((result) => { sendResponse(result); }); + return true; } if (command === COMMANDS.ADD_SINGLE_TIMER) { @@ -239,6 +249,7 @@ const executeBackground = () => { isUserSolvedProblem(handle, problemId).then((result) => { sendResponse(result); }); + return true; } if (command === COMMANDS.GET_RANDOM_DEFENSE_RESULT) { @@ -249,6 +260,7 @@ const executeBackground = () => { getRandomDefenseResult(message.query).then((result) => { sendResponse(result); }); + return true; } if (command === COMMANDS.APPEND_RANDOM_DEFENSE_HISTORY_INFO) { @@ -258,8 +270,6 @@ const executeBackground = () => { appendRandomDefenseInfoToHistory(message.randomDefenseHistoryInfo); } - - return true; }, ); }; diff --git a/hooks/useRandomDefenseSection.ts b/hooks/useRandomDefenseSection.ts index 9c4244ea..29935d6a 100644 --- a/hooks/useRandomDefenseSection.ts +++ b/hooks/useRandomDefenseSection.ts @@ -1,7 +1,9 @@ import { useState, useEffect } from 'react'; -import { isQuickSlotsResponse } from '@/domains/dataHandlers/validators/quickSlotsValidator'; -import { COMMANDS } from '@/constants/commands'; import type { QuickSlots, SlotNo, Hotkey } from '@/types/randomDefense'; +import { + fetchQuickSlots, + saveQuickSlots, +} from '@/domains/dataHandlers/quickSlotsDataHandler'; const emptySlots: QuickSlots = { 1: { isEmpty: true }, @@ -23,22 +25,14 @@ const useRandomDefenseManageMenu = () => { const [isLoaded, setIsLoaded] = useState(false); useEffect(() => { - const fetchQuickSlots = async () => { - const response = await browser.runtime.sendMessage({ - command: COMMANDS.FETCH_QUICK_SLOTS, - }); + (async () => { + const { slots, selectedSlotNo, hotkey } = await fetchQuickSlots(); - if (!isQuickSlotsResponse(response)) { - return; - } - - setSlots(response.slots); - setSelectedSlotNo(response.selectedSlotNo); - setHotkey(response.hotkey); + setSlots(slots); + setSelectedSlotNo(selectedSlotNo); + setHotkey(hotkey); setIsLoaded(true); - }; - - fetchQuickSlots(); + })(); }, []); useEffect(() => { @@ -46,13 +40,8 @@ const useRandomDefenseManageMenu = () => { return; } - browser.runtime.sendMessage({ - command: COMMANDS.SAVE_QUICK_SLOTS, - slots, - selectedSlotNo, - hotkey, - }); - }, [slots, selectedSlotNo, hotkey]); + saveQuickSlots(selectedSlotNo, slots, hotkey); + }, [selectedSlotNo, slots, hotkey]); const updateSlot = (title: string, query: string) => { setSlots((prev) => ({ diff --git a/hooks/useTotamjungThemeState.ts b/hooks/useTotamjungThemeState.ts index 3116f1eb..534e4580 100644 --- a/hooks/useTotamjungThemeState.ts +++ b/hooks/useTotamjungThemeState.ts @@ -2,14 +2,15 @@ import { useState, useEffect } from 'react'; import { COMMANDS } from '@/constants/commands'; import { isTotamjungTheme } from '@/domains/dataHandlers/validators/totamjungThemeValidator'; import type { TotamjungTheme } from '@/types/totamjungTheme'; +import type { Storage } from 'wxt/browser'; const useTotamjungThemeState = () => { const [totamjungTheme, setTotamjungTheme] = useState('none'); const [isLoaded, setIsLoaded] = useState(false); const updateTotamjungThemeIfLocalChanged = ( - changes: { [key: string]: browser.storage.StorageChange }, - areaName: browser.storage.AreaName, + changes: { [key: string]: Storage.StorageChange }, + areaName: string, ) => { if (areaName !== 'local' || !('totamjungTheme' in changes)) { return; diff --git a/hooks/widget/useRandomDefense.ts b/hooks/widget/useRandomDefense.ts index 566131a3..656afa55 100644 --- a/hooks/widget/useRandomDefense.ts +++ b/hooks/widget/useRandomDefense.ts @@ -7,6 +7,7 @@ import { } from '@/domains/dataHandlers/validators/quickSlotsValidator'; import type { ToastInfo } from '@/types/toast'; import type { QuickSlotsResponse, SlotNo } from '@/types/randomDefense'; +import type { Storage } from 'wxt/browser'; import { isRandomDefenseResultResponse } from '@/domains/dataHandlers/validators/RandomDefenseResultResponseValidator'; interface UseRandomDefenseParams { @@ -53,8 +54,8 @@ const useRandomDefense = (params: UseRandomDefenseParams) => { }, []); const updateQuickSlotsIfLocalChanged = ( - changes: { [key: string]: browser.storage.StorageChange }, - areaName: browser.storage.AreaName, + changes: { [key: string]: Storage.StorageChange }, + areaName: string, ) => { if (areaName !== 'local' || !('quickSlots' in changes)) { return; @@ -131,7 +132,7 @@ const useRandomDefense = (params: UseRandomDefenseParams) => { onToast( { title: `${selectedSlotNo}번 슬롯은 현재 비어 있습니다.`, - mainIconSrc: browser.runtime.getURL('dice.png'), + mainIconSrc: browser.runtime.getURL('/dice.png'), descriptions: [ '추첨을 만들지 않으셨다면, 설정에서 해당 슬롯에 추첨을 먼저 만들어 주세요!', '설정의 퀵슬롯 메뉴에서 선택된 슬롯 번호를 변경하는 것으로 위젯 클릭 시 사용할 추첨의 슬롯을 정하실 수 있습니다.', @@ -155,7 +156,7 @@ const useRandomDefense = (params: UseRandomDefenseParams) => { onToast( { title: '데이터 불일치가 발견되었습니다.', - mainIconSrc: browser.runtime.getURL('dice.png'), + mainIconSrc: browser.runtime.getURL('/dice.png'), descriptions: '개발자에게 이 문제가 발생했음을 알려 주세요.', }, 8000, @@ -171,7 +172,7 @@ const useRandomDefense = (params: UseRandomDefenseParams) => { onToast( { title: errorMessage, - mainIconSrc: browser.runtime.getURL('dice.png'), + mainIconSrc: browser.runtime.getURL('/dice.png'), descriptions: errorDescriptions, }, 8000, diff --git a/hooks/widget/useWidget.ts b/hooks/widget/useWidget.ts index 2016e81a..4fc4fb4a 100644 --- a/hooks/widget/useWidget.ts +++ b/hooks/widget/useWidget.ts @@ -130,7 +130,7 @@ const useWidget = (params: UseWidgetParams) => { { title: '이 문제를 풀기 위해서는 모르는 알고리즘을 사용해야 할 수 있습니다.', - mainIconSrc: browser.runtime.getURL('inspect-result-question.png'), + mainIconSrc: browser.runtime.getURL('/inspect-result-question.png'), }, 3500, ); @@ -138,7 +138,7 @@ const useWidget = (params: UseWidgetParams) => { onToast( { title: '이 문제는 알고 있는 알고리즘만으로 풀 수 있습니다.', - mainIconSrc: browser.runtime.getURL('inspect-result-check.png'), + mainIconSrc: browser.runtime.getURL('/inspect-result-check.png'), }, 3500, ); diff --git a/types/toast.ts b/types/toast.ts index 7096778c..5b4e88fd 100644 --- a/types/toast.ts +++ b/types/toast.ts @@ -1,7 +1,7 @@ -import type { SVGProps } from 'react'; +import type { SVGProps, ReactElement } from 'react'; export interface ToastInfo { title: string; descriptions?: string | string[]; - mainIconSrc: string | SVGProps; + mainIconSrc: string | ReactElement>; } diff --git a/wxt.config.ts b/wxt.config.ts index 328f746e..a8c90360 100644 --- a/wxt.config.ts +++ b/wxt.config.ts @@ -3,6 +3,7 @@ import vitePluginSvgr from 'vite-plugin-svgr'; export default defineConfig({ modules: ['@wxt-dev/module-react'], + extensionApi: 'chrome', vite: () => ({ plugins: [vitePluginSvgr()], define: {