Hypertopic / Porphyry

Corpus analyses confrontation
https://hypertopic.org/porphyry
GNU Affero General Public License v3.0
21 stars 165 forks source link

Share an item on Instagram #373

Open aamina12 opened 3 years ago

aamina12 commented 3 years ago

Description

We are the team of @Hypertopic/cite-du-vitrail, we want to give the possibility to share an item on Instagram to our user. This feature is available with Facebook and Twitter. We will provide an additional web page for the explanation of how to use this feature.

Phase 1

Phase 2

Phase 3

manacheh commented 3 years ago

@benel

Voici, avec @aamina12, notre troisième version de la stratégie d'implémentation. Celle-ci est bien différente des deux autres car nous avons commencé à tester le code dans notre environnement local :

Stratégie d'implémentation

Quelle partie du code sera impactée (classes, méthodes) ?

La partie du code impactée se situe dans le fichier Item.jsx ( https://github.com/Hypertopic/Porphyry/blob/v7/src/components/itemPage/Item.jsx) : En effet, c’est dans ce fichier que la page d’un item est crée et c’est précisément dans cette page que l’on veut permettre le partage d’un item sur Instagram.

La fonctionnalité “Share an item on Instagram” ne va pas impacter le code déjà présent. Nous allons ajouter un bouton qui, lors du clic, entraînera : -Le copiage dans le presse papier des informations de l’item que l’on veut mettre dans la description lors du partage sur Instagram (le créateur, la localisation et les points de vue). -Le téléchargement de l’image de l’item sur le téléphone de l’utilisateur -L’apparition d’un message indiquant que l’image a bien été téléchargée, que les informations sont bien copiées et que l’utilisateur n’a plus qu’à se rendre sur Instagram pour publier.

Cette implémentation sera efficace uniquement sur mobile, car on ne peut pas partager de médias sur Instagram via ordinateur.

Y aura-t-il des difficultés d'un point de vue algorithmique ? Avez-vous des pistes pour les résoudre ?

Les données dont vous avez besoin sont-elles déjà chargées par la page ? Si oui, quelle est la structure des données et comment allez-vous récupérer précisément celles qui vous intéressent ? Si non, quelle sera la requête la plus efficace et comment allez-vous récupérer dans la structure de données précisément celles qui vous intéressent ?

Nous avons besoin de 3 types de données différentes :

-les attributs de l’item : nous pouvons les trouver dans la variable this.state.item (en effectuant un JSON.stringify()) :

{"name":["AXN 009"],"thumbnail":["https://steatite.utt.fr/thumbnail/dff21da25a2bebd654e81536fc5aaa8a63ab6e4f"],"resource":["https://steatite.utt.fr/picture/dff21da25a2bebd654e81536fc5aaa8a63ab6e4f"],"topic":{"56e092d8a6179a788c74b618b29801c0":[],"a76306e4f17ed4f79e7e481eb9a1bd06":[]},"item":[],"creator":["Aurélien Bénel"],"created":["2017-09-24"],"spatial":["Église Saint-Loup, Auxon"]}

En rajoutant la clé (par exemple this.state.item.creator), nous obtenons directement la valeur de l’attribut désiré (par exemple Aurélien Bénel).

-l’URL de l’image à télécharger : comme vu juste avant, on la retrouve dans la variable this.state.item.resource.

-les points de vue de l’item : nous savons qu’ils se trouvent dans la variable this.state.item.topic mais les résultats apparaissent sous cette forme :

{"56e092d8a6179a788c74b618b29801c0":[{"viewpoint":"56e092d8a6179a788c74b618b29801c0","id":"ff69b3487ba60d4d8e2ea00441bba238"},{"viewpoint":"56e092d8a6179a788c74b618b29801c0","id":"2182a45481bd0a46a58721f2a861d4bf"},{"viewpoint":"56e092d8a6179a788c74b618b29801c0","id":"8e2a5c829fee6845bb5c4b3e4cc482b4"}],"a76306e4f17ed4f79e7e481eb9a1bd06":[{"viewpoint":"a76306e4f17ed4f79e7e481eb9a1bd06","id":"e145c06d9889434596e4f1c67ed941bb"}]}

Nous n’arrivons donc pas encore à extraire les points de vue d’un item.

Existe-t-il des bibliothèques qui pourraient simplifier l'implémentation ?

Nous avons pu trouver sur npmjs.com, les bibliothèques suivantes :

react-copy-to-clipboard : permet de spécifier le texte à copier dans le presse papier, notamment par le biais d’un clic sur un bouton. js-file-downloader : permet de télécharger un fichier sur l’appareil de l’utilisateur.

sources :

Comme dans notre séance sur le développement, vous pouvez tester des petits bouts de code indépendants et les associer à votre stratégie (avec éventuellement des exemples de données, voire même des temps d'exécution).

Nous avons pu essayer via notre environnement local nos bibliothèques pour débuter l’implémentation : -Avec la bibliothèque react-copy-to-clipboard, nous avons commencé par ajouter un bouton sous l’image de l’item :

<CopyToClipboard text={attributesInstagram}>
  <button>Copy to clipboard</button>
</CopyToClipboard>

image La position du bouton peut être amenée à changer.

Lorsque l’on clique sur le bouton, on copie la valeur de la variable attributesInstagram: sa valeur dépend si l’auteur et/ou la localisation de l’item existe ou non. Si un item a donc seulement pour attribut un auteur, seul cet attribut sera copié et il en va de même pour la localisation. Si l’auteur et la localisation existent, on copie les deux attributs en ajoutant des espaces et/ou des virgules pour harmoniser l’ensemble. Enfin, si aucun des deux attributs n’existent, on copie une phrase ‘Auteur et localisation inconnus’.

let attributesInstagram;
    if (typeof this.state.item.creator == 'undefined') {
      if (typeof this.state.item.spatial == 'undefined') {
        attributesInstagram = 'Auteur et localisation inconnus';
      } else {
        attributesInstagram = this.state.item.spatial;
      }
    } else if (typeof this.state.item.spatial == 'undefined') {
      attributesInstagram = this.state.item.creator;
    } else {
      attributesInstagram = this.state.item.creator + ', ' + this.state.item.spatial;
    }

Les attributs sélectionnés peuvent être amenés à changer.

Nous avons ensuite utilisé la bibliothèque js-file-downloader pour télécharger l’image de l’item. On crée une variable qui contient l’url de l’image, un booléen qui permet de désactiver le lancement automatique du téléchargement et enfin, le nom du fichier. Rajouter le ‘.jpg’ est important puisqu’il permet de télécharger l'image de l'item en tant qu’image JPEG, ne pas le mettre entraîne le téléchargement de l'image de l'item en tant que type fichier :

const download = new JsFileDownloader({
      url: this.state.item.resource,
      autoStart: false,
      filename: '' + this.state.item.name+ '.jpg'
});

Il ne reste qu’à modifier le code du copiage créé précédemment pour qu’il lance le téléchargement lorsque les attributs sont copiés, c’est à dire au clic du bouton :

 <CopyToClipboard text={attributesInstagram} onCopy={() => download.start()
  .then(function() { // success
  })
  .catch(function(error) { // handle errors
  })
}>
  <button>Copy to clipboard</button>
</CopyToClipboard>

Ainsi, lorsque l’on clique sur le bouton sous l’item AXN 009 : image Le téléchargement de l’image de l’item se lance et : image Les attributs creator et spatial sont bien copiés dans le presse papier.

Cela fonctionne sur ordinateur avec Firefox mais le plus important est de voir si cela marche sur mobile avec différents navigateurs.

Doit-on intégrer des services extérieurs (ex : cartographie) ? De quelles fonctionnalités en particulier aura-t-on besoin ? Est-ce que le service choisi les propose ou doit-on passer chez un concurrent ? Comment s'utilisent ces fonctionnalités ? avec quels paramètres ?

Nous n’avons pas besoin d’intégrer des services extérieurs, l’objectif étant simplement de télécharger l’image d’un item pour ensuite pouvoir le mettre en ligne via Instagram.

Des étapes préalables de développement, testables, sont-elles envisageables afin de diminuer la complexité de la livraison ? Refactoring (livrable à part entière, iso fonctionnel) ? Code développable et testable de manière externe au logiciel ? Étape du scénario (non livrable en tant que tel mais dont l'effet peut être testé) ?

Nous ne pouvons pas tellement diminuer la complexité de la livraison, il n’y aura donc pas d’étapes préalables de développement.

benel commented 3 years ago

Merci @manacheh @aamina12 pour cette nouvelle version de la stratégie d'implémentation. Je vois que vous avez déjà bien avancé l'implémentation proprement dite...

Cette implémentation sera efficace uniquement sur mobile, car on ne peut pas partager de médias sur Instagram via ordinateur.

"Efficace" ?

Nous avons pu essayer via notre environnement local nos bibliothèques pour débuter l’implémentation :

Dans ma pratique, c'est plutôt dans un bout de code indépendant du projet (pour éviter la complexité de l'intégration). Mais bon, ceci dit, si ça vous va comme ça, c'est l'essentiel...

Étape du scénario (non livrable en tant que tel mais dont l'effet peut être testé) ?

Nous ne pouvons pas tellement diminuer la complexité de la livraison, il n’y aura donc pas d’étapes préalables de développement.

C'est quand même un peu ce que vous avez fait plus haut... Des étapes préalables non livrables en tant que tel mais dont on peut tester l'effet.

les points de vue de l’item : nous savons qu’ils se trouvent dans la variable this.state.item.topic mais les résultats apparaissent sous cette forme : (...) Nous n’arrivons donc pas encore à extraire les points de vue d’un item.

Effectivement, vous n'avez que les identifiants (des catégories assignées à l'item) ... Le dictionnaire permettant d'avoir le nom et les relations entre catégories n'est pas disponible dans ce composant mais dans certains de ses sous-composants : les points de vue :

Capture d’écran 2021-06-03 à 21 45 51
Quentin-UTT commented 3 years ago

@benel Voici la dernière version des scénarios :

#language: fr

Fonctionnalité: Partager un item sur Instagram

Scénario: Préparer le partage d'un item sur Instagram

  Soit "SR 005" un item ouvert
  Quand l'utilisateur prépare le partage de l'item "SR 005" sur Instagram
  Alors l'image de l'item "SR 005" est téléchargée sur le terminal de l'utilisateur
  Et le presse-papier contient "#Isaac"
  Et le presse-papier contient "#SacrificeDAbraham"
  Et le presse-papier contient "#AbramAbraham"
  Et le presse-papier contient "#JPFlorence"
  Et le presse-papier contient "#Datation1894"
  Et le presse-papier contient "© Aurélien Benel, 2015-10-24, Église Saint-Remi, Troyes"
benel commented 3 years ago

@Quentin-UTT Super !

Dans le même esprit, bous pourriez couper la dernière étape en deux (en séparant ce qui à trait au copyright et ce qui a trait à la localisation) : ça donnera plus de latitude à ceux qui vont faire l'implémentation.

Quentin-UTT commented 3 years ago

@benel Parfait, voici la version finale, prête pour le pull request

#language: fr

Fonctionnalité: Partager un item sur Instagram

Scénario: Préparer le partage d'un item sur Instagram

  Soit "SR 005" un item ouvert
  Quand l'utilisateur prépare le partage de l'item "SR 005" sur Instagram
  Alors l'image de l'item "SR 005" est téléchargée sur le terminal de l'utilisateur
  Et le presse-papier contient "#Isaac"
  Et le presse-papier contient "#SacrificeDAbraham"
  Et le presse-papier contient "#AbramAbraham"
  Et le presse-papier contient "#JPFlorence"
  Et le presse-papier contient "#Datation1894"
  Et le presse-papier contient "© Aurélien Benel, 2015-10-24"
  Et le presse-papier contient "Église Saint-Remi, Troyes"
benel commented 3 years ago

@Quentin-UTT Super ! J'attends votre pull request !

manacheh commented 3 years ago

@benel

avec @aamina12 et @LSauter68140 , nous avons remonté la liste des topics dans l'état du composant Item.

-Nous arrivons à extraire l'id d'un topic (par exemple addd464d06159c4eb0b9666cffb2042c qui correspond au topic XIXe s.

-Si nous mettons this.state.topics['addd464d06159c4eb0b9666cffb2042c'].name[0], nous arrivons bien à copier le nom du topic.

-Mais si nous mettons par exemple this.state.topics[idDuTopic].name[0] (idDuTopic contenant addd464d06159c4eb0b9666cffb2042c), nous n'arrivons plus à récupérer le nom du topic.

Auriez-vous une idée pour nous débloquer ?

benel commented 3 years ago

@manacheh @aamina12 @LSauter68140

-Si nous mettons this.state.topics['addd464d06159c4eb0b9666cffb2042c'].name[0], nous arrivons bien à copier le nom du topic. -Mais si nous mettons par exemple this.state.topics[idDuTopic].name[0] (idDuTopic contenant addd464d06159c4eb0b9666cffb2042c), nous n'arrivons plus à récupérer le nom du topic.

C'est effectivement étrange... Ça devrait fonctionner :

Capture d’écran 2021-06-16 à 18 49 44

La seule hypothèse à laquelle je pense serait que idDuTopic n'ait pas exactement le type que vous imaginez...

LSauter68140 commented 3 years ago

@benel

J'ai pu aider @aamina12 et @manacheh pour réussir à récupérer les noms des topics pour pouvoir les copier.

On obtient Aurélien Bénel, Église Saint-Remi, Troyes, Isaac, Sacrifice d'Abraham, Abram/Abraham, 1894 le vitrail SR 005 ; image

Pour cela on a du ajouter cette fonction https://github.com/manacheh/Porphyry/blob/3833ddc766fa454e6c696dcf4c41f5ff280a9429/src/components/itemPage/Viewpoint.jsx#L211

qui permet de fetch les données à partir du serveur depuis un id (avant la fonction était juste disponible pour le composant viewpoint, maintenant on peut l'utiliser n'importe ou. Ensuite j'ai ajouté cette fonction https://github.com/manacheh/Porphyry/blob/3833ddc766fa454e6c696dcf4c41f5ff280a9429/src/components/itemPage/Item.jsx#L361 qui permet de concaténer tout ce qu'on veut copier.

https://github.com/manacheh/Porphyry/blob/3833ddc766fa454e6c696dcf4c41f5ff280a9429/src/components/itemPage/Item.jsx#L373-L381 cela permet de lier les id de this.state.topic au contenu de this.state.topics que l'ont veut Ensuite on a juste à récupérer les noms et c'est bon !

YaellePihan commented 3 years ago

@benel avec @Fulin-ZHANG nous avons rédigé le test automatique associé au scénario Partager un item sur instagramm qui donne : contexte.rb : Soit("{String} l'item affiché") do |item| visit getURI(item) end event.rb : Quand("Utilisateur prépare le partage de l'item {string} sur Instagram") do |item| click_on 'Copy to clipboard' end outcome.rb : Alors("l'image de l'item {string} est téléchargées sur le terminal de l'utilisateur") page.response_headers["Content-Disposition"].should == "attachment" page.response_headers['Content-Disposition'].partition('=').last end

En revanche pour l'instant notre environnement de test bug ce qui nous empêche de pour vérifier leur succès... Je n'ai aucun scénario qui apparait : image

image

benel commented 3 years ago

@YaellePihan @Fulin-ZHANG

image

Vous lancez cucumber à partir de votre dossier personnel (c'est ce que signifie le ~ avant le $). Ça ne fonctionnera que si vous la lancez à partir du dossier du projet Porphyry.

En effet elle a besoin d'accéder au dossier features.

YaellePihan commented 3 years ago

Oui je m'en suis rendue compte mais après j'ai ça : image

YaellePihan commented 3 years ago

Par ailleurs, je ne comprends pas pourquoi mon localhost 3000 renvoie vers un ancien porphyry alors que j'ai clone la dernière version et que lorsque je vais dans ma copie locale de porphyry je vois les toutes dernières fonctionnalités qui ont été ajoutées. Il faudrait que ce soit cette dernière version de porphyry qui soit lancée pour voir si mes tests sont adaptés.

Afin de clarifier ces problèmes et les problèmes qu'il risque d'y avoir après seriez vous d'accord pour une visio aujourd'hui (lundi 21/06) sinon je peux venir en présentiel si vous préférez?

@benel

YaellePihan commented 3 years ago

@benel la recette de test se lance enfin avec l'aide de @LSauter68140

benel commented 3 years ago

@YaellePihan Finalement, laquelle des deux pistes que je vous avais données était la bonne ? DockerDesktop ou Git ?

YaellePihan commented 3 years ago

le problème c'est que aucun des deux... J'ai montré à loic ce que je faisais tout le temps et ça s'est mis à marcher, je ne sais pas trop ce qui a changé....

manacheh commented 3 years ago

@benel

Avec @aamina12 et @LSauter68140 , nous pensons avoir terminé l'implémentation de ticket : image

Un bouton ''Partager sur Instagram'' est sous l'image du vitrail. Lorsque l'on clique sur ce bouton : image Une demande de téléchargement de l'image est lancée et un pop-up indiquant la démarche à suivre pour partager sur Instagram s'affiche. En simultané, les attributs et les points de vue du vitrail sont copiés pour pouvoir être utilisé sur Instagram : image

Y a-t-il des modifications à faire ou pouvons-nous effectuer un pull request ?

benel commented 3 years ago

Merci @manacheh @aamina12 @LSauter68140 ! Ça a l'air pas mal...

Trois petits points d'attention peut-être :

manacheh commented 3 years ago

@benel

* On avait mentionné le fait d'utiliser le symbole copyright devant l'auteur (voir scénarios),

C'est rajouté !

* Le bouton est vraiment très visible, vous êtes sûr que ça ne choque par rapport au reste ? Ça reste quand même fonctionnalité utilisée uniquement par un petit pourcentage des usagers...

En effet, nous allons réduire sa taille.

  • Je n'ai pas compris si votre bouton était dessus ou dessous le plugin Disqus. Qu'est-ce que ça donne visuellement quand il y a les deux ? Le bouton peut se situer soit au dessus de Disqus : image

Soit en dessous de Disqus (il sera en dessous des commentaires) : image

benel commented 3 years ago

@manacheh

Le bouton peut se situer soit au dessus de Disqus Soit en dessous de Disqus (il sera en dessous des commentaires) :

Certes, mais vous l'avez mis où ? ;) Ça rend mieux au-dessus de Disqus, non ?

manacheh commented 3 years ago

@manacheh

Le bouton peut se situer soit au dessus de Disqus Soit en dessous de Disqus (il sera en dessous des commentaires) :

Certes, mais vous l'avez mis où ? ;) Ça rend mieux au-dessus de Disqus, non ?

oui oui il était au dessus, entre l'image et Disqus.

manacheh commented 3 years ago

@benel

Nous avons modifié l'apparence et la taille du bouton : image

Qu'en pensez-vous ?

manacheh commented 3 years ago

@benel

Nous avons modifié l'apparence et la taille du bouton : image

Qu'en pensez-vous ?

@benel je sais que vous devez être innondé de notifications mais je vous retag pour être sûr que vous voyez notre implémentation.

benel commented 3 years ago

@manacheh

Oui, oui, je vois bien la copie d'écran...

N'attendez pas pour ouvrir une pull request :

manacheh commented 3 years ago

@manacheh

Oui, oui, je vois bien la copie d'écran...

N'attendez pas pour ouvrir une pull request :

* si c'est intégrable directement, ça me permettra de le faire,

* s'il y a des petites améliorations à apporter, je pourrai vous les suggérer grâce à l'interface prévue pour.

Entendu, merci !

manacheh commented 3 years ago

Voici le lien de la vidéo présentant l'implémentation de cette fonctionnalité : https://drive.google.com/file/d/1eq-eChK5IGICTltfZFZSnwp6v1qdQvcs/view?usp=sharing