feat: Phase 1 mobile tablet — Jenkins APK, PC tab, in-app update

Capacitor 확장으로 git push 시 Mobile Jenkins 빌드, PC 탭 Android/iPad 다운로드,
앱 내 APK 업데이트, iOS TestFlight API 및 Capacitor ios 프로젝트를 추가한다.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Macbook
2026-06-14 16:31:55 +09:00
parent 36c06b55ea
commit f34104b721
38 changed files with 1468 additions and 15 deletions
+50
View File
@@ -0,0 +1,50 @@
import React, { useEffect, useState } from 'react';
import { Capacitor } from '@capacitor/core';
import { promptAppUpdateIfNeeded } from '../services/appUpdate';
type Props = {
children: React.ReactNode;
};
/** Android 네이티브 — 시작 시 서버 APK 버전 확인 (무음 스킵, 이후 설정에서 수동 확인) */
export default function AppUpdateGate({ children }: Props) {
const [ready, setReady] = useState(() =>
!Capacitor.isNativePlatform() || Capacitor.getPlatform() !== 'android',
);
useEffect(() => {
if (ready) return;
let cancelled = false;
void (async () => {
try {
const { checkForAppUpdate, openApkDownload } = await import('../services/appUpdate');
const check = await checkForAppUpdate();
if (!cancelled && check.updateAvailable && check.remoteVersion) {
const dismissed = sessionStorage.getItem(`gc_skip_update_${check.remoteVersion}`);
if (!dismissed) {
const ok = window.confirm(
`GoldenChart v${check.remoteVersion} 업데이트가 있습니다.\n`
+ `(현재 v${check.currentVersion})\n\n지금 APK를 다운로드하시겠습니까?`,
);
if (ok) {
await openApkDownload(check.release);
} else {
sessionStorage.setItem(`gc_skip_update_${check.remoteVersion}`, '1');
}
}
}
} catch {
/* 네트워크 오류 — 앱 진입 허용 */
} finally {
if (!cancelled) setReady(true);
}
})();
return () => { cancelled = true; };
}, [ready]);
if (!ready) {
return <div className="loading-center"> </div>;
}
return <>{children}</>;
}