v0.3.0 — mise à jour in-app pour Android
- Server : GET /api/version (version + APK URL + taille), GET /download/latest.apk - Server : releases/latest.apk servi avec Content-Type APK - Web : checkForUpdate() compare version locale vs serveur au démarrage - Web : modale de mise à jour (télécharger + installer, ou plus tard) - Web : version affichée dans l'onglet Plus - Vite : __APP_VERSION__ injecté au build depuis shared/APP_VERSION - Workflow : bump APP_VERSION → build APK → copier vers server/releases/latest.apk
This commit is contained in:
parent
246f989bdc
commit
90adee1eae
9 changed files with 220 additions and 3 deletions
|
|
@ -1,7 +1,8 @@
|
|||
import express from 'express'
|
||||
import { existsSync } from 'node:fs'
|
||||
import { existsSync, statSync } from 'node:fs'
|
||||
import { dirname, resolve } from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { APP_VERSION } from '@meteo-exam/shared'
|
||||
import { classesRouter } from './routes/classes.js'
|
||||
import { examsRouter } from './routes/exams.js'
|
||||
import { streamRouter } from './routes/stream.js'
|
||||
|
|
@ -10,6 +11,10 @@ import { configRouter } from './routes/config.js'
|
|||
const here = dirname(fileURLToPath(import.meta.url))
|
||||
const PORT = Number(process.env['PORT'] ?? 8787)
|
||||
|
||||
/** Dossier contenant l'APK à distribuer (latest.apk). */
|
||||
const RELEASES_DIR = resolve(here, '../releases')
|
||||
const LATEST_APK = resolve(RELEASES_DIR, 'latest.apk')
|
||||
|
||||
/** Origines autorisées. L'app Android (WebView) est en cross-origin. */
|
||||
const ALLOW_ORIGINS = (process.env['METEO_ORIGINS'] ?? '*')
|
||||
.split(',')
|
||||
|
|
@ -40,6 +45,33 @@ app.use((req, res, next) => {
|
|||
app.get('/api/health', (_req, res) => {
|
||||
res.json({ ok: true })
|
||||
})
|
||||
|
||||
// --- Mise à jour de l'APK ----------------------------------------------------
|
||||
// GET /api/version : la version courante du serveur + URL de téléchargement.
|
||||
// L'app Android compare avec sa propre version et propose la mise à jour.
|
||||
app.get('/api/version', (_req, res) => {
|
||||
const apkAvailable = existsSync(LATEST_APK)
|
||||
const apkUrl = apkAvailable ? '/download/latest.apk' : null
|
||||
const apkSize = apkAvailable ? statSync(LATEST_APK).size : null
|
||||
res.json({
|
||||
version: APP_VERSION,
|
||||
apkUrl,
|
||||
apkSize,
|
||||
notes: process.env['METEO_UPDATE_NOTES'] ?? null,
|
||||
})
|
||||
})
|
||||
|
||||
// GET /download/latest.apk : sert l'APK pour l'installation directe.
|
||||
app.get('/download/latest.apk', (_req, res) => {
|
||||
if (!existsSync(LATEST_APK)) {
|
||||
res.status(404).json({ error: 'Aucune APK disponible pour le moment.' })
|
||||
return
|
||||
}
|
||||
res.setHeader('Content-Type', 'application/vnd.android.package-archive')
|
||||
res.setHeader('Content-Disposition', 'attachment; filename="meteo-exam.apk"')
|
||||
res.sendFile(LATEST_APK)
|
||||
})
|
||||
|
||||
app.use('/api/classes', classesRouter)
|
||||
app.use('/api/exams', examsRouter)
|
||||
app.use('/api/stream', streamRouter)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue