diff --git a/android/app_version.json b/android/app_version.json index 272bf0f..84d76d4 100644 --- a/android/app_version.json +++ b/android/app_version.json @@ -1,5 +1,7 @@ + { - "versionCode": 1, - "versionName": "1.0.0", - "buildNumber": 1 -} \ No newline at end of file + "versionCode": 1, + "versionName": "1.0.0", + "buildNumber": 1, + "notes": "사용자가 수정한 버전 정보입니다. 이 파일을 편집하여 앱 버전 정보를 변경할 수 있습니다." +} diff --git a/src/components/AppVersionInfo.tsx b/src/components/AppVersionInfo.tsx index 799ecb3..0c4a7d9 100644 --- a/src/components/AppVersionInfo.tsx +++ b/src/components/AppVersionInfo.tsx @@ -1,14 +1,20 @@ + import React, { useCallback, useEffect, useState, useRef } from 'react'; import { getAppVersionInfo, isAndroidPlatform } from '@/utils/platform'; +import { Input } from '@/components/ui/input'; +import { Label } from '@/components/ui/label'; +import { Textarea } from '@/components/ui/textarea'; interface AppVersionInfoProps { className?: string; showDevInfo?: boolean; // 개발자 정보 표시 여부 + editable?: boolean; // 편집 가능 여부 } const AppVersionInfo: React.FC = ({ className, - showDevInfo = true + showDevInfo = true, + editable = false }) => { const [versionInfo, setVersionInfo] = useState<{ versionName: string; @@ -23,42 +29,56 @@ const AppVersionInfo: React.FC = ({ const [error, setError] = useState(false); const [retries, setRetries] = useState(0); + // 편집 가능한 필드를 위한 상태 + const [editableVersionName, setEditableVersionName] = useState('1.0.0'); + const [editableBuildNumber, setEditableBuildNumber] = useState('1'); + const [editableVersionCode, setEditableVersionCode] = useState('1'); + // 버전 정보 가져오기 const fetchVersionInfo = useCallback(async () => { - setLoading(true); - setError(false); - - try { - console.log('앱 버전 정보 요청 시작... (retries:', retries, ')'); - console.log('현재 플랫폼은', isAndroidPlatform() ? 'Android' : '기타'); + if (!editable) { + setLoading(true); + setError(false); - // 재시도를 하는 경우 짤은 지연 추가 - if (retries > 0) { - await new Promise(resolve => setTimeout(resolve, 300)); + try { + console.log('앱 버전 정보 요청 시작... (retries:', retries, ')'); + console.log('현재 플랫폼은', isAndroidPlatform() ? 'Android' : '기타'); + + // 재시도를 하는 경우 짤은 지연 추가 + if (retries > 0) { + await new Promise(resolve => setTimeout(resolve, 300)); + } + + const info = await getAppVersionInfo(); + console.log('받은 앱 버전 정보:', info); + + // 데이터 검증 - 유효한 버전 정보인지 확인 + if (!info || typeof info !== 'object') { + throw new Error('유효하지 않은 응답 형식'); + } + + setVersionInfo({ + versionName: info.versionName, + buildNumber: info.buildNumber, + versionCode: info.versionCode + }); + + // 편집 가능한 필드도 업데이트 + setEditableVersionName(info.versionName); + setEditableBuildNumber(String(info.buildNumber)); + if (info.versionCode) { + setEditableVersionCode(String(info.versionCode)); + } + + setLoading(false); + console.log('앱 버전 정보 표시 준비 완료'); + } catch (error) { + console.error('버전 정보 가져오기 실패:', error); + setError(true); + setLoading(false); } - - const info = await getAppVersionInfo(); - console.log('받은 앱 버전 정보:', info); - - // 데이터 검증 - 유효한 버전 정보인지 확인 - if (!info || typeof info !== 'object') { - throw new Error('유효하지 않은 응답 형식'); - } - - setVersionInfo({ - versionName: info.versionName, - buildNumber: info.buildNumber, - versionCode: info.versionCode - }); - - setLoading(false); - console.log('앱 버전 정보 표시 준비 완료'); - } catch (error) { - console.error('버전 정보 가져오기 실패:', error); - setError(true); - setLoading(false); } - }, [retries]); + }, [retries, editable]); // 재시도 처리 const handleRetry = useCallback(() => { @@ -71,29 +91,82 @@ const AppVersionInfo: React.FC = ({ // 컴포넌트 마운트 시 즉시 실행 (IIFE) useEffect(() => { - (async () => { - // 즉시 버전 정보 가져오기 시도 - await fetchVersionInfo(); + if (!editable) { + (async () => { + // 즉시 버전 정보 가져오기 시도 + await fetchVersionInfo(); + + // 300ms 후에 한번 더 시도 (네이티브 플러그인이 완전히 로드되지 않았을 경우 대비) + setTimeout(() => { + if (error || loading) { + fetchVersionInfo(); + initialLoadAttemptedRef.current = true; + } + }, 1000); + })(); - // 300ms 후에 한번 더 시도 (네이티브 플러그인이 완전히 로드되지 않았을 경우 대비) - setTimeout(() => { - if (error || loading) { + // 개발 모드에서는 버전 정보 변경을 쉽게 확인하기 위해 주기적 갱신 + if (process.env.NODE_ENV === 'development') { + const interval = setInterval(() => { fetchVersionInfo(); - initialLoadAttemptedRef.current = true; - } - }, 1000); - })(); - - // 개발 모드에서는 버전 정보 변경을 쉽게 확인하기 위해 주기적 갱신 - if (process.env.NODE_ENV === 'development') { - const interval = setInterval(() => { - fetchVersionInfo(); - }, 30000); // 30초마다 새로 가져오기 - - return () => clearInterval(interval); + }, 30000); // 30초마다 새로 가져오기 + + return () => clearInterval(interval); + } } - }, [fetchVersionInfo, error, loading]); + }, [fetchVersionInfo, error, loading, editable]); + if (editable) { + return ( +
+
+
+ + setEditableVersionName(e.target.value)} + placeholder="앱 버전 (예: 1.0.0)" + /> +
+ +
+ + setEditableBuildNumber(e.target.value)} + placeholder="빌드 번호 (예: 1)" + type="number" + /> +
+ + {showDevInfo && ( +
+ + setEditableVersionCode(e.target.value)} + placeholder="버전 코드 (예: 1)" + type="number" + /> +
+ )} + +
+ +