Rencontre de l'équipe et présentation du projet MONA par Lena via Zoom. Découverte des outils,
des enjeux et des problématiques.
Utilisation de l'application Android pour un état des lieux. Téléchargement
d'Android Studio et début d'apprentissage de Kotlin.
Apprentissage du Kotlin, familiarisation avec le code de l'application ; je n'ai pas
d'expérience en développement Android. Je lis les rapports des anciens étudiants pour
avoir une idée globale. Après quelques recherches, je doute qu'il soit plus facile de refaire
une app avec React.js
(trop de travail), mais
j'ai vu Ionic
qui pourrait être
intéressant.
Update lundi 6 : j'ai patché le bug de l'œuvre du jour (section vide, à cause d'une sélection
aléatoire invalide d'une œuvre), qui menait au crash de l'application si l'on essayait depuis
la page de l'œuvre du jour de :
- Prendre une photo ;
- Cibler l'œuvre d'art ;
- Accéder à son emplacement sur la carte.
En fait, l'ancien code déterminait l'ID de l'œuvre en partant du numéro de mois notamment, et
le divisait par 2. Cependant les mois de janvier et février ont les numéros respectifs 0 et 1,
et la division euclidienne par 2 renvoie donc 0 pour ces deux-là, ce qui mène à un
ID = 0
, qui est bien sûr invalide. J'ai décidé de déterminer l'ID de l'œuvre en
initialisant un RNG (Random Number Generator) avec une seed unique dans le temps
(JOUR_ANNEE * 10000 + ANNEE)
, puis en générant un entier entre 1 et la taille de la DB des
œuvres.
Je vais essayer de résoudre le problème de caméra qui affecte les Google Pixel d'ici mercredi 8
prochain.
Update mardi 7 : j'ai résolu le problème de l'appareil photo cassé sur les Google Pixel !
Le problème était causé par une mauvaise syntaxe de la fonction
dispatchTakePictureIntent
de la classe œuvreJourFragment
. Normalement
le problème ne devrait plus réapparaître.
Update mardi 7, plus tard : il semblerait que le bug persiste hors du contexte de
l'œuvre du jour... Le problème, c'est que je n'arrive pas à déterminer la section qui gère ce
bouton.
Update mardi 7 (encore) : j'ai enfin réussi à supprimer l'exception levée à l'obtention
de certains badges ! Il arrivait qu'un booléen soit null
ce qui levait une
exception d'assertion.
À la dernière réunion, on a discuté d'une réécriture complète de l'application, en
Kotlin ou probablement dans un autre langage avec l'aide d'un framework : quitte à
devoir réécrire le code en vue de la migration vers l'API v3, ce serait peut-être
une bonne occasion pour faire table rase.
Lena m'a chargé de faire un comparatif des frameworks/langages du marché pour se faire
une idée et potentiellement en choisir un. On tombe assez rapidement sur 3
possibilités : Flutter,
React Native et Ionic.
| Ionic
| React Native
| Flutter
| Kotlin
| Swift
|
Performances |
Bonnes |
Bonnes |
Très bonnes |
Maximales |
Maximales |
Taille APK "Hello world!" |
3500 Ko |
7000 Ko |
7500 Ko |
550 Ko |
?? |
Avantage particulier |
Très facile à apprendre, multi-plateforme |
Utile pour le multi-plateforme proche des éléments natifs |
Agréable à développer, performant |
Natif, 100% compatible JVM, performant |
Natif, facile à développer, performant |
Désavantage particulier |
Peu adapté aux projets de grande échelle, feeling web |
Apprendissage relativement difficile |
Nécessite la connaissance de Dart |
Verbeux, contraignant, relativement laid |
Exclusif aux produits Apple |
Tous les langages/frameworks peuvent utiliser les composants de
l'appareil (caméra, GPS et stockage). J'ai un peu de mal à saisir la différence entre Ionic et React Native,
mais je crois qu'alors que React Native manipule des éléments natifs
par une sous-couche Kotlin (et passe par le JS pour l'implémentation),
Ionic utilise un arbre DOM, en HTML couplé au CSS pour le rendu ; cela
vient avec tous les défauts et qualités du Web, notamment pour les
performances.
Cependant, le post de blog de Ionic
(et malgré son biais évident), montre que les performances des deux se
valent, voire une meilleure utilisation GPU d'Ionic selon l'analyseur
de Xcode.
Update vendredi 10 : j'ai essayé de reproduire l'interface de base
de l'application sur Ionic. Ca semble assez facile, bien que la tentative
reste très simple et reste de l'interface.
Nous avons pu rencontrer Guy Lapalme à l'occasion de la dernière réunion. J'ai pu y présenter
les différentes alternatives qui se présentent à l'équipe, dans l'optique de reconstruire
l'application. De toutes les options, la majorité du groupe a penché vers Ionic.
Je me suis attelé à l'apprentissage d'Ionic auquel est associé Vue.js
J'ai eu du mal à implémenter la carte dans l'application en utilisant Leaflet,
si bien que j'ai fini par abandonner au profit d'OpenLayers.
L'intégration était beaucoup plus naturelle et c'était plus agréable. Je me suis ensuite concentré
sur la création des classes de bases de données de l'application. J'ai pu télécharger les
données automatiquement depuis l'API V3, mais je n'ai pas encore réussi à écrire le contenu
dans un fichier stable.
Nous avons eu une réunion avec Barbara, la graphiste. Elle a conçu un nouveau tutoriel
et nous a expliqué comment se servir de Figma pour exporter les différents assets dont
on peut avoir besoin. C'était très intéressant.
Update 25/02 : j'ai réussi à faire en sorte que l'application lise et écrive dans
des fichiers.
Update 26/02 : j'ai changé le style de la carte de
Watercolor à
Toner Lite. C'était
marrant mais pas très accessible come style de tuiles.
Update 01/03 : j'a retravaillé la page de découverte du jour. Elle est plus propre
en termes de code, et correspond mieux aux mockups du Figma.
Je poursuis le travail de l'application. J'ai essayé de faire un splash screen pour
temporiser le temps que l'application récupère les données. Au final, j'ai trouvé une meilleure
solution qui consiste à lancer les bases de données avant l'ouverture de l'application pour
éviter de lancer l'interface avant le chargement des œuvres. Je compte maintenant travailler
sur la prise de photo depuis la page des détails d'une découverte.
Update 04/03 : je suis en train d'implémenter la prise de photos depuis les détails d'une
oeuvre. Je travaille aussi sur la page de notation d'une œuvre. L'apparence devrait être terminée
pour les 2. Il faut maintenant travailler sur le code interne.
J'ai ajouté la prise de photo, puis j'ai conçu la page de review d'une œuvre. En revanche, impossible
de téléverser la photo au serveur. J'ai passé 4 jours à essayer différentes méthodes mais je serveur me
renvoie inévitablement une
erreur code 422 avec comme "explication" : {'message': 'The given data was invalid.', 'errors': {'photo': ['The photo must be a file of type: jpeg, jpg, png.']}}
. J'ai essayé tellement de manière différentes, je me demande si le serveur n'accepte pas un format de données particulier, et
la documentation n'est pas assez précise.
Le problème de téléversement est résolu ! Abdelhakim s'est penché sur le problème et a réussi à
trouver un moyen de faire la requête correctement (merci à lui et à Thomas de m'avoir aidé).
J'ai donc pu finir le système de prise de photo et ça fonctionne (enfin presque : il arrive que
la photo ne soit pas prise en compte localement et ça marche au 2e essai, il faut
que je regarde pourquoi).
D'un autre côté, j'ai retravaillé complètement la manière dont les pins sont affichés sur la
carte, maintenant tous les pins (peu importe leur asset) sont affichés sur une seule layer
alors qu'il en fallait une par asset auparavant (approximativement une dizaine). Je réfléchis
aussi à retirer le bouton de changement du fond de carte. En effet, il manque des tuiles aux fonds
Stamen à partir d'un certain zoom (issue #97).
J'ai mis en place le système de popup focus sur la carte quand on clique sur une découverte.
Normalement tout fonctionne correctement en termes de focus/unfocus automatique (unfocus si on
appuie ailleurs par exemple). Idéalement il faudrait que j'augmente la hitbox des pins (ou
celle du clic) pour faciliter l'UX.
Nous avons eu le point de mi-session avec M. Lapalme. Il nous a rappelé l'importance du recul
sur notre travail, et qu'il fallait qu'on soit prêts à expliquer, avec un esprit critique,
le travail effectué au long de la session.
J'ai pu finaliser l'implémentation des pages de connexion et d'inscription. À cause de certains
enjeux d'ordre d'exécution et de programmation asynchrones, j'ai aussi décidé d'ajouter une
page de chargement des données utilisateur pour préparer l'application avant chaque lancement.
J'ai fait la page de la liste des découvertes. Pour l'instant il n'y a aucun filtre, et elle
affiche les découvertes triées par ID (plus simple pour certaines raisons techniques).
J'ai aussi fini une implémentation de la géolocalisation. Normalement ça fonctionne OK, mais
il faudra s'assurer du bon fonctionnement avec les permissions sur Android Studio.
J'ai bien avancé sur la structure générale. J'ai pu implémenter :
- la page Liste (triée alphabétiquement) et une barre de recherche intégrée
- la page Collection
- la page Autres
- les sous-pages "À propos" et "Qui sommes-nous ?"
- le tutoriel
En plus de cela, j'ai retravaillé l'onglet carte pour améliorer encore les performances :
plutôt que de mettre 1 layer par style de feature, j'ai réussi à mettre tous les pins sur une
seule layer.
J'ai aussi pu gérer les permissions et le moment où elles sont demandées, et j'ai ajouté une
page qui s'ouvre s'il manque des permissions à l'application.
J'ai réussi à implémenter la récupération des données (collection, et photos s'il y en a) au
moment de la connexion, ainsi que la fonctionnalité qui permet à la DB de se mettre à jour
toute seule. Je n'ai pas pu tester cette dernière cependant, mais le code est assez simple donc
je doute qu'il y ait des problèmes. J'ai rencontré un problème : le serveur bloque les requêtes
au-delà de 60/minute. J'ai demandé à Natacha d'augmenter cette limite à 240/minute mais
il faudra tôt ou tard implémenter une classe pour gérer les temps d'attente forcés.
J'ai mis à jour l'application sur le Play Store en interne avec cette version.
C'était assez facile, je m'attendais à avoir des problèmes avec les permissions mais il semble
que non. J'en ai profité pour changer les images d'illustration de la page de l'app, qui datent
trop et qui sont en trop mauvaise résolution.
J'ai commencé à implémenter la page des badges sur le menu collection. Pour simplifier et
accélérer le développement, je ne pars pas (du moins pour le moment) sur l'idée de deux onglets
en haut comme sur le Figma,
mais sur un bouton centré qui redirige vers un composant Vue. Ca n'est pas optimal mais ça aura
le mérite de fonctionner tout autant.
J'ai aussi (enfin) réussi à mettre l'icône à l'application, qui gardait celle par
défaut jusqu'à maintenant. J'ai dû télécharger le fichier Illustrator et changer la taille du motif
central parce qu'il est trop grand et ne tient pas dans le cercle inscrit (et donc il dépassait,
voir exemple). J'ai testé sur Android 13 et ça fonctionne,
mais pas encore vérifié sur les versions plus anciennes.
Un test avec un autre appareil m'a fait réaliser que lorsqu'on demande les permissions de
géolocalisation alors que le GPS est désactivé, la requête crashe. J'ai résolu ce problème.
Nous avons eu la réunion de test mercredi dernier, qui nous a valu un retour utilisateur très
utile. Nous avons trouvé des bugs, ainsi que plusieurs remarques pertinentes concernant l'UX :
Bugs :
- Le serveur n'accepte pas les images plus grande que 2 Mo par sa configuration (problème critique)
- La recherche par mots-clefs ne gère pas les lettres accentuées
- Il arrive que la photo sur la page des détails d'une découverte ne s'affiche pas
- Il arrive que le titre d'une découverte dépasse du popup sur la carte.
Suggestions d'amélioration de l'UX :
- Ajouter une estimation de la précision du GPS, qui se met à jour en temps réel
- Augmenter la taille du bouton "rafraîchir" et changer son icône pour le rendre plus clair
- Afficher l'adresse ou l'emplacement de la découverte sur sa page des détails
- Rendre les pages d'inscription/connexion plus claires sur leur nature respective
- La police de la description d'une découverte est un peu trop petite et difficile à lire.
Les éléments marqués d'un ✅
ont été corrigés.
À propos du texte qui dépasse des popups sur la carte, j'en ai retravaillé complètement
le CSS. On ne devrait plus avoir ce problème. Le problème du serveur n'est pas encore corrigé
mais cela devrait être assez facile, si l'on trouve quelqu'un qui a les droits super user.
J'estime que 32 Mo est une limite suffisante pour ne plus rencontrer ce problème du tout. Si
c'est trop grand, 16 Mo est, je pense, le minimum absolu. Avec l'augmentation de la qualité photo des
appareils ainsi que l'agrandissement du stockage interne, une photo lambda pèse facilement 5+ Mo.
De plus, étant donné qu'on donne la possibilité d'envoyer un photo depuis la galerie, il faut
s'attendre à ce que les photos puissent atteindre les 10 Mo (un panorama par exemple a une très
grande résolution).
Raouf a augmenté la limite de taille des requêtes POST à 8 Mo. Ce n'est pas assez à mon avis
mais ça suffira pour conclure la session. Je vais mettre plus de compression sur les photos
pour gérer ça.