Roadmap
Phases de développement, de la fondation au polish.
Vue d’ensemble
Les phases sont des ÉPICS THÉMATIQUES, pas une chronologie. Elles regroupent le travail par thème (lecture, écriture, messages, extensions, polish), pas par ordre de livraison. Le « quand » est porté par les releases — l’historique réel des livraisons se lit dans les
CHANGELOG.md(racine +app/CHANGELOG.md) et lesversionNamedes bêtas/prod, pas dans la numérotation des phases. Une feature peut donc être livrée « en avance » sur sa phase (ex. la Blacklist, thème Phase 4, shippée en bêta 0.15.0 avant l’ouverture formelle de la Phase 4).Corollaire : « Polish & UX » (ex-Phase 5) n’est pas une étape finale mais un backlog continu alimenté tout au long du projet. Le milestone GitHub correspondant a été renommé en ce sens (« Polish & UX (backlog continu) »), et le label
phase-5est devenupolish.
Les phases gardent un ordre de dépendances techniques (on ne livre pas l’écriture avant la lecture), pas un calendrier. Le rythme réel dépend des contributeurs et des dépendances externes. Cohérent avec la méthodologie triple-hybride (prototype-driven).
Pour la liste des capabilities et des non-goals, voir le scope fonctionnel.
Dashboard des phases
| Phase | Objectif | Taille | Dépend de | Statut |
|---|---|---|---|---|
| 0 — Bootstrap | Squelette qui compile, CI, thème, navigation | S | — | ✅ Livrée |
| 1 — Core | Lecture du forum (drapeaux, topics, forum, deep links) | XL | Phase 0 | ✅ Livrée (AAB 0.1.0-phase1.7 / app-v38 / specs v0.8.4) |
| 2 — Écriture | Post / edit / quote / create topic / recherche / proxy alpha | L | Phase 1 | ✅ Livrée |
| 3 — Messages | MPs classiques + MultiMPs (lecture + écriture + DT + sync de position) | M | Phase 2 | ✅ Livrée (clôture #598 ; sync MPStorage bidirectionnelle complète + cache Room reportés → #6, Phase 4) |
| 4 — Extensions + refonte UI pré-1.0 | Bookmarks, Qualitay, Redflag + refonte Drapeaux (#603) / Topic (#604) + hygiène repo (#605) ; Blacklist déjà livrée | L | Phase 3 + hfr-redflag Worker | 🚧 En cours |
| Polish & UX | Animations, offline, thème dynamique, Play Store, raffinements UX | — | continu | ♾️ Backlog continu (pas une étape finale) |
Taille : S = petit sous-chantier, M = quelques composants, L = plusieurs features indépendantes, XL = écran majeur + parseurs + cache (ex. PostRenderer natif).
Graphe des dépendances
flowchart LR
P0["Phase 0<br/>Bootstrap"]
P1["Phase 1<br/>Core lecture"]
P2["Phase 2<br/>Écriture"]
P3["Phase 3<br/>Messages"]
P4["Phase 4<br/>Extensions + refonte UI"]
POL["Polish & UX<br/>(backlog continu)"]
MPS[("MPStorage2<br/>hfr-redkit")]
RFL[("hfr-redflag<br/>CF Worker")]
P0 --> P1 --> P2 --> P3 --> P4
MPS -.prérequis.-> P4
RFL -.prérequis.-> P4
P2 -.alimente.-> POL
P3 -.alimente.-> POL
P4 -.alimente.-> POL
classDef external fill:#fef3c7,stroke:#d97706
classDef continuous fill:#ede9fe,stroke:#7c3aed
class MPS,RFL external
class POL continuous
Les dépôts en cylindre (MPStorage2, hfr-redflag) sont des dépendances externes hors de ce repo — leur état bloque le démarrage de la phase qui les consomme. Note : la lecture MPStorage (positions DT) est livrée en Phase 3 sans dépendre de MPStorage2 (l’enveloppe v0.1 de facto a été adoptée, cf. ADR-014) ; le prérequis MPStorage2 ne pèse plus que sur la sync complète de Phase 4 (#6). « Polish & UX » n’est pas une phase terminale : c’est un backlog continu alimenté par toutes les phases.
Phase 0 — Bootstrap ✅ livrée
Objectif : un squelette d’app qui compile, avec CI, thème et navigation.
- Structure Gradle multi-modules (8 core + 8 features base déclarés ; certains modules conservent un
build.gradle.ktsvide en attente de leur cycle, cf. ADR-001) - CI GitHub Actions (
detektAll,lintDebug,test,testDebugUnitTest,:app:assembleDebug) - Thème Material 3 dans
:core:ui(clair, sombre, AMOLED — Material You + HFR Classique différés Phase 5) - Navigation graph Compose Navigation 3 (bottom nav 4 onglets + back stacks par onglet, cf. navigation.md)
- Hilt wiring (
build-logicconvention plugins, KSP,@HiltAndroidApp) - Design system de base (typographie, couleurs, composants thème)
- Build signed AAB — pipeline
--init-script+ stampingredface2-v<vc>-<YYYYMMDD>-<sha>.aab
Livrable : une app qui démarre, affiche la bottom nav et navigue entre les écrans Phase 1 (drapeaux placeholder Phase 0 ; remplacé par la liste réelle en Phase 1B.4 ; forum/search/messages placeholder, topic fixe, éditeur placeholder).
Phase 1 — Core (lecture seule) ✅ livrée
Objectif : lire le forum. C’est 80% du use case.
- Login HFR (cookies persistants) —
:feature:auth.LoginScreen+AuthRepositorycache-aside (DataStore +PersistentCookieJar), session persistée viamd_user/md_pass, commit cookies seulement après classificationAuthenticated, détection session expirée sur endpoints authentifiés (cf. ADR-002 — DataStore non chiffré + FBE, AAB v14 /0.1.0-phase1b.0, hardening v24 /0.1.0-phase1b.10) - Écran Drapeaux (accueil) —
:feature:flags.FlagsRoute+FlagRepository(RESTforums/hardwarefr/topics/{participated,read,favorites}/depuis Phase 1D-1 #110, anciennement HTMLforum1f.php?owntopic={1,2,3}), 3 onglets (« Mes sujets » / « Lus uniquement » / « Favoris »), boutons « Réessayer » / « Actualiser » sans pull-to-refresh complet en 1B, filtre client CYAN masquant les sujets participés déjà lus par défaut (#154). Le footer alpha initial (pseudo, logout, version, signalement, Diagnostics) a vécu temporairement surMessagesScreen(#154), puis a été hoisté en Phase 2 finish (#198) dans le menu compte global (RedfaceAccountMenu) accessible depuis chaque écran principal via un slottopBarActions.MessagesScreenredevient un placeholder Phase 3. - Slice topic fixe — historique :
TopicScreena rendu une fixture HFR via parser → AST → renderer le temps que le pipeline réseau soit posé - Parser HTML topic —
:core:parserproduitPostContentdepuis le HTML HFR (cf. PR #78) - PostRenderer Compose — rendu natif
PostContentdans:core:ui(paragraphes, citations imbriquées avec collapse, spoilers, smileys builtin/perso, images, couleurs ; cf. ADR-011 et PR #80) - Écran Topic réel —
TopicRepositorycache-aside (OkHttp + parser + Room) livré (PR #88) puis branché surTopicScreen(1A-bind),TopicFixtureRepositorysupprimé - Écran Topic — lecture longue Phase 1D-2 (#107) : Précédent / Suivant + indicateur page X/Y + champ “Aller à la page” pour les longs topics ; rangée 1..N gardée en complément ≤ 40 pages.
TopicEffect.ScrollToPost(numreponse)consommé une seule fois parLaunchedEffect(Unit)(re-emit empêché par un flag interne au ViewModel). Deep linkforum2.php?cat=N&post=M&page=P#tIDouvre la page P et scrolle au posttIDquand il est présent. Back stack préservé : tap sur une page replace l’entrée TopicRoute (pas de push), back ramène au caller. - Écran Forum 1C-A REST-first —
:feature:forum.ForumScreen(19 catégories) +ForumCategoryScreen(subcats + topics paginés). Source REST/webservices/rest_api.phpviaHfrApiClient(:core:network) etForumRepository(:core:data), cf. ADR-003 - Écran Forum 1C-B — Material 3
PullToRefreshBoxsurForumScreen/ForumCategoryScreen(contenu préservé pendant le refresh, pas deSwipeRefreshAccompanist), badge drapeau par topic dérivé du RESTflag_owntopic(CYAN / RED / FAVORITE), recherche locale dans la page courante (titre / auteur / dernier réponseur, accent-insensitive) - Cache Room Phase 1D-3 (#26) — pages topic + posts persistés avec TTL,
authModeanti-écrasement, drapeaux REST persistés par compte dansflag_topics, purge logout / changement de pseudo viaCacheInvalidator - Deep linking (URLs HFR → app) —
parseHfrDeepLinkcorrigé (mappingforum1.php↔forum2.phpinversé, fixé en 1C-A) et branché sur les écrans réels Forum/Category/Topic - Prefetch pages suivantes Phase 1D-4 (#108) — topic
page + 1persisté enANONYMOUSsans écraser l’authentifié, listing forumpage + 1warm-up anonyme sans exposer le payload ; annulation au changement de page / sortie d’écran - Images + smileys (Coil 3) — Phase 1D-5 (#109) —
SingletonImageLoader.Factorycôté:appavecAnimatedImageDecoder.Factory()(autoplay GIFs builtins + perso).:core:uiPostMediaDisplayPolicycentralise les tailles : builtin 18×18, perso 70×50 (ContentScale.Fit, bucket aligné sur la distribution wikismilies), inline image 240×180 borné (ContentScale.Inside), block image largeur parent + hauteur max 480dp + arrondi + état loading/error. Pas de mesure intrinsèque async niFlowRow— décision B+ verrouillée par Codex (re-évaluable Phase 2/4 si le bucket fixe reste insuffisant). MAJ Phase 2F : le bucket fixe des smileys a été remplacé par un rendu intrinsèque (mesure native Coil, no-upscale, cap abs 70sp/240sp + cap relatif 0.9×largeur,AboveBaseline+line-growth) en #175 / PR #222 — cf.protocol-hfr.md§ Smileys. Les images inline[img]restent en bucket fixe (migration intrinsèque suivie en #224 ; validation visuelle smileys app↔web en #131). - Blocs monospace
[fixed]/[code](#79) —PostBlock.Fixed(text)etPostBlock.CodeBlock(text, language?)parsés depuis<table class="fixed">/<table class="code">;PostRendererrend chaque bloc dans uneCard surfaceContainerHighestà police monospace avec scroll horizontal sur overflow. Coloration syntaxique aplatie en texte brut (Phase 2).
Livrable : une app utilisable pour lire le forum au quotidien. Pas encore de possibilité d’écrire.
PostRenderer — le sous-chantier critique
Le rendu natif Compose du contenu HFR est le composant le plus complexe de toute l’app. Il doit gérer :
| Élément | Complexité |
|---|---|
| Texte formaté (gras, italique, souligné, couleur, taille) | Moyenne |
| Citations imbriquées | Élevée |
| Blocs de code | Faible |
| Images inline | Moyenne |
| Smileys HFR | Moyenne (cache + mapping) |
| URLs cliquables | Faible |
| Spoilers (clic pour révéler) | Moyenne |
| Listes | Faible |
Le PostRenderer sera développé de manière incrémentale : texte brut d’abord, puis formatage, puis citations, puis images.
Phase 2 — Écriture
Objectif : interagir avec le forum.
- 2A — Reality check protocole d’écriture HFR (#81) + références écosystème (#32) — fixtures live, spec écriture alignée HFR, page
docs/guides/references.mdconsolidée. Mergé via PR #159 (writes) + PR #160 (références). - 2B-A — Socle éditeur local (#86, refs #144) —
PostEditorRoute/TopicFormRoute,PostEditorScreen+ ViewModel, toolbar BBCode complète (gras / italique / souligné / barré / quote / code / cpp / fixed / spoiler / url / image), preview locale viaparsePostContentFromBbcode. Pas encore d’envoi HFR — local seulement. - 2C — Reply MVP (#145) — POST réel
bddpost.phpviaReplyRepository(:core:domain/write/+:core:data/write/),PostEditorViewModelwire submit + erreurs typées (empty,invalid_token,antiflood,locked,login_required). Migration Room v3 → v4 ajoutesubcatàtopic_pages; HFR write contract recapturé sur fixtures Phase 2A. - Quote MVP (#146, hardening #227) — bouton « Citer » par post dans
TopicScreen, gate surTopic.canReply(pas surquoteRef),PostEditorRouteétendu avecquotedNumreponse+quoteRefoptionnel. GETmessage.php?…&numrep={cited}avec&ref={N}seulement quand HFR l’a exposé en clair ; HFR préremplit quand même[quotemsg=…]avecnumrepseul sur les liens obfusqués.ReplyForm.initialContenthydrate le draft une seule fois sans écraser une saisie utilisateur, POSTbddpost.phpavecnumrep={cited}etnumreponse="". Réutilise leReplyRepository; pas deQuoteRepository. - Edit post MVP (#147) — bouton « Modifier » par post éditable détecté depuis la toolbar HFR (lien
message.php?…&numreponse=N). GET edit form, hydratation du draft depuis le BBCode existant, POSTbdd.php?config=hfr.incavecnumreponse={N}etnumrep="".EditPostRepositorydistinct duReplyRepository; partage les parsers, options, classification d’erreurs.delete=1filtré (hors scope). Refresh topic + scroll vers le post édité. - Edit FP MVP (#148) — édition du sujet + contenu BBCode du premier post via
TopicFormScreendédié.TopicFormParserextraitsujet,subcatsélectionnée + choix complet du<select>,MsgIconchecked, options checkboxes, et préserve les champs sondage /toread1..5verbatim. POSTbdd.php?config=hfr.incavecsujetmodifiable etsubcatre-catégorisable ;deletefiltré (suppression hors scope).Topic.isFirstPostOwnerdétecté depuis la toolbar du premier post (page 1 uniquement). Édition active du sondage : reportée — fixture avec sondage existant nécessaire avant de prouver le contrat. - Edit FP polish (#178) — recatégorisation exposée via le dropdown sous-catégorie pour
TopicFormMode.EditFirstPost, avec submit duselectedSubcatexistant ; l’UX sondage reste honnête (préservation verbatim uniquement tant que les fixtures POST sondage manquent). - Create topic MVP (#149 Phase 2E + #214/#206 finish) — depuis
ForumCategoryScreen, FAB « Nouveau topic » (visible enAuthState.Authenticateduniquement), composer dédiéTopicFormScreenmodeNew(sujet + dropdown sous-catégorie obligatoire + BBCode toolbar + options HFR), POSTbddpost.php?config=hfr.incviaTopicFormRepository.submitNewTopic.from_subcat(chip d’arrivée) reste distinct dusubcatfinal (dropdown). La réponse succès live refresh vers la liste cible et ne renvoie aucun topic id : l’app revient donc sur la sous-catégorie cible avec Toast et met en évidence le sujet créé par correspondance exacte du titre. Sondage actif à la création : reporté tant qu’aucune fixture POST sondage n’a été capturée. - Toolbar BBCode (#144 Phase 2B-B) — palette couleur Material 3 (
BbcodeAction.Color(#RRGGBB)+ dropdown 5 swatches) ajoutée à la toolbar partagée:core:ui/BbcodeToolbar.BbcodeActionest devenu unsealed interfacepour porter le hex. Listes BBCode ([list]/[*]) restent hors AST en Phase 2B : le parser les conserve en texte brut sans crash (cf.BbcodeContentParserTest), à revoir Phase 4 quand un renderer liste sera utile. Smileys perso et upload images : #11. - Preview BBCode — livré 2B-A en local via
parsePostContentFromBbcode; preview serveurapercu.phpreportée tant qu’aucune divergence HFR ne le justifie. - Smileys éditeur MVP (#11 partiel, Phase 2F-B + 2F-C) — picker
ModalBottomSheetMaterial 3 dansPostEditorScreen(Reply / Quote / Edit, Phase 2F-B) et dansTopicFormScreen(Edit FP + New topic, Phase 2F-C). Onglet Standard : 25 builtins HFR servis depuis la constanteBUILTIN_HFR_SMILEYS(codes dérivés dewrite_reply_form_open_topic.html). Onglet Wiki : recherche live viaGET /message-smi-mp-aj.php?config=hfr.inc&user_id={id}&findsmilies={query}(contrat vérifié 2026-05-22,user_idparsé depuisfind_smilies_timer('hfr.inc', N)du form HTML et plumb dansReplyForm.userId/TopicForm.userId), debounce 300 ms + gatequery.length > 2alignés sur le composer HFR. Insertion viainsertBbcodeToken(" $token ")qui reproduit la conventionputSmileyJS. Le rendu adaptatif des smileys inline dans les posts est sorti du scope et tracé dans #175. Hors scope #11 conservé : favoris, récents, upload smiley perso, GIFs externes, catalogue offline. - Dogfood rendu smileys (#131 / #175, Phase 2F-D) — comparer visuellement RF2 au rendu web HFR sur de vrais topics ; garder le bucket fixe 70×50 si acceptable, ou livrer le rendu adaptatif #175 si le dogfood invalide ce compromis.
- Médias éditeur Phase 2F-E (#189) — helper MVP d’insertion d’image par URL distante : dialog Material 3 depuis la toolbar partagée, validation
http(s)uniquement, insertion[img]url[/img]au curseur dans Reply / Quote / Edit / Edit FP / New topic. Upload/rehost, favoris/récents smileys, GIFs externes et sync MPStorage sont différés aux phases ultérieures (#190). - Recherche HFR MVP (#150 partiel, Phase 2G-A/B) — recherche via
GET /forum1.php?recherches=1&...(le form HFRPOST /search.phprenvoie une page de transition meta-refresh, on hit le GET canonique directement). Parser couvre les shapes capturées :no-results(page.hopminimaliste),pivot single(1 cat hit),pivot multi(N cats hit, sélecteur via<select name="cat">dans<div class="search">),explicit cat(listing standard sans bannière), et les extraits contenuDernier message correspondantavec lienforum2.php?...numreponse=...quand HFR les fournit. Écran Recherche : champ + IME Search + bouton, choix Titres+messages/Titres/Messages, états idle/loading/empty/error/results, pivot horizontal pour relancer dans une autre catégorie. Navigation →TopicRoute(cat, post, page, scrollTo)quand le résultat porte unnumreponse, sinon page 1. - Recherche HFR bugfix (#188, Phase 2G-B) — les catégories de pivot de recherche sont rendues en rail horizontal borné (single-line + ellipsis), ce qui évite les libellés verticaux du style « Linux et OS Alternatifs » sur écran étroit.
- Recherche HFR filtres avancés auteur/date + pagination — backlog non bloquant après stabilisation du MVP, à ouvrir en issue dédiée si le besoin reste confirmé après #188.
- Profil utilisateur (#208, Phase 2 finish) — tap sur avatar/pseudo d’un post ouvre un bottom sheet résumé (avatar carré/arrondi, pseudo, localisation, inscription, posts). Bouton « Voir le profil complet » navigue vers la page détaillée.
Post.profileIdextrait du lien toolbar HFR et persisté en Room v6. Module:feature:profileavecProfileViewModel(AssistedInject),ProfilePreviewSheet(ModalBottomSheet M3) etProfileScreen. Frontière:feature:topic→:feature:profilezéro (callbackonOpenProfilehoisted dans:app). Bouton « Derniers messages » désactivé (pas de route stable, marqué « à venir »). - Retirer un drapeau (delflag) (#99, Phase 2 finish) — retrait par swipe-to-remove (
SwipeToDismissBoxM3, swipe end-to-start) sur chaque ligne dans:feature:flags, avec confirmation Material 3 obligatoire avant l’appel réseau (le swipe ouvre le dialog mais ne supprime jamais la ligne seul ; pas d’undo optimiste :addflagn’est pas prouvé pour tous les types, donc rien à re-poser après coup). Suppression unitaire viaGET /user/delflag.phpauthentifié (mappingFlagType→owntopic1/2/3, classée sur « Drapeau effacé avec succès » ; cf.protocol-hfr.md). Succès → éviction des caches mémoire + Room (clécat+topicId+type) et ré-émission immédiate ; échec → aucun cache touché + snackbar d’erreur. Action désactivée pendant l’appel (anti double-tap). Suppression en masse (manageaction.php) hors scope. - Réglage proxy utilisateur (#187, Phase 2H) — écran Settings alpha, persistance DataStore, branchement HFR-only pour OkHttp + Coil (seuls
hardware.fr/*.hardware.frpassent par le proxy ; les images externes restent en direct), proxy HTTP avec authentification optionnelle, et guide utilisateur. Le MVP demande un redémarrage de l’app après changement ; pas de proxy embarqué, PAC, SOCKS ou bypass list. - Swipe pour changer de page de topic (#282, Phase 2 finish) — geste horizontal gauche/droite « drag-follow » dans
TopicScreen(la page suit le doigt, résistance amortie aux bords, retour haptique armement/commit, edge-glow discret), implémenté parModifier.topicPageSwipe(feature/topic/.../TopicSwipe.kt, helpers purs testés). Il appelle le mêmeonOpenPage(targetPage)que les boutons de pager (navigation route-driven, remplace laTopicRoute) ; transition Topic→Topic rendue instantanée (transitionSpecdédié dansRedfaceApp) pour supprimer la fenêtre morte du cross-fade ; geste gaté tant que l’entrée nav n’est pasRESUMED(anti double-commit pendant la transition). Aucune action destructive.
Livrable : une app complète pour lire ET écrire sur le forum.
Phase 3 — Messages
Objectif : les messages privés, classiques et multi.
- Inbox MPs classiques — liste + lecture en read-only (#298)
- Reply / quote MP classique (#301)
- Nouveau MP — création
- MultiMPs — liste avec vue drapeaux, lecture, reply, quote (onglet « DT » des Drapeaux listant les MultiMP + reprise de lecture MPStorage livré 2026-06-19, app-v166)
- Nouveau MultiMP — création (2+ destinataires)
- Intégration MPStorage — lecture livrée (découverte par scan inbox + parsing + seed des positions DT) et écriture déclencheur de synchronisation de la position de lecture DT livrée (
writeBackFlagIfPresentUPDATE-ONLY, opt-in OFF par défaut, #593/#597 via PR #608, RMW guardé + verify-after-write + cap 64 KiB, POSTbdd.php cat=privenon observé live). Activation opt-in par défaut + cache Room du contenu + synchronisation bidirectionnelle = Phase 4 (#6/#577) (ADR-013 déc. 2/3 + ADR-014 §4). - Notifications MP (#313)
- Recherche intra-topic (#546/#576/#585) —
transsearch.php, saut préc./suiv., filtre pseudo, tout-le-sujet - Mode plein écran (#518)
- Onglet « DT » conditionnel dans les Drapeaux (réglage section DT, OFF par défaut)
Livrable : gestion complète des MPs, y compris les MultiMPs (lecture, écriture, membres) et la reprise de position de lecture DT.
Statut (2026-06-20) — Phase 3 ✅ Livrée (clôture #598). L’épic Messages est livré et shippé : MP lecture (#298), reply/quote MP (#301), nouveau MP + nouveau MultiMP, gestion des membres MultiMP via
newdest(#606/#612), onglet DT + reprise de position MPStorage, recherche intra-topic (#546), plein écran (#518), parité des gestes de lecture topic↔MP (#351 a/b/c), et le déclencheur de synchronisation de position de lecture DT (#597, UPDATE-ONLY opt-in OFF).Reste explicitement reporté (hors clôture Phase 3) :
- Synchronisation MPStorage bidirectionnelle complète + activation opt-in par défaut + cache Room → umbrella #6, requalifié Phase 4 (questions de fond non tranchées : fréquence, conflits, format v1/v2, clé write-back).
- #531 (réconcilier le lu/non-lu serveur des MP, re-unread best-effort) — polish, pas du fonctionnel manquant ; suivi en backlog Polish & UX, pas dans la clôture.
Lancer
/spec-realitypour figer l’alignement specs↔code avant un bump de version specs.
Phase 4 — Extensions communautaires + refonte UI pré-1.0 🚧 en cours
Objectif : les features inspirées des userscripts HFR et la refonte UI avant la 1.0.
Extensions communautaires :
- Architecture d’extensions (
PostDecorator,TopicToolbarContributor) — prospective,:core:extensionest encore une coquille vide (cf. extensions.md) - Bookmarks — sauvegarder des posts
- Blacklist — masquer des utilisateurs — ✅ livrée par anticipation (bêta 0.15.0, #509), hors module d’extension dédié (DataStore JSON +
:feature:settings, cf. extensions.md) - Alertes Qualitay — signaler un post remarquable
- Redflag — alertes intelligentes sur topics suivis (dépend du Worker
hfr-redflag)
Synchronisation MPStorage (suite Phase 3, requalifiée ici) :
- Activation de l’écriture MPStorage opt-in par défaut + clé write-back tranchée (#597 reste OFF en attendant) — umbrella #6 / #577
- Cache Room du contenu MP (opt-in, ADR-013 étage 3) + synchronisation bidirectionnelle
Refonte UI pré-1.0
Mandat de refonte des écrans chauds avant la 1.0 (post HFR XaTriX 2788560) :
- Refonte de la vue Drapeaux — #603
- Refonte de la vue Topic — #604
- Hygiène repo / audit des dérives — #605 (cadrage + audit + purge des branches
feature/*obsolètes ; à démarrer en premier)
Livrable : les features communautaires les plus demandées + une UI refondue prête pour la 1.0.
Polish & UX — backlog continu ♾️
Pas une étape finale. Anciennement « Phase 5 ». Le milestone GitHub est renommé « Polish & UX (backlog continu) » et le label
phase-5est devenupolish. Les raffinements sont livrés en continu tout au long du projet — beaucoup le sont déjà (thème AMOLED #286, transitions, swipe de pages, ascenseur, etc.). L’historique de livraison se lit dans lesCHANGELOG.md(racine +app/CHANGELOG.md), pas ici.
Objectif : l’expérience utilisateur raffinée, en continu.
- Animations et transitions (raffinements continus)
- Mode offline complet (lecture + file d’attente d’écriture)
- Notifications push configurables
- Thème dynamique (Material You)
- Thème “HFR classique”
- Widgets Android
- Tests de performance (scroll, cold start, mémoire)
- Release automation — pipeline bêta/prod live (Play open testing + F-Droid, signed AAB via
--init-script, guard CIversionName)
Livrable : une app continuellement raffinée pour le grand public.
Participation
Chaque phase sera trackée via les issues GitHub et des milestones. Les contributions sont les bienvenues à partir de la Phase 1.
Pour contribuer :
- Choisir une issue non assignée
- Commenter pour signaler qu’on la prend
- Ouvrir une PR sur une branche feature
- Review par un mainteneur