Commit Graph

8 Commits

Author SHA1 Message Date
Sylvain Bettinelli
83b5260bc1 Plugin discovery : MainViewController sous-classe CAPBridgeViewController
Capacitor 8 n'auto-découvre pas les plugins in-app Swift (qui ne sont pas
des npm packages). Les plugins définis dans le target App doivent être
enregistrés manuellement via une sous-classe de CAPBridgeViewController
qui override capacitorDidLoad().

Ajouts :
- ios/App/App/MainViewController.swift : sous-classe qui registers
  CoachWorkoutKitPlugin() dans capacitorDidLoad()
- Main.storyboard : customClass pointe sur MainViewController (module
  'App' target) au lieu de CAPBridgeViewController (module Capacitor)
- project.pbxproj : 4 entrées pour MainViewController.swift (BuildFile,
  FileReference, group, Sources phase)

Après rebuild, Capacitor.Plugins.CoachWorkoutKit sera dispo en JS.
2026-05-08 10:05:06 +00:00
Sylvain Bettinelli
483ad09c20 fix CoachWorkoutKit : retire preview() (API absente du SDK), garde schedule()
L'API WorkoutScheduler.shared.preview(plan) n'existe pas (ou pas avec cette
signature) dans le SDK iOS de l'utilisateur — compile error 'Value of type
WorkoutScheduler has no...'.

On garde uniquement WorkoutScheduler.shared.schedule(plan, at: now), qui
est l'API stable depuis iOS 17.0. Effet : le workout devient immédiatement
disponible dans Apple Watch → Exercice → Workouts personnalisés.

Le 1er schedule déclenche automatiquement la dialog d'autorisation iOS
'Coach Hypnotruck souhaite ajouter des workouts à votre Apple Watch' si pas
encore accordée. Plus besoin du authorizationState query manuel.

Trade-off : pas de sheet de prévisualisation système avant ajout (l'user ne
voit pas la structure dans une UI native avant que le workout soit ajouté).
Mais c'est le bon compromis pour avoir un build qui marche. On pourra
réintroduire preview() plus tard si on bump le deployment target.
2026-05-08 09:49:16 +00:00
Sylvain Bettinelli
cfa6a8bb52 fix CoachWorkoutKit Swift : API WorkoutKit corrigée
Compile errors :
- WorkoutAlertEnumeration n'existe pas → c'est WorkoutAlert (et il faut
  passer l'alert via WorkoutStep.alert, pas en param d'IntervalStep)
- IntervalStep init est .init(_ purpose:, step: WorkoutStep) — pas de goal
  ni alert direct, faut wrapper dans WorkoutStep d'abord
- WorkoutScheduler.shared.preview(plan) ajouté en iOS 17.4+ → wrap dans
  if #available(17.4) avec fallback schedule() pour 17.0-17.3

Ajouts :
- requestAuthorization() avant preview/schedule (idempotent si déjà accordée)
- HeartRateZoneAlert appliqué sur work + rest steps via .alert (style mutable)
2026-05-08 09:40:34 +00:00
Sylvain Bettinelli
2d3e149c0a Plugin natif WorkoutKit : pousse workouts intervalles vers Apple Watch
Plugin Capacitor Swift in-app (ios/App/App/CoachWorkoutKit.swift) qui utilise
le framework Apple WorkoutKit (iOS 17+ / watchOS 10+) pour construire un
CustomWorkout structuré (warmup + IntervalBlock work/rest répété + cooldown)
et présenter la sheet système iOS qui propose à l'user d'ajouter le workout
à ses workouts personnalisés Apple Watch.

API JS (côté WebView) :
  Capacitor.Plugins.CoachWorkoutKit.isAvailable()
  Capacitor.Plugins.CoachWorkoutKit.sendInterval({
    activity, displayName, warmupMin, work, rest, repeats, cooldownMin
  })

Activity supportées : running / cycling / walking / hiking
HR zones (1-5) optionnelles via HeartRateZoneAlert sur work + rest steps.

Workflow attendu user :
1. coach.hypnotruck.ch → /settings ou bouton 'Envoyer Apple Watch' depuis /calendar
2. JS appelle WK.sendInterval(...)
3. Plugin Swift construit CustomWorkout + IntervalBlock + alerts
4. WorkoutScheduler.shared.preview(plan) ouvre la sheet iOS native
5. User tape 'Ajouter aux workouts' → workout dispo dans Apple Watch
   → Exercice → Course → Workouts personnalisés → [displayName]

Build à faire sur le Mac (cap sync ios + Xcode build → install iPhone).

Phase 1 = MVP plugin + bouton test sur /settings de coach.hypnotruck.ch.
Phase 2 = bouton 'Envoyer Apple Watch' sur card du jour /calendar (convertit
la séance prévue en CustomWorkout).
Phase 3 = bibliothèque templates intervalles (10x400m, fartlek, etc.).

Project.pbxproj : ajouté 4 entrées (PBXBuildFile + PBXFileReference + group +
Sources phase) avec IDs D1BD5B1990CF3F2B9C5D000{1,2}.
2026-05-08 09:28:15 +00:00
Sylvain Bettinelli
04581915ac Generate Android icons + splash variants depuis resources/
@capacitor/assets v3.0.5 → 87 assets Android générés à partir des sources
1024x1024 (icon) et 2732x2732 (splash) déjà présentes :
- mipmap-{m,h,xh,xxh,xxxh}dpi : ic_launcher.png + _round + _foreground
  (foreground/background layers pour adaptive icons Android 8+)
- drawable-{land,port}-{l,m,h,xh,xxh,xxxh}dpi : splash.png
- mipmap-anydpi-v26 : ic_launcher.xml et ic_launcher_round.xml
  (XML adaptive icon refs vers les layers PNG)

iOS pbxproj : strip leading zero `0920` → `920` (effet de bord du tool, pas
de comportement Xcode modifié — juste format normalisé).

Reste assets marketing pour Play Console (Feature Graphic 1024x500,
screenshots phone) — à générer au moment du upload, pas dans le repo.
2026-05-07 16:30:35 +00:00
Sylvain Bettinelli
a7809992a9 Enregistre CoachAuth.swift dans project.pbxproj
Évite l'étape manuelle Add Files dans Xcode. Le fichier sera
automatiquement compilé dès qu'il existe dans ios/App/App/CoachAuth.swift.
2026-05-05 19:33:30 +00:00
Sylvain Bettinelli
50a8db9830 Inject auth cookie native dans AppDelegate au lancement
Évite le redirect 303 du backend /login qui casse WKWebView (WebKitErrorDomain
code 102, frame load interrupted by policy change). Le cookie est posé
directement dans HTTPCookieStorage.shared avec les bons attributs (domain
coach.hypnotruck.ch, path /, secure, expire 1 an).

Token lu depuis CoachAuth.kCoachWebToken défini dans CoachAuth.swift
(gitignored). Template fourni dans CoachAuth.swift.example.

Setup côté Mac mini :
1. cp ios/App/App/CoachAuth.swift.example ios/App/App/CoachAuth.swift
2. Éditer pour mettre la vraie valeur du token
3. Dans Xcode, Right-click App folder → Add Files → sélectionner CoachAuth.swift
2026-05-05 19:31:38 +00:00
Sylvain
6e3f74209b Init iOS project (cap add ios) avec privacy keys et entitlements 2026-05-05 21:29:17 +02:00