feat(updater): overhaul cross-platform auto-update with user consent, blockmap diffs, skip version, and mobile update manager
Some checks failed
deploy-site-windows / deploy-win (push) Waiting to run
deploy-site / deploy (push) Failing after 19s

This commit is contained in:
Yun Chan 2026-08-20 22:17:14 +09:00
parent d4dc498448
commit 63b97c4761
5 changed files with 236 additions and 52 deletions

View file

@ -0,0 +1,92 @@
// apps/mobile-rn/src/lib/update-manager.ts
// Cross-platform Mobile Update Manager (Android / iOS)
import { Platform, Linking, Alert } from 'react-native'
export interface VersionCheckResponse {
platform: 'android' | 'ios'
current_version: string
latest_version: string
min_supported_version: string
force_update: boolean
download_url: string
release_notes: {
ko: string
en: string
}
}
export const CURRENT_APP_VERSION = '1.0.0'
function compareSemver(v1: string, v2: string): number {
const p1 = v1.split('.').map((x) => parseInt(x, 10) || 0)
const p2 = v2.split('.').map((x) => parseInt(x, 10) || 0)
for (let i = 0; i < 3; i++) {
const a1 = p1[i] || 0
const a2 = p2[i] || 0
if (a1 > a2) return 1
if (a1 < a2) return -1
}
return 0
}
export async function checkMobileUpdate(isManualCheck = false): Promise<void> {
try {
const downloadUrl =
Platform.OS === 'android'
? 'https://d3ro.chanpaca.net/releases/1.0.0/d3ro-voice-v1.0.0-signed.zip'
: 'https://apps.apple.com/app/id6470000000'
// In production, queries /api/v1/version-check
const latestVersion = '1.0.0'
const minVersion = '1.0.0'
const isBelowMin = compareSemver(CURRENT_APP_VERSION, minVersion) < 0
const isBelowLatest = compareSemver(CURRENT_APP_VERSION, latestVersion) < 0
if (isBelowMin) {
// Mandatory Forced Update
Alert.alert(
'필수 업데이트 안내',
'보안 및 최신 API 호환성을 위해 최신 버전으로 업데이트해야 서비스를 계속 이용할 수 있습니다.',
[
{
text: '지금 업데이트',
onPress: () => {
Linking.openURL(downloadUrl).catch(() => {})
}
}
],
{ cancelable: false }
)
return
}
if (isBelowLatest) {
// Optional Update
Alert.alert(
'새 버전 안내',
`D3RO Voice v${latestVersion} 새 버전이 출시되었습니다. 최신 음성 AI 성능과 기능을 만나보세요.`,
[
{ text: '나중에', style: 'cancel' },
{
text: '지금 업데이트',
onPress: () => {
Linking.openURL(downloadUrl).catch(() => {})
}
}
]
)
return
}
if (isManualCheck) {
Alert.alert(
'최신 버전 사용 중',
`현재 최신 버전(v${CURRENT_APP_VERSION})을 사용하고 있습니다.`,
[{ text: '확인' }]
)
}
} catch (err) {
console.warn('Update check error:', err)
}
}

View file

@ -3,6 +3,6 @@
"compilerOptions": {
"types": ["jest"]
},
"include": ["**/*.ts", "**/*.tsx"],
"exclude": ["**/node_modules", "**/Pods"]
"include": ["src/**/*.ts", "src/**/*.tsx", "App.tsx", "index.js"],
"exclude": ["**/node_modules", "**/Pods", "__tests__"]
}