Skip to content

Commit

Permalink
feat: 오프라인을 위한 asset 캐싱
Browse files Browse the repository at this point in the history
  • Loading branch information
wildcatco committed Aug 24, 2023
1 parent fecad39 commit 626528f
Show file tree
Hide file tree
Showing 20 changed files with 246 additions and 193 deletions.
12 changes: 0 additions & 12 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -137,16 +137,4 @@
<div id="root" class="h-full"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
<script>
if ('serviceWorker' in navigator) {
navigator.serviceWorker
.register('/my-sw.js')
.then(function (registration) {
console.log(
'ServiceWorker registration successful with scope: ',
registration.active,
);
});
}
</script>
</html>
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"lodash": "^4.17.21",
"pulltorefreshjs": "^0.1.22",
"react": "^18.2.0",
"react-detect-offline": "^2.4.5",
"react-device-detect": "^2.2.3",
"react-dom": "^18.2.0",
"react-error-boundary": "^4.0.11",
Expand Down Expand Up @@ -74,6 +75,7 @@
"@types/node": "^20.4.8",
"@types/pulltorefreshjs": "^0.1.5",
"@types/react": "^18.2.18",
"@types/react-detect-offline": "^2.4.1",
"@types/react-dom": "^18.2.7",
"@types/react-lazy-load-image-component": "^1.5.3",
"@types/testing-library__jest-dom": "^5.14.9",
Expand All @@ -99,6 +101,7 @@
"vite-plugin-pwa": "^0.16.4",
"vite-plugin-svgr": "^3.2.0",
"vitest": "^0.34.1",
"workbox-core": "^7.0.0",
"workbox-precaching": "^7.0.0",
"workbox-window": "^7.0.0"
},
Expand Down
46 changes: 46 additions & 0 deletions public/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"short_name": "고민의 참견",
"name": "고민의 참견, 고참",
"icons": [
{
"src": "icon/android/icon-36.png",
"sizes": "36x36",
"type": "image/png"
},
{
"src": "icon/android/icon-48.png",
"sizes": "48x48",
"type": "image/png"
},
{
"src": "icon/android/icon-72.png",
"sizes": "72x72",
"type": "image/png"
},
{
"src": "icon/android/icon-96.png",
"sizes": "96x96",
"type": "image/png"
},
{
"src": "icon/android/icon-144.png",
"sizes": "144x144",
"type": "image/png"
},
{
"src": "icon/android/icon-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "any maskable"
},
{
"src": "icon/android/icon-512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "./index.html",
"display": "standalone",
"theme_color": "#F5F7FB",
"background_color": "#ffffff"
}
5 changes: 2 additions & 3 deletions public/robots.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
# https://www.robotstxt.org/robotstxt.html
UserPage-agent: *
Disallow:
User-agent: *
Allow: /
2 changes: 1 addition & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ auth_check: "/auth-check", // HOC적용이 힘든 케이스에 사용할 검증
┃ ┣ 📜logo.svg # 미사용
┃ ┣ 📜react-app-env.d.ts # 미사용
┃ ┣ 📜reportWebVitals.ts # 미사용
┃ ┣ 📜my-sw.js # PWA를 위한 서비스 워커
┃ ┣ 📜sw.ts # PWA를 위한 서비스 워커
┃ ┣ 📜serviceWorkerRegistration.ts # PWA를 위한 서비스 워커
┃ ┣ 📜setupTests.ts # 미사용
┃ ┗ 📜version.js # 버전 커밋
Expand Down
7 changes: 6 additions & 1 deletion src/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import { RootLayout } from '@/common/components/layout';
import { IosInstallGuide, UpdateBanner } from '@/common/components/system';
import {
AlertOffline,
IosInstallGuide,
UpdateBanner,
} from '@/common/components/system';
import { GlobalErrorBoundary } from './GlobalErrorBoundary';
import { Provider } from './Provider';
import Routes from './Routes';
Expand All @@ -9,6 +13,7 @@ export function App() {
<Provider>
<RootLayout>
<GlobalErrorBoundary>
<AlertOffline />
<UpdateBanner />
<IosInstallGuide />
<Routes />
Expand Down
15 changes: 15 additions & 0 deletions src/common/components/system/AlertOffline/AlertOffline.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Offline } from 'react-detect-offline';
import { Snackbar } from '@/common/components/ui/modal';

export function AlertOffline() {
return (
<Offline>
<Snackbar
className={'absolute bottom-[10rem] left-1/2 z-[100] -translate-x-1/2'}
text={
'고민의 참견 서비스에 연결할 수 없습니다. 네트워크 상태를 확인해주세요.'
}
/>
</Offline>
);
}
1 change: 1 addition & 0 deletions src/common/components/system/AlertOffline/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { AlertOffline } from './AlertOffline';
1 change: 1 addition & 0 deletions src/common/components/system/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './IosInstallGuide';
export * from './UpdateBanner';
export * from './AlertOffline';
13 changes: 8 additions & 5 deletions src/common/hooks/useUpdate.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
import { useState } from 'react';
import { useRegisterSW } from 'virtual:pwa-register/react';

const UPDATE_INTERVAL = 60 * 60 * 1000;
const UPDATE_INTERVAL = 60 * 60 * 1000; // 1시간

export function useUpdate() {
const [showUpdate, setShowUpdate] = useState(false);
const { updateServiceWorker } = useRegisterSW({
onRegistered: (r) => {
r &&
setInterval(() => {
r.update();
}, UPDATE_INTERVAL);
if (!r) return;

r.update();
setInterval(() => {
console.log('interval');
r.update();
}, UPDATE_INTERVAL);
},
onNeedRefresh: () => {
setShowUpdate(true);
Expand Down
9 changes: 0 additions & 9 deletions src/my-sw.js

This file was deleted.

100 changes: 52 additions & 48 deletions src/pages/edit-profile/EditProfilePage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FormEvent, useEffect, useState } from 'react';
import { Online } from 'react-detect-offline';
import { useNavigate } from 'react-router-dom';
import { TopAppBar } from '@/common/components/layout';
import { DockedButton } from '@/common/components/ui/buttons';
Expand Down Expand Up @@ -104,54 +105,57 @@ export default function EditProfilePage() {
return (
<div className="flex h-full flex-col">
<TopAppBar title={'프로필 편집'} />
<form
className="mt-[2.5rem] flex min-h-0 w-full flex-1 flex-col space-y-[2.9rem]"
onSubmit={handleEditProfile}
>
<div className="hide-scrollbar flex-1 space-y-[2.9rem] overflow-y-scroll px-[2.5rem]">
<NicknameAgeGenderForm
initialData={{
nickname: user.nickname,
gender: user.gender,
birthDate: user.birthDate || '',
}}
onChange={({ nickname, gender, birthDate }, isValid) => {
setFormData({
...formData,
nickname,
gender,
birthDate,
});
setIsValid((prevIsValid) => ({
...prevIsValid,
nicknameAgeGender: isValid,
}));
}}
/>
<RegionJobCategoryForm
initialData={{
categoryIds: user.worryCategories?.map((cat) => cat.value) || [],
job: user.job,
residenceId: user.residence?.value || null,
}}
onChange={({ job, categoryIds, residenceId }, isValid) => {
setFormData({
...formData,
job,
categoryIds,
residenceId,
});
setIsValid((prevIsValid) => ({
...prevIsValid,
regionJobCategory: isValid,
}));
}}
/>
</div>
<DockedButton disabled={!buttonEnabled} backgroundClassName="w-full">
변경 완료
</DockedButton>
</form>
<Online>
<form
className="mt-[2.5rem] flex min-h-0 w-full flex-1 flex-col space-y-[2.9rem]"
onSubmit={handleEditProfile}
>
<div className="hide-scrollbar flex-1 space-y-[2.9rem] overflow-y-scroll px-[2.5rem]">
<NicknameAgeGenderForm
initialData={{
nickname: user.nickname,
gender: user.gender,
birthDate: user.birthDate || '',
}}
onChange={({ nickname, gender, birthDate }, isValid) => {
setFormData({
...formData,
nickname,
gender,
birthDate,
});
setIsValid((prevIsValid) => ({
...prevIsValid,
nicknameAgeGender: isValid,
}));
}}
/>
<RegionJobCategoryForm
initialData={{
categoryIds:
user.worryCategories?.map((cat) => cat.value) || [],
job: user.job,
residenceId: user.residence?.value || null,
}}
onChange={({ job, categoryIds, residenceId }, isValid) => {
setFormData({
...formData,
job,
categoryIds,
residenceId,
});
setIsValid((prevIsValid) => ({
...prevIsValid,
regionJobCategory: isValid,
}));
}}
/>
</div>
<DockedButton disabled={!buttonEnabled} backgroundClassName="w-full">
변경 완료
</DockedButton>
</form>
</Online>
</div>
);
}
17 changes: 10 additions & 7 deletions src/pages/home/HomePage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useQueryClient } from '@tanstack/react-query';
import { Suspense } from 'react';
import { Online } from 'react-detect-offline';
import { BottomAppBar, PageWrapper } from '@/common/components/layout';
import { Spacing } from '@/common/components/ui';
import { POST_TYPE } from '@/common/constants/post-type';
Expand Down Expand Up @@ -44,13 +45,15 @@ export default function HomePage() {
>
<Spacing size={'10.3rem'} />
<HomeBanner />
<div className={'mx-[2.5rem]'}>
<Spacing size={'2.1rem'} />
<Suspense fallback={<PostCardListSkeleton />}>
<PostCardList type={POST_TYPE.ALL} />
</Suspense>
<Spacing size={'12rem'} />
</div>
<Online>
<div className={'mx-[2.5rem]'}>
<Spacing size={'2.1rem'} />
<Suspense fallback={<PostCardListSkeleton />}>
<PostCardList type={POST_TYPE.ALL} />
</Suspense>
<Spacing size={'12rem'} />
</div>
</Online>
</main>
<BottomAppBar onScrollToTop={scrollToTop} />
</PageWrapper>
Expand Down
55 changes: 29 additions & 26 deletions src/pages/unregister/UnregisterPage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useQueryClient } from '@tanstack/react-query';
import { useEffect, useState } from 'react';
import { Online } from 'react-detect-offline';
import { useNavigate } from 'react-router-dom';
import { TopAppBar } from '@/common/components/layout';
import { Button } from '@/common/components/ui/buttons';
Expand Down Expand Up @@ -74,32 +75,34 @@ export default function UnregisterPage() {
return (
<div>
<TopAppBar title={'탈퇴하기'} />
<div className="px-[1.5rem]">
<p className="mt-[3.3rem] font-system-heading1">
{user?.nickname}님이 떠나신다니 너무 아쉬워요.
</p>
<p className="mt-[1.3rem] text-text-subTitle-700 font-system-body3">
계정을 삭제해도 게시글, 댓글, 투표한 기록 등 모든 활동 정보는 그대로
유지됩니다. 계정 삭제 후 재가입 할 경우 이전에 활동한 정보를 수정할 수
없습니다.
</p>
<PostVoteInput
id={'unregister-input'}
placeholder="계정을 삭제하는 이유를 작성해주세요."
maxLength={280}
className="mt-[2.5rem] w-full"
onChange={handleInputChange}
hasError={showError && !!errorMessage}
errorMessage={showError ? errorMessage : ''}
/>
</div>
<Button
variant="line"
className="absolute bottom-[4.8rem] left-1/2 -translate-x-1/2"
onClick={handleButtonClick}
>
탈퇴하기
</Button>
<Online>
<div className="px-[1.5rem]">
<p className="mt-[3.3rem] font-system-heading1">
{user?.nickname}님이 떠나신다니 너무 아쉬워요.
</p>
<p className="mt-[1.3rem] text-text-subTitle-700 font-system-body3">
계정을 삭제해도 게시글, 댓글, 투표한 기록 등 모든 활동 정보는 그대로
유지됩니다. 계정 삭제 후 재가입 할 경우 이전에 활동한 정보를 수정할
수 없습니다.
</p>
<PostVoteInput
id={'unregister-input'}
placeholder="계정을 삭제하는 이유를 작성해주세요."
maxLength={280}
className="mt-[2.5rem] w-full"
onChange={handleInputChange}
hasError={showError && !!errorMessage}
errorMessage={showError ? errorMessage : ''}
/>
</div>
<Button
variant="line"
className="absolute bottom-[4.8rem] left-1/2 -translate-x-1/2"
onClick={handleButtonClick}
>
탈퇴하기
</Button>
</Online>
<Popup
isOpen={modalOpen}
text="정말 탈퇴 하시겠습니까?"
Expand Down
Loading

0 comments on commit 626528f

Please sign in to comment.