From ff77668cb4e2255938d0c919fba44cbe1b2543ec Mon Sep 17 00:00:00 2001 From: yyypearl Date: Sun, 15 Jun 2025 00:36:05 +0900 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=AAtest(#174):=20PWA=20=EC=84=A4?= =?UTF-8?q?=EC=B9=98=20=EC=9C=A0=EB=8F=84=20=EA=B8=B0=EB=8A=A5=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- next.config.mjs | 4 +- src/app/test/page.tsx | 130 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 src/app/test/page.tsx diff --git a/next.config.mjs b/next.config.mjs index 77d459a..5831169 100644 --- a/next.config.mjs +++ b/next.config.mjs @@ -20,7 +20,9 @@ export default withPlugins( withPWA, { pwa: { - dest: 'public' + dest: 'public', + register: true, + skipWaiting: true } } ], diff --git a/src/app/test/page.tsx b/src/app/test/page.tsx new file mode 100644 index 0000000..e101584 --- /dev/null +++ b/src/app/test/page.tsx @@ -0,0 +1,130 @@ +'use client'; + +import Button from '@/components/common/Button'; +import ConfirmModal from '@/components/common/ConfirmModal'; +import { theme } from '@/styles/theme'; +import React, { useEffect, useState } from 'react'; +import styled from 'styled-components'; + +declare global { + interface WindowEventMap { + beforeinstallprompt: BeforeInstallPromptEvent; + } +} + +interface BeforeInstallPromptEvent extends Event { + readonly platforms: Array; + readonly userChoice: Promise<{ + outcome: 'accepted' | 'dismissed'; + platform: string; + }>; + prompt(): Promise; +} + +const page = () => { + const [deferredPrompt, setDeferredPrompt] = useState(null); + const [isIOS, setIsIOS] = useState(false); + const [isAndroid, setIsAndroid] = useState(false); + + const [showModal, setShowModal] = useState(false); + + useEffect(() => { + const userAgent = window.navigator.userAgent.toLowerCase(); + const isIOSDevice = /iphone|ipad|ipod/.test(userAgent); + const isAndroidDevice = /android/.test(userAgent); + + setIsIOS(isIOSDevice); + setIsAndroid(isAndroidDevice); + + // Android에서만 beforeinstallprompt 이벤트 처리 + if (isAndroidDevice) { + const handler = (e: any) => { + console.log('🔥 beforeinstallprompt 발생'); + e.preventDefault(); + setDeferredPrompt(e); + }; + + window.addEventListener('beforeinstallprompt', handler); + return () => { + window.removeEventListener('beforeinstallprompt', handler); + }; + } + }, []); + + const handleInstallClick = async () => { + if (isAndroid && deferredPrompt) { + deferredPrompt.prompt(); + const { outcome } = await deferredPrompt.userChoice; + console.log('Android 사용자 선택:', outcome); + setDeferredPrompt(null); + setShowModal(false); + } else if (isIOS) { + // iOS는 안내만 + alert( + 'iPhone 사용자는 Safari에서 공유 버튼을 눌러 [홈 화면에 추가]를 선택해주세요!' + ); + setShowModal(false); + } else { + alert('설치 기능이 현재 환경에서 지원되지 않습니다.'); + setShowModal(false); + } + }; + + const handleShowModal = () => { + if (isAndroid && deferredPrompt) { + setShowModal(true); + } else if (isIOS) { + setShowModal(true); + } else { + alert('브라우저가 아직 설치를 허용하지 않았습니다.'); + } + }; + + return ( + + PWA 설치 유도 TEST +