Blog
Feature
18 octobre 20258 min

Video mobile et drag-and-drop React Native : guide UX

Il y a une différence entre une app qui fonctionne et une app qui donne envie d'être utilisée. Cette différence, elle se joue dans les détails : la fluidité d'une animation, la réactivité d'un geste, le temps de chargement d'un écran. En octobre 2025, j'ai passé deux semaines à travailler sur trois features qui n'avaient rien en commun sauf un objectif : rendre TAMSIV moderne et agréable à utiliser.

Capture vidéo façon TikTok. Drag-and-drop pour réorganiser les onglets. Carousel infini dans le feed. Trois chantiers distincts, une seule obsession : la sensation de fluidité.

Points clés à retenir :
- La compression vidéo est indispensable sur mobile — les fichiers bruts pèsent 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 nécessite le pré-chargement des éléments adjacents
- La sauvegarde de l'ordre des onglets en base permet la persistance cross-device
- Les micro-interactions sont ce qui différencie une app "correcte" d'une app "remarquable"

Pourquoi intégrer une capture vidéo dans une app de productivité ?

La question semble bizarre au premier abord. Une app de gestion de tâches n'a pas besoin de vidéo, non ? En réalité, si. Quand tu crées un mémo vocal avec TAMSIV, tu veux parfois y joindre une pièce jointe visuelle — une photo d'un document, une vidéo d'un prototype, un enregistrement d'écran.

J'avais déjà implémenté les pièces jointes (photos et documents). Mais la vidéo manquait. Et quand j'ai commencé à prototyper l'interface, j'ai réalisé qu'une capture vidéo classique — le composant caméra brut d'Android — était horrible. Pas de style, pas de fluidité, une expérience digne de 2015.

L'inspiration est venue d'où tu t'y attends : TikTok. Pas pour les vidéos courtes, mais pour l'interface de capture. Bouton central, aperçu plein écran, contrôles minimaux. C'est devenu le standard UX que les utilisateurs attendent en 2026.

Personne tenant un smartphone en mode portrait pour enregistrer une vidéo avec une interface de caméra moderne
L'interface de capture vidéo de TAMSIV : inspiration TikTok, exécution minimaliste.

Comment gérer la compression vidéo sur mobile ?

C'est le plus gros défi technique de la capture vidéo. Les vidéos brutes d'un smartphone moderne pèsent des dizaines de mégaoctets pour quelques secondes. Un iPhone 15 enregistre en HEVC 4K à 60fps — ça peut atteindre 400 Mo par minute. Même en 1080p, une vidéo de 30 secondes pèse facilement 50 Mo.

Pour une app de productivité, c'est inacceptable. Les pièces jointes sont stockées dans Supabase Storage, et chaque Mo d'egress coûte de l'argent. J'ai d'ailleurs détaillé les problèmes d'egress dans l'article sur la réduction des coûts Supabase.

La solution : configurer la capture pour limiter la résolution et le bitrate dès le départ. Plutôt que de capturer en 4K et compresser ensuite (ce qui consomme CPU et batterie), je configure le composant caméra pour capturer directement dans un format léger :

  • Résolution : 720p maximum (suffisant pour des pièces jointes)
  • Bitrate : limité à 2 Mbps
  • Format : H.264 pour la compatibilité universelle
  • Durée maximale : 60 secondes (limite volontaire pour éviter les fichiers énormes)

Avec ces paramètres, une vidéo de 30 secondes pèse environ 3 à 5 Mo au lieu de 50 Mo. Un gain de facteur 10 qui rend le stockage et le transfert viables.

Quel est le piège du plein écran sur Android ?

L'aperçu plein écran de la caméra semble trivial. Ça ne l'est pas. Sur Android, le ratio de l'écran (généralement 19.5:9 ou 20:9) ne correspond pas au ratio de la caméra (16:9 ou 4:3). Résultat : soit tu affiches des bandes noires, soit tu crops l'image, soit tu étires.

J'ai opté pour le crop avec un léger zoom — ce que fait TikTok. L'image remplit tout l'écran, mais les bords sont légèrement coupés. L'utilisateur ne le remarque pas. La sensation d'immersion est préservée.

Le deuxième piège : la gestion de l'orientation. TAMSIV force le mode portrait pour la capture vidéo (cohérent avec l'usage mobile), mais il faut intercepter les changements d'orientation du device pour éviter que la vidéo soit enregistrée à l'envers. Un bug classique que j'ai mis une demi-journée à traquer.

Comment implémenter le drag-and-drop des onglets ?

TAMSIV a 6 onglets principaux : Dictaphone, Feed, Agenda, Groupes, Social, Profil. L'ordre par défaut convient à la plupart des utilisateurs, mais certains préfèrent un autre arrangement. J'ai implémenté la réorganisation par drag-and-drop : appui long sur un onglet, glisser, relâcher.

Écran de tablette montrant une interface d'application mobile avec des icônes d'onglets réorganisables par glisser-déposer
Drag-and-drop des onglets : personnalise ton expérience TAMSIV.

L'implémentation utilise react-native-gesture-handler (obligatoire dans React Native pour les gestes complexes) combiné avec react-native-reanimated pour les animations fluides.

Le gotcha majeur : gesture-handler obligatoire

C'est un piège dans lequel j'ai perdu des heures. Dans un GestureDetector, il faut obligatoirement utiliser les composants de react-native-gesture-handlerTouchableOpacity, FlatList, ScrollView — et jamais ceux de react-native. Les composants natifs ne reçoivent tout simplement pas les événements 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 à chercher un problème de logique alors que c'est juste un mauvais import. C'est devenu une règle cardinale du projet : dans tout composant utilisant des gestes, vérifier les imports.

La persistance cross-device

L'ordre des onglets est sauvegardé en base de données dans userProfile.mainTabsOrder. Ce n'est pas juste du AsyncStorage local — si l'utilisateur se connecte sur un autre appareil ou réinstalle l'app, il retrouve sa configuration. Ce détail semble mineur mais contribue à la sensation d'une app "intelligente" qui te connaît.

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 réarrange la navigation en conséquence. Si un onglet manque (par exemple après un ajout de feature), il est ajouté à la fin.

Comment fonctionne le carousel infini dans le feed ?

Le feed de TAMSIV affiche un flux d'éléments : tâches, mémos, événements, activité de gamification. Quand tu cliques sur un élément, tu veux pouvoir naviguer vers le précédent ou le suivant sans revenir à la liste. C'est le pattern du carousel infini.

L'implémentation repose sur un composant FlatList horizontal (de react-native-gesture-handler, bien sûr) avec un système de pré-chargement des éléments adjacents. Quand tu visualises l'élément N, les éléments N-1 et N+1 sont déjà chargés en mémoire et rendus hors écran.

Personne faisant défiler un flux de contenu sur smartphone avec des cartes et des images qui se chargent de manière fluide
Le carousel infini : pas de spinner, pas de chargement visible.

Le résultat : pas de spinner, pas de chargement visible. L'illusion d'un contenu toujours prêt. Le swipe est instantané. C'est ce genre de détail invisible qui fait la différence entre une app qu'on utilise par obligation et une app qu'on utilise par plaisir.

Le défi de la mémoire

Le pré-chargement a un coût : la mémoire. Si chaque élément du feed contient des images ou des vidéos, charger 3 éléments en même temps (courant + 2 adjacents) peut consommer beaucoup de RAM. J'ai mis en place un système de recyclage : les éléments éloignés (N-3, N+3 et au-delà) sont libérés de la mémoire. Seule la fenêtre glissante de 5 éléments est maintenue.

Ce pattern est d'ailleurs directement lié au système de cache que j'ai construit plus tard. Les signed URLs Supabase qui expirent après 60 minutes rendent le pré-chargement encore plus critique : les URLs doivent être fraîches quand l'utilisateur swipe.

Pourquoi les micro-interactions sont-elles si importantes ?

Ces trois features — capture vidéo, drag-and-drop, carousel — sont invisibles individuellement. Personne ne télécharge une app pour son drag-and-drop d'onglets. Mais collectivement, elles créent une sensation de fluidité qui fait toute la différence.

Les études UX de Nielsen Norman Group montrent que la perception de qualité d'une app est davantage influencée par les micro-interactions que par les features principales. Un temps de réponse de 100ms est perçu comme instantané. Au-delà de 300ms, l'utilisateur commence à sentir un délai.

C'est exactement la philosophie que j'ai suivie pour le bouton IA animé : chaque interaction doit sentir "vivante". L'animation du bouton d'enregistrement vidéo, le feedback haptique lors du drag-and-drop, le snap magnétique du carousel — tout contribue à cette sensation.

J'ai mesuré l'impact de ces changements avec les analytics Firebase. Le temps moyen passé dans l'app a augmenté après le déploiement de ces features. Pas parce qu'elles ajoutent des fonctionnalités, mais parce qu'elles rendent l'usage plus agréable. Les utilisateurs restent plus longtemps quand l'app est fluide.

Quels outils utiliser pour les animations fluides en React Native ?

Pour obtenir des animations à 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, zéro jank
  • react-native-gesture-handler : gestion des gestes directement sur le thread natif
  • LayoutAnimation : pour les transitions de layout simples (ajout/suppression d'éléments)

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 différence de fluidité est immédiate et massive.

J'ai détaillé l'utilisation de cette stack dans l'article sur la recherche contextuelle avec swipe, où le geste de swipe-back pour fermer les écrans de détail utilise exactement le même pattern.

Ce que ces détails m'ont appris sur le développement mobile

Ces deux semaines de travail sur les "détails" ont été 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 disproportionné sur l'expérience utilisateur.

C'est une leçon que j'ai apprise à mes dépens : en tant que dev solo, la tentation est de toujours courir après la prochaine grosse feature. Mais les utilisateurs ne voient pas les features. Ils ressentent l'expérience. Et l'expérience, c'est la somme de centaines de micro-décisions : le délai d'une animation, la taille d'une zone de touch, le feedback d'un geste.

Ça rejoint ce que j'explique dans l'article sur l'onboarding : la première impression est cruciale, et elle se joue dans ces détails. Un onboarding fluide avec des animations soignées donne confiance. Un onboarding saccadé avec des transitions brutales donne envie de désinstaller.

FAQ

Pourquoi limiter la durée des vidéos à 60 secondes ?

Pour garder les fichiers légers et le stockage viable. À 2 Mbps en 720p, 60 secondes représentent environ 8 Mo. Au-delà, les temps d'upload et les coûts de stockage deviennent problématiques pour une app de productivité qui n'est pas centrée sur la vidéo.

Le drag-and-drop des onglets fonctionne-t-il sur iOS ?

Oui. L'implémentation utilise react-native-gesture-handler et react-native-reanimated, qui sont cross-platform. Le même code fonctionne sur Android et iOS sans modification. Seuls les ajustements de retour haptique sont spécifiques à chaque plateforme.

Le carousel infini ne consomme-t-il pas trop de mémoire ?

Non, grâce au système de recyclage. Seuls 5 éléments sont maintenus en mémoire (l'élément courant + 2 de chaque côté). Les éléments plus éloignés sont libérés. Sur les appareils avec peu de RAM, la fenêtre peut être réduite à 3 éléments.

Peut-on désactiver la personnalisation des onglets ?

L'ordre par défaut est restaurable à tout moment via les paramètres de l'app. Un bouton "Réinitialiser" remet l'ordre original. L'ordre personnalisé est aussi supprimé si l'utilisateur se déconnecte.

Pourquoi ne pas utiliser Lottie pour les animations ?

Lottie est excellent pour les animations illustratives (icons animées, splash screens) mais n'est pas adapté aux animations interactives pilotées par les gestes. react-native-reanimated permet de lier directement le geste à l'animation, frame par frame, ce que Lottie ne peut pas faire.