fix: replace broken swipe-to-refresh with toolbar button (#61) #67

Merged
maximus merged 1 commit from issue-61-refresh-button-toolbar into master 2026-04-09 13:44:09 +00:00
Owner

Fixes #61

Problème

Le RefreshControl ajouté dans la PR #64 ne déclenchait aucun feedback visuel. Cause : react-native-draggable-flatlist enveloppe son FlatList interne dans un GestureDetector avec Gesture.Pan(), qui intercepte les swipes verticaux avant que RefreshControl puisse les détecter — particulièrement avec activationDistance=0 en mode sort position (le défaut).

Fix

  • Bouton refresh (RefreshCw de lucide-react-native) ajouté dans la toolbar de l'inbox et du détail de liste
  • Animation spin (Animated.loop avec rotation) pendant le refresh, cohérent avec l'UX web
  • Tout le code mort lié au swipe-to-refresh retiré (RefreshControl, prop refreshControl sur DraggableFlatList)

Test plan

  • Bouton refresh visible dans la toolbar de l'inbox
  • Bouton refresh visible dans la toolbar du détail de liste
  • Tapper sur le bouton déclenche une animation spin et recharge les données
  • Plus aucun import ou usage de RefreshControl
Fixes #61 ## Problème Le `RefreshControl` ajouté dans la PR #64 ne déclenchait aucun feedback visuel. Cause : `react-native-draggable-flatlist` enveloppe son FlatList interne dans un `GestureDetector` avec `Gesture.Pan()`, qui intercepte les swipes verticaux avant que `RefreshControl` puisse les détecter — particulièrement avec `activationDistance=0` en mode sort `position` (le défaut). ## Fix - Bouton refresh (`RefreshCw` de `lucide-react-native`) ajouté dans la toolbar de l'inbox et du détail de liste - Animation `spin` (Animated.loop avec rotation) pendant le refresh, cohérent avec l'UX web - Tout le code mort lié au swipe-to-refresh retiré (`RefreshControl`, prop `refreshControl` sur DraggableFlatList) ## Test plan - [ ] Bouton refresh visible dans la toolbar de l'inbox - [ ] Bouton refresh visible dans la toolbar du détail de liste - [ ] Tapper sur le bouton déclenche une animation spin et recharge les données - [ ] Plus aucun import ou usage de `RefreshControl`
maximus added 1 commit 2026-04-09 13:35:12 +00:00
The RefreshControl on DraggableFlatList never worked because the
library wraps its FlatList in a GestureDetector with Gesture.Pan(),
which intercepts vertical swipes before RefreshControl can detect
them — particularly with activationDistance=0 in position sort mode.

Replace with a toolbar refresh button (RefreshCw icon) on inbox and
list detail screens. The button uses an Animated spin during refresh,
matching the web UX. Removes all dead RefreshControl code and the
useless refreshControl prop.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
maximus force-pushed issue-61-refresh-button-toolbar from f273e4ad8b to 5b0d27175c 2026-04-09 13:38:37 +00:00 Compare
Author
Owner

Verdict : APPROVE

Summary

Le fix remplace correctement le RefreshControl intercepte par le GestureDetector interne de react-native-draggable-flatlist par un bouton dans la toolbar avec animation de rotation. Code propre, coherent entre inbox et detail de liste, aucun secret ni regression.

Suggestions (non bloquantes)

  1. app/(tabs)/index.tsx:91 et app/list/[id].tsx:116spinAnim.stopAnimation() arrete la valeur courante a son angle actuel. Au prochain handleRefresh, le spinAnim.setValue(0) remet a zero, mais entre deux refreshs l'icone peut rester figee a un angle arbitraire. Envisager spinAnim.stopAnimation(() => spinAnim.setValue(0)) pour un rendu plus propre au repos.

  2. Double boucle de rafraichissement — Il y a deja un setInterval(loadTasks, 500) qui recharge toutes les demi-secondes (index.tsx:71, list/[id].tsx:96). Le bouton refresh est donc essentiellement cosmetique. Pas bloquant, mais a considerer a terme en remplacant le polling par des live queries.

  3. Accessibilite — Le Pressable du bouton refresh n'a pas de accessibilityLabel. Coherent avec les autres boutons de la toolbar, mais dette a11y a garder en tete.

  4. Dependance spinAnimspinAnim est un useRef, sa reference ne change jamais. Pas besoin de le lister dans les dependances de useCallback, mais exhaustive-deps l'encourage donc ok.

Checklist

  • Pas de secrets, aucune chaine visible ajoutee (bouton icone seul) donc pas de besoin i18n
  • Pas de modification de migrations SQL
  • Convention de commit conforme
  • PR reference bien l'issue (Fixes #61)
  • Code mort (RefreshControl) correctement retire des deux ecrans

Review adversariale via /pr-review

## Verdict : APPROVE ### Summary Le fix remplace correctement le `RefreshControl` intercepte par le `GestureDetector` interne de `react-native-draggable-flatlist` par un bouton dans la toolbar avec animation de rotation. Code propre, coherent entre inbox et detail de liste, aucun secret ni regression. ### Suggestions (non bloquantes) 1. **`app/(tabs)/index.tsx:91` et `app/list/[id].tsx:116`** — `spinAnim.stopAnimation()` arrete la valeur courante a son angle actuel. Au prochain `handleRefresh`, le `spinAnim.setValue(0)` remet a zero, mais entre deux refreshs l'icone peut rester figee a un angle arbitraire. Envisager `spinAnim.stopAnimation(() => spinAnim.setValue(0))` pour un rendu plus propre au repos. 2. **Double boucle de rafraichissement** — Il y a deja un `setInterval(loadTasks, 500)` qui recharge toutes les demi-secondes (index.tsx:71, list/[id].tsx:96). Le bouton refresh est donc essentiellement cosmetique. Pas bloquant, mais a considerer a terme en remplacant le polling par des live queries. 3. **Accessibilite** — Le `Pressable` du bouton refresh n'a pas de `accessibilityLabel`. Coherent avec les autres boutons de la toolbar, mais dette a11y a garder en tete. 4. **Dependance `spinAnim`** — `spinAnim` est un `useRef`, sa reference ne change jamais. Pas besoin de le lister dans les dependances de `useCallback`, mais exhaustive-deps l'encourage donc ok. ### Checklist - Pas de secrets, aucune chaine visible ajoutee (bouton icone seul) donc pas de besoin i18n - Pas de modification de migrations SQL - Convention de commit conforme - PR reference bien l'issue (`Fixes #61`) - Code mort (`RefreshControl`) correctement retire des deux ecrans --- _Review adversariale via `/pr-review`_
maximus merged commit fe43b65cfd into master 2026-04-09 13:44:09 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: maximus/simpl-liste#67
No description provided.