Video mobile et drag-and-drop React Native : guide UX
Il y a une difference entre une app qui fonctionne et une app qui donne envie d'etre utilisee. Cette difference, elle se joue dans les details : la fluidite d'une animation, la reactivite d'un geste, le temps de chargement d'un ecran. En octobre 2025, j'ai passe deux semaines a travailler sur trois features qui n'avaient rien en commun sauf un objectif : rendre TAMSIV moderne et agreable a utiliser.
Capture video facon TikTok. Drag-and-drop pour reorganiser les onglets. Carousel infini dans le feed. Trois chantiers distincts, une seule obsession : la sensation de fluidite.
Points cles a retenir :
- La compression video est indispensable sur mobile — les fichiers bruts pesent des dizaines de Mo
- Le drag-and-drop des onglets utilise obligatoirement react-native-gesture-handler, pas les composants natifs
- Un carousel infini bien fait necessite le pre-chargement des elements adjacents
- La sauvegarde de l'ordre des onglets en base permet la persistance cross-device
- Les micro-interactions sont ce qui differencie une app "correcte" d'une app "remarquable"
Pourquoi integrer une capture video dans une app de productivite ?
La question semble bizarre au premier abord. Une app de gestion de taches n'a pas besoin de video, non ? En realite, si. Quand tu crees un memo vocal avec TAMSIV, tu veux parfois y joindre une piece jointe visuelle — une photo d'un document, une video d'un prototype, un enregistrement d'ecran.
J'avais deja implemente les pieces jointes (photos et documents). Mais la video manquait. Et quand j'ai commence a prototyper l'interface, j'ai realise qu'une capture video classique — le composant camera brut d'Android — etait horrible. Pas de style, pas de fluidite, une experience digne de 2015.
L'inspiration est venue d'ou tu t'y attends : TikTok. Pas pour les videos courtes, mais pour l'interface de capture. Bouton central, apercu plein ecran, controles minimaux. C'est devenu le standard UX que les utilisateurs attendent en 2026.
Comment gerer la compression video sur mobile ?
C'est le plus gros defi technique de la capture video. Les videos brutes d'un smartphone moderne pesent des dizaines de megaoctets pour quelques secondes. Un iPhone 15 enregistre en HEVC 4K a 60fps — ca peut atteindre 400 Mo par minute. Meme en 1080p, une video de 30 secondes pese facilement 50 Mo.
Pour une app de productivite, c'est inacceptable. Les pieces jointes sont stockees dans Supabase Storage, et chaque Mo d'egress coute de l'argent. J'ai d'ailleurs detaille les problemes d'egress dans l'article sur la reduction des couts Supabase.
La solution : configurer la capture pour limiter la resolution et le bitrate des le depart. Plutot que de capturer en 4K et compresser ensuite (ce qui consomme CPU et batterie), je configure le composant camera pour capturer directement dans un format leger :
- Resolution : 720p maximum (suffisant pour des pieces jointes)
- Bitrate : limite a 2 Mbps
- Format : H.264 pour la compatibilite universelle
- Duree maximale : 60 secondes (limite volontaire pour eviter les fichiers enormes)
Avec ces parametres, une video de 30 secondes pese environ 3 a 5 Mo au lieu de 50 Mo. Un gain de facteur 10 qui rend le stockage et le transfert viables.
Quel est le piege du plein ecran sur Android ?
L'apercu plein ecran de la camera semble trivial. Ca ne l'est pas. Sur Android, le ratio de l'ecran (generalement 19.5:9 ou 20:9) ne correspond pas au ratio de la camera (16:9 ou 4:3). Resultat : soit tu affiches des bandes noires, soit tu crops l'image, soit tu etires.
J'ai opte pour le crop avec un leger zoom — ce que fait TikTok. L'image remplit tout l'ecran, mais les bords sont legerement coupes. L'utilisateur ne le remarque pas. La sensation d'immersion est preservee.
Le deuxieme piege : la gestion de l'orientation. TAMSIV force le mode portrait pour la capture video (coherent avec l'usage mobile), mais il faut intercepter les changements d'orientation du device pour eviter que la video soit enregistree a l'envers. Un bug classique que j'ai mis une demi-journee a traquer.
Comment implementer le drag-and-drop des onglets ?
TAMSIV a 6 onglets principaux : Dictaphone, Feed, Agenda, Groupes, Social, Profil. L'ordre par defaut convient a la plupart des utilisateurs, mais certains preferent un autre arrangement. J'ai implemente la reorganisation par drag-and-drop : appui long sur un onglet, glisser, relacher.
L'implementation utilise react-native-gesture-handler (obligatoire dans React Native pour les gestes complexes) combine avec react-native-reanimated pour les animations fluides.
Le gotcha majeur : gesture-handler obligatoire
C'est un piege dans lequel j'ai perdu des heures. Dans un GestureDetector, il faut obligatoirement utiliser les composants de react-native-gesture-handler — TouchableOpacity, FlatList, ScrollView — et jamais ceux de react-native. Les composants natifs ne recoivent tout simplement pas les evenements tactiles dans un contexte gesture-handler.
Le bug est vicieux : tout compile, il n'y a aucun warning, mais le drag-and-drop ne fonctionne pas. Tu passes des heures a chercher un probleme de logique alors que c'est juste un mauvais import. C'est devenu une regle cardinale du projet : dans tout composant utilisant des gestes, verifier les imports.
La persistance cross-device
L'ordre des onglets est sauvegarde en base de donnees dans userProfile.mainTabsOrder. Ce n'est pas juste du AsyncStorage local — si l'utilisateur se connecte sur un autre appareil ou reinstalle l'app, il retrouve sa configuration. Ce detail semble mineur mais contribue a la sensation d'une app "intelligente" qui te connait.
Le format est simple : un tableau JSON d'identifiants d'onglets. ["dictaphone", "agenda", "feed", "groups", "social", "profile"]. Au chargement, l'app lit ce tableau et rearrange la navigation en consequence. Si un onglet manque (par exemple apres un ajout de feature), il est ajoute a la fin.
Comment fonctionne le carousel infini dans le feed ?
Le feed de TAMSIV affiche un flux d'elements : taches, memos, evenements, activite de gamification. Quand tu cliques sur un element, tu veux pouvoir naviguer vers le precedent ou le suivant sans revenir a la liste. C'est le pattern du carousel infini.
L'implementation repose sur un composant FlatList horizontal (de react-native-gesture-handler, bien sur) avec un systeme de pre-chargement des elements adjacents. Quand tu visualises l'element N, les elements N-1 et N+1 sont deja charges en memoire et rendus hors ecran.
Le resultat : pas de spinner, pas de chargement visible. L'illusion d'un contenu toujours pret. Le swipe est instantane. C'est ce genre de detail invisible qui fait la difference entre une app qu'on utilise par obligation et une app qu'on utilise par plaisir.
Le defi de la memoire
Le pre-chargement a un cout : la memoire. Si chaque element du feed contient des images ou des videos, charger 3 elements en meme temps (courant + 2 adjacents) peut consommer beaucoup de RAM. J'ai mis en place un systeme de recyclage : les elements eloignes (N-3, N+3 et au-dela) sont liberes de la memoire. Seule la fenetre glissante de 5 elements est maintenue.
Ce pattern est d'ailleurs directement lie au systeme de cache que j'ai construit plus tard. Les signed URLs Supabase qui expirent apres 60 minutes rendent le pre-chargement encore plus critique : les URLs doivent etre fraiches quand l'utilisateur swipe.
Pourquoi les micro-interactions sont-elles si importantes ?
Ces trois features — capture video, drag-and-drop, carousel — sont invisibles individuellement. Personne ne telecharge une app pour son drag-and-drop d'onglets. Mais collectivement, elles creent une sensation de fluidite qui fait toute la difference.
Les etudes UX de Nielsen Norman Group montrent que la perception de qualite d'une app est davantage influencee par les micro-interactions que par les features principales. Un temps de reponse de 100ms est percu comme instantane. Au-dela de 300ms, l'utilisateur commence a sentir un delai.
C'est exactement la philosophie que j'ai suivie pour le bouton IA anime : chaque interaction doit sentir "vivante". L'animation du bouton d'enregistrement video, le feedback haptique lors du drag-and-drop, le snap magnetique du carousel — tout contribue a cette sensation.
J'ai mesure l'impact de ces changements avec les analytics Firebase. Le temps moyen passe dans l'app a augmente apres le deploiement de ces features. Pas parce qu'elles ajoutent des fonctionnalites, mais parce qu'elles rendent l'usage plus agreable. Les utilisateurs restent plus longtemps quand l'app est fluide.
Quels outils utiliser pour les animations fluides en React Native ?
Pour obtenir des animations a 60fps sur mobile, tu ne peux pas utiliser l'Animated API de base de React Native. Tout doit passer par le thread UI natif, pas le thread JavaScript. Voici la stack que j'utilise :
- react-native-reanimated : les animations tournent sur le thread natif, zero jank
- react-native-gesture-handler : gestion des gestes directement sur le thread natif
- LayoutAnimation : pour les transitions de layout simples (ajout/suppression d'elements)
La combinaison reanimated + gesture-handler est devenue le standard de facto pour les animations React Native en 2026. Si tu ne les utilises pas encore, migre. La difference de fluidite est immediate et massive.
J'ai detaille l'utilisation de cette stack dans l'article sur la recherche contextuelle avec swipe, ou le geste de swipe-back pour fermer les ecrans de detail utilise exactement le meme pattern.
Ce que ces details m'ont appris sur le developpement mobile
Ces deux semaines de travail sur les "details" ont ete parmi les plus satisfaisantes du projet. Pas parce que les features sont impressionnantes — elles ne le sont pas — mais parce qu'elles ont un impact disproportionne sur l'experience utilisateur.
C'est une lecon que j'ai apprise a mes depens : en tant que dev solo, la tentation est de toujours courir apres la prochaine grosse feature. Mais les utilisateurs ne voient pas les features. Ils ressentent l'experience. Et l'experience, c'est la somme de centaines de micro-decisions : le delai d'une animation, la taille d'une zone de touch, le feedback d'un geste.
Ca rejoint ce que j'explique dans l'article sur l'onboarding : la premiere impression est cruciale, et elle se joue dans ces details. Un onboarding fluide avec des animations soignees donne confiance. Un onboarding saccade avec des transitions brutales donne envie de desinstaller.
FAQ
Pourquoi limiter la duree des videos a 60 secondes ?
Pour garder les fichiers legers et le stockage viable. A 2 Mbps en 720p, 60 secondes representent environ 8 Mo. Au-dela, les temps d'upload et les couts de stockage deviennent problematiques pour une app de productivite qui n'est pas centree sur la video.
Le drag-and-drop des onglets fonctionne-t-il sur iOS ?
Oui. L'implementation utilise react-native-gesture-handler et react-native-reanimated, qui sont cross-platform. Le meme code fonctionne sur Android et iOS sans modification. Seuls les ajustements de retour haptique sont specifiques a chaque plateforme.
Le carousel infini ne consomme-t-il pas trop de memoire ?
Non, grace au systeme de recyclage. Seuls 5 elements sont maintenus en memoire (l'element courant + 2 de chaque cote). Les elements plus eloignes sont liberes. Sur les appareils avec peu de RAM, la fenetre peut etre reduite a 3 elements.
Peut-on desactiver la personnalisation des onglets ?
L'ordre par defaut est restaurable a tout moment via les parametres de l'app. Un bouton "Reinitialiser" remet l'ordre original. L'ordre personnalise est aussi supprime si l'utilisateur se deconnecte.
Pourquoi ne pas utiliser Lottie pour les animations ?
Lottie est excellent pour les animations illustratives (icons animees, splash screens) mais n'est pas adapte aux animations interactives pilotees par les gestes. react-native-reanimated permet de lier directement le geste a l'animation, frame par frame, ce que Lottie ne peut pas faire.