Skip to content
arflischPublic

About

Carnet de musculation hors ligne (.NET MAUI : iPhone, Android, Mac)

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

14 Commits

Folders and files

Repository files navigation

Fonte

Carnet de musculation hors ligne : on note chaque série pendant la séance, l'app retrouve ce qui a été fait la fois d'avant, décompte le repos et repère les records ; elle propose des programmes dont les charges montent toutes seules, montre les progrès semaine après semaine, suit le poids, les mensurations et les photos, et (Fonte Pro) les calories et macros mangées face à un objectif. En .NET MAUI 10 pour iPhone, Android et Mac.

Accueil Séance en cours Fin de séance Fiche exercice Bibliothèque Mode sombre

Fonctionnalités

  • Bienvenue (premier lancement, en 3 étapes) : ce que fait l'app, l'objectif (force, muscle, forme) et le nombre de séances par semaine, puis un programme prêt à l'emploi qui leur correspond, à suivre ou non. L'objectif règle le temps de repos et les répétitions proposées. « J'ai déjà une sauvegarde » restaure tout sur un nouveau téléphone.
  • Séances (premier onglet) :
    • la prochaine séance du programme suivi (« Semaine 3 sur 8 · Haut / Bas »), à lancer en une touche, ou une séance libre ;
    • la semaine en cours face à l'objectif hebdomadaire (« 2 / 4 séances ») et la série de semaines réussies d'affilée ;
    • les dernières séances, et l'historique : calendrier du mois, nombre de séances, durée totale, volume, semaines régulières.
  • Programmes (second onglet) :
    • la bibliothèque d'exercices, ouverte par le bouton haltère de l'en-tête ;
    • le programme suivi : semaine en cours, ses séances dans l'ordre (A, B, C…), la prochaine, celles faites et quand ;
    • programmes prêts à l'emploi : Full body (3×/sem.), 5×5 (force), Haut / Bas (4×/sem.), Push Pull Legs (6×/sem.), adaptés à l'objectif ;
    • ses propres programmes et séances (« Bras », « Cardio »…) ;
    • l'éditeur de séance : séries, répétitions (ou durée) et charge visées par exercice, ordre, supersets (deux exercices enchaînés, sans repos entre eux) ;
    • progression automatique : quand toutes les séries atteignent leurs répétitions, la charge monte la fois suivante (+2,5 kg à la barre ou à la machine, +2 kg aux haltères, une répétition ou 5 s de plus sans charge). Une charge vide est apprise à la première séance.
  • Séance en cours :
    • chronomètre depuis le début, écran maintenu allumé ;
    • un exercice reprend les séries de la dernière fois (charges et répétitions à battre), ou celles prévues par la séance du programme, avec l'objectif affiché (« Objectif 4 × 6 · 60 kg ») et la colonne « Précédent » en regard ;
    • saisie kg × répétitions, répétitions seules ou durée ; une série validée remplit la suivante et lance le minuteur de repos (±15 s, « Passer »), avec notification si le téléphone est verrouillé ; dans un superset, le repos attend le dernier exercice ;
    • menu « ⋯ » : monter, descendre, superset avec le suivant, calculateur de disques (exercices à la barre), historique, retirer.
  • Fin de séance : durée, volume, séries, comparaison avec la dernière fois (« +4 % de volume »), records personnels, objectifs relevés pour la prochaine fois, ressenti et note.
  • Progrès (troisième onglet) : volume par semaine sur 1 ou 3 mois (graphique et moyenne), séries par groupe musculaire sur 7 jours face à une cible de 10, alerte quand un groupe est délaissé depuis deux semaines ou sous la cible, records du mois.
  • Corps (quatrième onglet) : poids et courbe sur 3 mois, évolution sur 8 semaines, objectif de poids avec progression ; mensurations (taille, poitrine, bras, cuisse, hanches) avec l'écart depuis la mesure précédente ; photos de progression prises ou choisies, gardées dans l'app (pas dans la photothèque), verrouillées par Face ID, à comparer avant / après.
  • Nutrition (cinquième onglet, Fonte Pro) :
    • objectif calculé : sexe, année de naissance, taille, poids (repris de l'onglet Corps), activité, et perdre (0,25 à 1 kg/sem.), maintenir ou prendre (0,25 ou 0,5 kg/sem.) du poids. Métabolisme de base de Mifflin-St Jeor × facteur d'activité (1,2 à 1,9), ± 7 700 kcal par kg ; jamais sous 1 200 kcal (femme) ou 1 500 kcal (homme). Protéines de 1,2 à 2 g/kg, lipides 25 % des calories, glucides le reste. Date prévue pour l'objectif de poids de l'onglet Corps ;
    • journal du jour : calories restantes (objectif − mangé, + calories actives d'Apple Santé si on le veut), protéines, glucides et lipides, petit-déjeuner, déjeuner, dîner et collations ; jours précédents ; un repas se recopie depuis la veille ou se vide ;
    • 3 055 aliments hors ligne (table Ciqual 2020 de l'ANSES, noms français et anglais), recherche sans accents ni pluriels ; scan du code-barres (iPhone et Mac) puis Open Food Facts, et recherche en ligne sur Open Food Facts ; un produit trouvé est gardé sur l'appareil ;
    • quantité en grammes ou en portions, repas, calories et macros calculées en direct ; favoris, récents, aliments à soi (étiquette pour 100 g ; énergie déduite des macros si vide) et plats composés d'ingrédients, avec le poids cuit et le nombre de parts ;
    • objectif ajusté chaque semaine (au choix) : le maintien réel est mesuré sur 21 jours, à partir des jours notés en entier (au moins 10, d'au moins 800 kcal) et de la tendance du poids (moindres carrés sur au moins 3 pesées, 7 700 kcal par kg), puis remplace la formule, à ± 25 % près ;
    • jours d'entraînement (au choix) : +10 % de calories, en glucides, les jours de séance (une séance ce jour-là, ou le jour marqué à la main), et un peu moins les autres pour garder la même semaine selon le nombre de séances par semaine ; jamais sous le minimum ;
    • jeûne intermittent de 12:12 à 20:4, fenêtre de repas ouvrant à 8 h, 10 h, 12 h ou 14 h : carte « fenêtre ouverte, ferme à 20:00 » ou « jeûne depuis 14 h 20 sur 16 h », mise à jour chaque minute ;
    • repas types : un repas s'enregistre (« ⋯ › Enregistrer comme repas type ») et revient en une touche dans l'onglet « Repas types » de la recherche ;
    • rappels (notifications quotidiennes) : noter ses repas (9 h 30, 13 h 30, 20 h 30), boire (toutes les 2 h de 10 h à 20 h), ouverture et fermeture de la fenêtre de jeûne ;
    • eau par verre de 250 ml face à un objectif (1,5 à 3 L) ; les 7 derniers jours face à l'objectif, avec le bilan : calories et protéines moyennes des jours notés, jours dans la cible (± 10 %), évolution du poids ;
    • Apple Santé : chaque aliment (énergie, protéines, glucides, lipides) et chaque verre d'eau y sont écrits, modifiés ou retirés avec le journal.
  • Exercices (depuis Programmes) : 51 exercices intégrés avec conseils d'exécution, filtres par groupe musculaire et par matériel, recherche sans accents ; chaque fiche montre le record, le 1RM estimé, la progression sur 3 mois, 1 an ou tout, et l'historique avec le volume de chaque séance. On peut créer ses propres exercices.
  • Calculateur de disques : disques à mettre de chaque côté pour une charge, barre de 20, 15 ou 10 kg, échauffement proposé (barre, puis environ 40, 60 et 80 %) ; les disques disponibles se règlent dans les réglages.
  • Unité de poids : kilogrammes ou livres (par défaut, les livres là où la région du téléphone n'est pas métrique). Tout est gardé en kilogrammes et converti à l'affichage et à la saisie ; en livres, la progression automatique monte de 5 lb (10 lb au kettlebell) et le calculateur de disques a ses propres disques (45, 35, 25, 10, 5, 2,5 lb) et barres (45, 35, 25 lb).
  • Import depuis Strong ou Hevy (gratuit) : l'export CSV de l'une ou l'autre app est reconnu à son en-tête (séparateur « , » ou « ; », colonnes trouvées par leur nom), avec les échauffements, séries dégressives et jusqu'à l'échec, le RPE, la durée et les supersets de Hevy. L'unité est lue dans le fichier ou demandée (anciens exports de Strong). Un aperçu montre les séances, les séries, la période et les exercices à créer : les noms de Strong et Hevy sont reconnus pour les exercices intégrés (« Bench Press (Barbell) »…), ceux déjà créés sont réutilisés, les autres sont créés avec un groupe et un matériel devinés. Une séance qui commence à la même minute qu'une séance de Fonte est ignorée : importer deux fois n'ajoute rien.
  • Réglages : objectif, séances par semaine, minuteur et durée du repos, unité, disques disponibles, couleur de l'app (violet, bleu, turquoise, vert, orange, rouge, rose ou ardoise, appliquée aussitôt, en clair comme en sombre), langue, sauvegarde.
  • Sauvegarde / restauration : toutes les données (séances, programmes, exercices, poids, mensurations, aliments, repas, plats, eau) et les réglages (dont l'objectif nutritionnel) dans un fichier fonte-AAAA-MM-JJ.fontebackup chiffré par un mot de passe choisi à chaque sauvegarde, remis à la feuille de partage (iCloud Drive, mail, AirDrop…) ou au panneau Enregistrer sur Mac. Les photos de progression sont incluses au choix (Face ID demandé, comme pour les voir). La restauration, depuis les réglages ou l'écran de bienvenue, lit et vérifie tout le fichier avant de remplacer quoi que ce soit ; une sauvegarde sans photos garde celles de l'appareil. La langue n'est pas restaurée : elle suit le nouvel appareil.
  • Langues : français, néerlandais et anglais (par défaut : la langue du téléphone), changement immédiat.
  • Thème clair / sombre automatique. La couleur d'accent vient de Services/AccentTheme.cs : les pages l'utilisent par des ressources dynamiques (Accent, AccentSoft, HeroGradient…), redéfinies quand on change de couleur ou de thème. L'icône et l'écran de lancement restent violets.

Fonte Pro

Achat unique, sans abonnement (com.arflisch.fonte.pro, prix conseillé 7,99 €), via l'App Store ou Google Play avec Plugin.InAppBilling, comme Poches Pro. Le déblocage est gardé sur l'appareil et se restaure depuis le compte du Store.

Gratuit et illimité : noter les séances, séries de la dernière fois, minuteur de repos, supersets, exercices et conseils, records, 1RM, historique et calendrier, objectif de la semaine, suivre un programme prêt à l'emploi, jusqu'à 3 séances à soi, le poids.

Fonte Pro :

  • progression automatique : sans Pro, la fin de séance montre ce qui serait monté (« Tu as gagné une hausse »), sans modifier la séance type ;
  • programmes à soi et séances illimitées ;
  • progrès sur 3 mois, séries par muscle et alertes ;
  • objectif et courbe de poids, mensurations, photos ;
  • nutrition : objectif de calories et de macros ajusté chaque semaine, jours d'entraînement, journal des repas, aliments, scan, plats, repas types, jeûne, rappels, eau ;
  • séries avancées : échauffement (« É »), dégressive (« D »), jusqu'à l'échec (« X »), RPE de 6 à 10, repos propre à chaque exercice (séance type et séance en cours). Les échauffements ne comptent ni dans le volume, ni dans les records, ni dans la progression ; les dégressives comptent dans le volume mais pas dans la progression ;
  • calculateur de disques et échauffement ;
  • Apple Santé (iPhone) : chaque séance terminée y est enregistrée (musculation), le poids des 12 derniers mois en est repris ; les repas et l'eau y sont écrits, les calories actives en sont lues ;
  • export CSV de toutes les séries (séparateur et décimales de la langue, pour Excel ou Numbers) et bilan du mois en image à partager ;
  • les couleurs de l'app autres que le violet.

Fonte Pro est proposé quand on touche une fonction Pro, dans les réglages, et une seule fois après la 3e séance.

Les builds Debug, et ceux faits avec -p:ProTesting=true, permettent de débloquer et reverrouiller Pro sans le Store (jamais pour le Store).

Apple Santé demande un identifiant d'app com.arflisch.fonte avec la capacité HealthKit, et un profil de signature qui la contient : le profil générique « * » ne peut pas l'avoir.

Persistance

SQLite local via sqlite-net-pcl, dans le dossier privé de l'app. La seule connexion réseau est celle d'Open Food Facts, quand on scanne un produit inconnu ou qu'on cherche en ligne (rien n'est envoyé d'autre que le code-barres ou les mots cherchés).

  • Tables exercises, workouts, workout_exercises, workout_sets ; programs, templates, template_exercises (programmes et séances types) ; body_weights, measurements, body_photos ; foods (table Ciqual, produits scannés, aliments à soi et plats, avec les nutriments pour 100 g), food_entries (ce qui a été mangé, nutriments copiés au moment de la saisie), recipe_ingredients, water, meal_templates et meal_template_items (repas types). Les exercices et programmes intégrés sont stockés par clé (bench_press, full_body…) et traduits à l'affichage ; les nouveaux exercices d'une mise à jour sont ajoutés au démarrage, et les colonnes nouvelles ajoutées aux tables existantes.
  • Une séance lancée depuis un programme garde le lien vers sa séance type (TemplateId) et copie ses objectifs : la prochaine séance du programme est celle qui suit la dernière faite, et la progression automatique relève les objectifs de la séance type quand la séance est terminée.
  • Les photos de progression sont des fichiers dans le dossier privé de l'app (photos/), jamais dans la photothèque.
  • Il y a au plus une séance en cours (FinishedAt nul). Les records, la dernière fois et les statistiques sont toujours recalculés à partir des séries validées des séances terminées : rien ne peut se désynchroniser.
  • La table Ciqual (Fonte.Core/Nutrition/ciqual.csv, ressource incorporée) est copiée dans foods à la première recherche. Elle est produite par tools/ciqual_to_csv.py depuis le fichier officiel de l'ANSES (Ciqual 2020, Licence Ouverte Etalab 2.0) : aliments pour bébés retirés, énergie manquante calculée avec les coefficients du règlement UE 1169/2011.
  • Un aliment ou un plat déjà mangé n'est jamais effacé, seulement masqué : les repas passés le montrent encore.
  • Un exercice déjà utilisé n'est jamais effacé, seulement masqué de la bibliothèque, pour que les anciennes séances le montrent encore.
  • Comparaison des séries : 1RM estimé pour les séries chargées (plafonné à 12 répétitions), répétitions sinon, durée pour les exercices chronométrés.
  • Format de sauvegarde (Fonte.Core/Backup) : une archive tar (data.json, puis photos/<fichier>) chiffrée en flux, pour que les photos ne passent jamais entièrement en mémoire. Clé dérivée du mot de passe par PBKDF2-HMAC-SHA256 (600 000 itérations, sel aléatoire de 16 octets, mot de passe normalisé NFC), puis morceaux de 64 Kio scellés chacun par AES-256-GCM, avec l'en-tête en données associées et le numéro du morceau dans le nonce ; le dernier est marqué et plus court (construction STREAM). Un morceau modifié, déplacé, ajouté ou retiré est refusé. Un mauvais mot de passe échoue dès le premier morceau ; un fichier abîmé plus loin est signalé comme tel. Le mot de passe n'est stocké nulle part : perdu, la sauvegarde est irrécupérable. Les dates restent à l'heure locale où elles ont été notées, sans fuseau. La restauration garde les identifiants des lignes. Le chiffrement passe uniquement par les fonctions cryptographiques du système (CryptoKit et CommonCrypto sur iPhone et Mac) : l'Info.plist iOS garde ITSAppUsesNonExemptEncryption = false.
  • La fin du repos est enregistrée : le minuteur continue si l'app est fermée, et une notification locale (Plugin.LocalNotification) sonne à l'heure. Sur Android 14+, l'autorisation « Alarmes et rappels » la rend exacte ; sans elle, elle peut arriver avec un peu de retard.

Architecture

Fonte.slnx
├── src/Fonte.Core          net10.0 — modèles, FonteStore (SQLite), catalogues d'exercices et de programmes, calculs (1RM, volume, records, progression, disques, séries de semaines)
├── src/Fonte               app .NET MAUI (MVVM avec CommunityToolkit.Mvvm)
│   ├── Views/              pages XAML (bindings compilés)
│   ├── ViewModels/         un ViewModel par page
│   ├── Controls/           dessin vectoriel maison : icônes, courbe, barre de progression
│   ├── Services/           réglages, minuteur de repos, dialogues, palette, routes
│   └── Resources/Styles/   couleurs et styles (clair/sombre)
└── tests/Fonte.Core.Tests  tests xUnit de la logique métier (SQLite réel en fichier temporaire) et des traductions

La base technique (contrôles, feuilles sur Mac, localisation, raccourcis clavier) vient de Poches.

Traductions

Les textes sont dans src/Fonte/Resources/Strings/ : AppResources.resx (anglais, langue par défaut), AppResources.fr.resx et AppResources.nl.resx.

  • En XAML : Text="{l:Tr Home_Start}" ; en C# : Loc.Get("Home_Start") ou Loc.Format("Picker_Add", n).
  • Noms construits à l'exécution : exercices intégrés Ex_<clé> et leurs conseils Tip_<clé>, programmes Program_* / ProgramText_*, séances types Template_*, objectifs Goal_* / GoalText_*, mensurations Measure_*, groupes Muscle_*, matériel Equipment_*, saisie Tracking_*, erreurs Error_* (codes FonteError de Fonte.Core), repas Meal_*, sexe Sex_*, activité Activity_*, objectif de poids WeightGoal_*, listes d'aliments FoodShelf_*.
  • Les tests TranslationTests échouent si une langue n'a pas les mêmes clés ou les mêmes {0}, si une clé utilisée n'existe pas, si une clé n'est plus utilisée, ou s'il manque le nom ou le conseil d'un exercice, le nom d'un programme, d'une séance type, d'un objectif, d'une mensuration, d'un groupe, d'un matériel ou d'une erreur.

Lancer l'app

Prérequis : SDK .NET 10 et workload MAUI (dotnet workload install maui).

dotnet test tests/Fonte.Core.Tests
dotnet build src/Fonte -t:Run -f net10.0-ios
dotnet build src/Fonte -t:Run -f net10.0-android
dotnet build src/Fonte -t:Run -f net10.0-maccatalyst

Sur un vrai iPhone, un compte Apple Developer est nécessaire pour signer l'app. Avec Xcode 27, tant que le SDK .NET pour iOS ne le reconnaît pas officiellement, ajouter -p:ValidateXcodeVersion=false aux commandes iOS et Mac. Sur Mac, les feuilles s'affichent en carte centrée et Échap les ferme, comme dans Poches.

Données nutritionnelles

  • Ciqual 2020, ANSES, Table de composition nutritionnelle des aliments, sous Licence Ouverte / Open Licence 2.0 (Etalab).
  • Open Food Facts (openfoodfacts.org), base collaborative sous Open Database License (ODbL) ; requêtes envoyées avec l'agent Fonte/<version>.
  • Les objectifs sont des estimations (Mifflin-St Jeor) et l'app le dit ; ce n'est pas un avis médical.

Idées pour la suite

  • Minuteur de repos sur l'écran verrouillé (Live Activity, extension native en Swift).
  • Synchronisation iCloud entre iPhone et iPad.

About

Carnet de musculation hors ligne (.NET MAUI : iPhone, Android, Mac)

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages