<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Martin Niombela</title>
    <description>The latest articles on DEV Community by Martin Niombela (@dawhistler).</description>
    <link>https://dev.to/dawhistler</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1408059%2F32072db8-f891-4507-91bd-f75615a5fd42.png</url>
      <title>DEV Community: Martin Niombela</title>
      <link>https://dev.to/dawhistler</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dawhistler"/>
    <language>en</language>
    <item>
      <title>Pourquoi j'ai définitivement coupé les ponts avec Windows</title>
      <dc:creator>Martin Niombela</dc:creator>
      <pubDate>Mon, 13 Apr 2026 16:55:02 +0000</pubDate>
      <link>https://dev.to/dawhistler/pourquoi-jai-definitivement-coupe-les-ponts-avec-windows-4140</link>
      <guid>https://dev.to/dawhistler/pourquoi-jai-definitivement-coupe-les-ponts-avec-windows-4140</guid>
      <description>&lt;p&gt;Pendant des décennies, Windows (et plus largement Microsoft) a régné en maître sur le monde des ordinateurs. On le remarque dans la pop culture actuelle, car des petits éléments très reconnaissables sont encore aujourd’hui présents dans l'imaginaire commun. Qui n'a jamais entendu le son de démarrage ou celui de la pop-up d'erreur de Windows XP ? Ces éléments sont tellement iconiques qu’ils sont des "&lt;a href="https://knowyourmeme.com/memes/windows-xp-system-sound-remixes" rel="noopener noreferrer"&gt;mèmes&lt;/a&gt;".&lt;/p&gt;

&lt;p&gt;Cependant, le vent a tourné. Entre l'obsolescence programmée, l'invasion de l'IA, et une expérience utilisateur de plus en plus dégradée, une question se pose : &lt;strong&gt;pourquoi continuer d’accepter les contraintes de Microsoft ?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Personnellement, j'ai mis toutes mes machines sur des systèmes GNU/Linux, et je vais vous expliquer pourquoi.&lt;/p&gt;

&lt;h2&gt;
  
  
  Obsolescence programmée
&lt;/h2&gt;

&lt;p&gt;Annoncé comme le "dernier système majeur" que Microsoft proposerait, la loi de l'obsolescence programmée a fini par rattraper Windows 10. Date du décès ? 14 octobre 2025, 10:10.&lt;/p&gt;

&lt;p&gt;Mais cette mort depuis longtemps annoncée ne concerne pas seulement une version de Windows. Elle concerne aussi &lt;strong&gt;plusieurs centaines de millions de machines en état de marche&lt;/strong&gt;, les miennes incluses. Malheureusement pour leurs propriétaires, ces machines, pourtant viables, ne remplissent pas les critères demandés par Windows 11, le nouveau système d'exploitation que Microsoft pousse désormais chez tout le monde.&lt;/p&gt;

&lt;p&gt;À ce stade, une décision s'impose et plusieurs options sont envisageables :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rester sur un système obsolète&lt;/li&gt;
&lt;li&gt;Prendre l'extension de mise à jour de sécurité &lt;strong&gt;payante&lt;/strong&gt; (service limité dans le temps)&lt;/li&gt;
&lt;li&gt;Acheter une nouvelle machine&lt;/li&gt;
&lt;li&gt;Installer une distribution GNU/Linux&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Personnellement, mon choix s'est vite porté sur &lt;strong&gt;un abandon de Windows&lt;/strong&gt; (🤓). Mais beaucoup ont fait le choix de continuer avec Windows, soit en forçant le passage, soit en payant chèrement le droit d'embarquer, nouvelle machine sous le bras, ou encore en choisissant l'extension de mise à jour, là aussi &lt;strong&gt;payante&lt;/strong&gt; (j'insiste dessus, parce que je trouve ça grave). Et si ce premier billet d'entrée joue déjà en défaveur de Windows 11, les éléments qui vont suivre sont tout autant à charge.&lt;/p&gt;

&lt;h2&gt;
  
  
  Surveillance
&lt;/h2&gt;

&lt;p&gt;Un autre élément qui me dérange de plus en plus, et pas seulement dans Windows, c'est la &lt;strong&gt;télémétrie&lt;/strong&gt;. De nos jours, tout est prétexte à récupérer les données de l'utilisateur, et Windows n'y échappe pas. Sans aller fureter dans les paramètres pour y désactiver tout ce qu'on vous laissera désactiver (🙃), il est certains que beaucoup d'informations vous concernant, comme les logiciels installés par exemple, remonteront chez Microsoft. Et cela est d'autant plus vrai avec l'impossibilité croissante d'utiliser Windows avec un compte local.&lt;/p&gt;

&lt;p&gt;Cependant, la "surveillance" que l'on peut constater dans Windows provient surtout d’un élément étonnamment présent dans le système : la &lt;strong&gt;publicité&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Microsoft attribue un ID publicitaire unique à chaque utilisateur, de manière "opt-out". Et si cela signifie que l'on peut désactiver ce paramètre, le fait qu'il soit activé par défaut &lt;strong&gt;me dérange profondément&lt;/strong&gt;. Cet ID permet à Windows de "mieux calibrer" les pubs à ceux qui les reçoivent. Mais cela demande forcément une récupération d'informations en tout genre (activités personnelles, goûts, …) sur une machine qui est censée vous appartenir.&lt;/p&gt;

&lt;p&gt;Ces nouveaux éléments viennent s'ajouter au dossier à charge contre Windows. Néanmoins, malgré leur nature désagréable, il faut souligner la possibilité de désactiver une partie de ces désagréments. Chose plus difficile pour le dernier élément à charge.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Intelligence artificielle"
&lt;/h2&gt;

&lt;p&gt;Il serait difficile de parler des problèmes actuels de Windows sans parler de l'IA. À dire vrai, la manière dont Microsoft avance avec l'IA représente le cœur du problème. C'est pour introduire l'IA dans le système et dans le quotidien des gens que Microsoft a pressé le bouton "obsolescence". L'IA est également un vecteur de surveillance supplémentaire, autant au travers de ce qu'elle est censée accomplir, qu'au travers de certaines de ses fonctionnalités, notamment "&lt;a href="https://www.lemondeinformatique.fr/actualites/lire-la-fonction-controversee-recall-de-microsoft-relancee-96716.html" rel="noopener noreferrer"&gt;Windows Recall&lt;/a&gt;".&lt;/p&gt;

&lt;p&gt;En plus d'accentuer les problèmes déjà existants, l'adoption forcée de l'IA en crée de nouveaux : &lt;strong&gt;instabilité&lt;/strong&gt; des mises à jour et &lt;strong&gt;dégradation de l'expérience utilisateur&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ce qui est vraiment dérangeant, c'est qu'il est difficile de désactiver toute forme d'IA. Parfois, ce sont des applications entières qui pâtissent de ce choix de design, comme l'application Bloc-Note, qui a subi un relooking IA. Mais "difficile" ne voulant pas dire "impossible", plein de résistants ont développé des scripts pour supprimer le trop plein d'IA et autre bloatware de leur système Windows. Et même si je salue l'effort et le temps sacrifié, &lt;strong&gt;je ne juge pas Windows suffisamment précieux pour lui dédier du temps afin de le sauver de lui-même&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;J'ai conscience que mon profil me permet plus facilement de passer d'un système grand public comme Windows à l'univers des possibles qu'offre une distribution GNU/Linux. J'ai étudié avec ces distributions, j'ai travaillé avec ces distributions, donc l'environnement m'est quelque peu familier.&lt;/p&gt;

&lt;p&gt;Néanmoins, il faut observer une tendance : &lt;strong&gt;de moins en moins d’utilisateurs apprécient ce que fait Microsoft avec Windows&lt;/strong&gt;. Le désormais nommé "&lt;a href="https://www.frandroid.com/marques/microsoft/2997427_microsoft-tente-de-bannir-lutilisation-du-terme-microslop-mais-parvient-a-faire-exactement-linverse" rel="noopener noreferrer"&gt;Microslop&lt;/a&gt;" a bien mérité son nom, et tente désormais de rétropédaler sur son leitmotiv de ces dernières années. Rétropédaler est sensé quand on jauge le mécontentement ambiant, mais ça ne concernera que l'IA (&lt;a href="https://www.clubic.com/actualite-608434-windows-11-microsoft-entame-le-menage-annonce-autour-de-copilot-mais-pas-comme-vous-l-imaginiez.html" rel="noopener noreferrer"&gt;et encore&lt;/a&gt;). Et je ne vais pas attendre que le résultat soit juste "acceptable" quand &lt;strong&gt;une meilleure solution existe, et qu’elle a un petit pingouin en mascotte&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>developerlife</category>
      <category>microsoft</category>
    </item>
    <item>
      <title>Better integrate your AppImage with .desktop file</title>
      <dc:creator>Martin Niombela</dc:creator>
      <pubDate>Wed, 19 Nov 2025 20:04:58 +0000</pubDate>
      <link>https://dev.to/dawhistler/better-integrate-your-appimage-with-desktop-file-41o0</link>
      <guid>https://dev.to/dawhistler/better-integrate-your-appimage-with-desktop-file-41o0</guid>
      <description>&lt;p&gt;All Linux distribution users are familiar with "AppImages": they are portable and do not require any prior installation. This is very convenient, but as it stands, the application does not appear in any of the computer's menus and is not necessarily detected by launchers.&lt;/p&gt;

&lt;p&gt;This is where &lt;code&gt;.desktop&lt;/code&gt; files come in. A &lt;code&gt;.desktop&lt;/code&gt; file is simply a text file that tells the computer that an application exists and creates a new entry in the menu.&lt;/p&gt;

&lt;h2&gt;
  
  
  The basic
&lt;/h2&gt;

&lt;p&gt;A basic &lt;code&gt;.desktop&lt;/code&gt; file contains several informations about the application it describes :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;[Desktop Entry]&lt;/code&gt;: Mandatory header, that indicates a menu entry&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Type&lt;/code&gt;: "Application", "Link", or "Directory" (but here we want "Application")&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Name&lt;/code&gt;: The name that will appear in the menu&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Comment&lt;/code&gt;: The tooltip that shows when hovering over the icon.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Icon&lt;/code&gt;: The path to the icon of the app&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Exec&lt;/code&gt;: The command to run to launch the app&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Terminal&lt;/code&gt;: To know whether it should run from a terminal or not&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Categories&lt;/code&gt;: To categorize the app (e.g., "Development", "Game", "Network")&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This would look like this :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Desktop Entry]
Type=Application
Name=MySuperApp
Comment=Super is my app
Icon=/home/YOUR_USER/Applications/my-super-app.png
Exec=/home/YOUR_USER/Applications/MySuperApp.AppImage
Terminal=false
Categories=Utility;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;⚠️ &lt;code&gt;Exec&lt;/code&gt; and &lt;code&gt;Icon&lt;/code&gt; don't understand relative paths. You need to use &lt;strong&gt;absolute paths&lt;/strong&gt; for those fields.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Make it executable
&lt;/h2&gt;

&lt;p&gt;To have a functional menu entry, the AppImage needs to be &lt;strong&gt;executable&lt;/strong&gt;, meaning it has the permission to be executed. To do so, the following command can be used :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /home/YOUR_USER/Applications/MySuperApp.AppImage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Put it in the relevant folder
&lt;/h2&gt;

&lt;p&gt;For your desktop to know where to find your menu entry, you can your freshly created file in &lt;code&gt;~/.local/share/applications/&lt;/code&gt;. The menu entry will be available for the user possessing the &lt;code&gt;.desktop&lt;/code&gt; file.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;It can also be placed in &lt;code&gt;/usr/share/applications/&lt;/code&gt;, if all the user of the desktop should have the menu entry.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  That's it
&lt;/h2&gt;

&lt;p&gt;You should now see your app with its icon. You can now search for it, pin it to your dock, or launch it just like any other installed application.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>tutorial</category>
      <category>appimage</category>
      <category>desktop</category>
    </item>
    <item>
      <title>Hexo vs Hugo: My Take on Two Static Site Generators</title>
      <dc:creator>Martin Niombela</dc:creator>
      <pubDate>Wed, 24 Jul 2024 01:39:43 +0000</pubDate>
      <link>https://dev.to/dawhistler/hexo-et-hugo-deux-generateurs-statiques-bien-pratiques-57e</link>
      <guid>https://dev.to/dawhistler/hexo-et-hugo-deux-generateurs-statiques-bien-pratiques-57e</guid>
      <description>&lt;p&gt;When it comes to building a website, you’ve got a bunch of options: start from scratch, use a CMS like WordPress, or go for a static site generator. In this post, I’ll skip the theoretical comparisons and dive into my hands-on experience with two popular generators: &lt;strong&gt;Hexo&lt;/strong&gt; and &lt;strong&gt;Hugo&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Both are great tools for getting a site online quickly without spending hours setting up infrastructure or fiddling with a backend.&lt;/p&gt;

&lt;p&gt;(There's a TL;DR at the end, if you're in a rush)&lt;/p&gt;

&lt;h2&gt;
  
  
  Wait, what’s a static site ?
&lt;/h2&gt;

&lt;p&gt;A static site is just plain HTML, CSS (and maybe some JavaScript) served directly to users. There’s no server-side processing — everyone gets the same page, fast.&lt;/p&gt;

&lt;p&gt;The downside ? Writing each page by hand gets tedious fast. That’s where static site generators come in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s a static site generator ?
&lt;/h2&gt;

&lt;p&gt;In short: you write your content (usually in Markdown), pick or customize a theme, and the generator builds the final HTML/CSS/JS files for you. It handles layout, links, menus, and deployment. Boom — your site’s ready.&lt;/p&gt;

&lt;p&gt;It’s a great time-saver if you want a clean, fast site without dealing with dynamic content or databases.&lt;/p&gt;




&lt;h2&gt;
  
  
  Hexo
&lt;/h2&gt;

&lt;p&gt;Hexo is a Node.js-based static site generator. It’s especially popular for blogs and personal sites. Markdown support is solid, and deployment to places like GitHub Pages or S3 is easy.&lt;/p&gt;

&lt;p&gt;It has a good range of themes, many of which are community-built (check out the “themes” section on Hexo’s site). You can also extend functionality using plugins or custom JavaScript.&lt;/p&gt;

&lt;p&gt;One thing to note: a lot of the Hexo ecosystem comes from the Asian dev community. Some themes are optimized for ideograms, and documentation can be sparse in English.&lt;/p&gt;




&lt;h2&gt;
  
  
  Hugo
&lt;/h2&gt;

&lt;p&gt;Hugo is built with Go and known for being blazing fast and flexible. It works similarly to Hexo — Markdown content + templates + config = a working site.&lt;/p&gt;

&lt;p&gt;Its theme library isn’t quite as big, but it’s still solid. Even if you don’t write Go, you can easily tweak an existing theme. The documentation is excellent, which helps a lot when customizing things.&lt;/p&gt;




&lt;h2&gt;
  
  
  So… Hexo or Hugo?
&lt;/h2&gt;

&lt;p&gt;Honestly, it depends.&lt;/p&gt;

&lt;p&gt;If you're comfy with Node.js, Hexo is a great pick. If you’ve played with Go — or just want something ultra-fast and simple — go with Hugo.&lt;/p&gt;

&lt;p&gt;Also, sometimes the deciding factor is just a theme you fall in love with. Don't let blog rankings tell you one is “better” than the other. Use what works best for your project.&lt;/p&gt;




&lt;h2&gt;
  
  
  My experience
&lt;/h2&gt;

&lt;p&gt;At first, I wanted to build everything myself. But when I hit the blog section, I realized I’d waste a ton of time. That’s when I discovered static site generators.&lt;/p&gt;

&lt;p&gt;I used Hugo for a small project, and despite not knowing Go, I was able to customize a theme with the help of the docs. I also tried Hexo for a personal blog — easy to set up, but I did run into a few language/documentation hiccups with some themes.&lt;/p&gt;




&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Hexo and Hugo are both great options for launching a website quickly, especially if you’re on a budget or just want to keep things simple.&lt;/p&gt;

&lt;p&gt;Whether it’s a blog, portfolio, or side project, these tools help you focus on content instead of setup.&lt;/p&gt;

&lt;p&gt;Give them a try — and don’t be afraid to explore others like &lt;strong&gt;Jekyll&lt;/strong&gt; or &lt;strong&gt;Gatsby&lt;/strong&gt; too!&lt;/p&gt;

&lt;p&gt;Until next time 👋&lt;/p&gt;

</description>
      <category>web</category>
      <category>webdev</category>
    </item>
    <item>
      <title>OpenAI and React Native: JARVIS project v.1</title>
      <dc:creator>Martin Niombela</dc:creator>
      <pubDate>Sun, 07 Apr 2024 21:29:58 +0000</pubDate>
      <link>https://dev.to/dawhistler/openai-et-react-native-projet-jarvis-v0-21oa</link>
      <guid>https://dev.to/dawhistler/openai-et-react-native-projet-jarvis-v0-21oa</guid>
      <description>&lt;p&gt;Yo devs!&lt;/p&gt;

&lt;p&gt;I've been writing articles on my own for a while now, and I thought it might be interesting to post them here too. To do that, I'm starting by reposting an article I wrote &lt;strong&gt;a year ago&lt;/strong&gt; on my own blog (in 2023), so feel free to react in the comments, so I'll know if I should do any more!&lt;/p&gt;




&lt;p&gt;As I write this article, the world is on fire with AI. ChatGPT, Microsoft Bing, even Bard, all these AIs are the talk of the town, for good or bad (with a special mention for the rocky beginnings of the AI version of Microsoft Bing). And while the &lt;em&gt;devfluencers&lt;/em&gt; (yes, they do exist) are talking about the arrival of OpenAI's GPT-4 model, I myself wanted to try out what could be done with one of the models offered by OpenAI.&lt;/p&gt;

&lt;p&gt;Between image generators (Midjourney, Stable Diffusion), music generators (Mubert), and less... "serious" AIs (a nod to ChatCGT, a very French initiative), there are projects to suit every need. But to access these AIs, you have to open your web browser and share the AI's resources with the thousands of other requests sent at the same time as yours. So I thought I'd make my own chatbot! And who knows, maybe one day I'll turn it into a sort of Jarvis, like Tony Stark's?&lt;/p&gt;

&lt;p&gt;For my personal client, the choice of a mobile application seemed obvious. After all, it's the future &lt;em&gt;Jarvis&lt;/em&gt;, isn't it?&lt;br&gt;
So I chose to work with React Native, as I was already keen to find out more about this framework. And, to keep with the AI theme, I chose ChatGPT to help me get started on this project. Although ChatGPT won't be doing all the code for the application, it might be interesting to have him as an assistant on this project, for which I haven't (yet) mastered all the subtleties of the technology used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;SPOILER ALERT 🔊&lt;/em&gt;&lt;/strong&gt; &lt;em&gt;: This article could potentially be a little long. What's more, the application could only be tested on an Android device.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up the project
&lt;/h2&gt;

&lt;p&gt;After a quick request to ChatGPT about how I should go about making a chatbot app using React Native, I got an eight-step plan, complete with command lines and sample code. We start with the setup steps.&lt;/p&gt;
&lt;h3&gt;
  
  
  Environment
&lt;/h3&gt;

&lt;p&gt;Two elements are essential for this project :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;Expo Go (A mobile app for testing a React Native project developed with &lt;a href="https://expo.dev/" rel="noopener noreferrer"&gt;Expo&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the installations are complete, you can create your project and see React Native's "Hello World" by running the following commands :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-expo-app myChatBot &amp;amp;&amp;amp; cd myChatBot
npx expo start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Settings
&lt;/h3&gt;

&lt;p&gt;Now that the project is up and running, there are two more elements to be recovered :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An OpenAI API key (to be able to communicate with a GPT-3 instance)&lt;/li&gt;
&lt;li&gt;An icon for the application&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The API key is required for each request made to the AI. You can obtain this key by creating an &lt;a href="https://platform.openai.com/" rel="noopener noreferrer"&gt;OpenAI&lt;/a&gt; account, and then managing the API keys for that account. The icon, meanwhile, will be used to display the application on the phone, as well as for a possible &lt;em&gt;splash screen&lt;/em&gt;. If you're not so good at graphics, you can use a library of royalty-free images and &lt;a href="https://www.figma.com/community/file/1155362909441341285" rel="noopener noreferrer"&gt;the Figma template provided in the Expo documentation&lt;/a&gt;. For my part, I used the &lt;a href="https://www.reshot.com/" rel="noopener noreferrer"&gt;Reshot&lt;/a&gt; site to find my brain icon, which I reworked slightly using Inkscape.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnb-dev.fr%2Fimages%2Frn-chatbot%2Ficon.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnb-dev.fr%2Fimages%2Frn-chatbot%2Ficon.webp" alt="cerveau.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The images that will be used for the application's icon and &lt;em&gt;splash screen&lt;/em&gt; must be added to the application's &lt;code&gt;assets&lt;/code&gt; folder. You can then modify certain parameters of the application, such as the background colour of the &lt;em&gt;splash screen&lt;/em&gt;, or that of the icon (in the case of an Android device).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"expo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"splash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"image"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./assets/splash.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"backgroundColor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#333"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"android"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"adaptiveIcon"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"foregroundImage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"./assets/adaptive-icon.png"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"backgroundColor"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"#333"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Quick planning
&lt;/h3&gt;

&lt;p&gt;At this stage, everything is running smoothly: the application has an icon, a &lt;em&gt;splash screen&lt;/em&gt; and a simple "Hello World" screen. While ChatGPT has already provided me with sample code for my application's interface, I've chosen to add a few elements, resulting in the following list of elements :&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A little style&lt;/li&gt;
&lt;li&gt;A header (with the application icon inside)&lt;/li&gt;
&lt;li&gt;A list box for messages&lt;/li&gt;
&lt;li&gt;An input area with a send button&lt;/li&gt;
&lt;li&gt;A modal window for application information (version, name of developer, etc.)&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;spinner&lt;/em&gt; (while the AI thinks about its response)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;With my list and ChatGPT's indications, I already know where to start: setting up the first item on my list: &lt;strong&gt;the style&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So now it's time to tackle the &lt;code&gt;App.js&lt;/code&gt; file!&lt;/p&gt;

&lt;h3&gt;
  
  
  A little style
&lt;/h3&gt;

&lt;p&gt;In terms of style, I've chosen a 'Matrix' colour theme (green and black, in short). The header and the part containing the input area will be dark black, while the part displaying the messages will have a background colour closer to grey.&lt;/p&gt;

&lt;p&gt;To distinguish between messages from the AI and those from the user, I've decided to give them different colours, as well as a different font. The application's loading spinner will also adopt the colours of the "Matrix" theme. To make it clearly visible, I've chosen to make it a relatively light green, which contrasts well with the black of the header and input area.&lt;/p&gt;

&lt;p&gt;(The code corresponding to the style can be found in my &lt;code&gt;App.js&lt;/code&gt; file, it might be a bit long to put it all here)&lt;/p&gt;

&lt;h3&gt;
  
  
  Interface
&lt;/h3&gt;

&lt;p&gt;Although I had planned the style I wanted to apply to my interface from the outset, it was by actually working on the interface that I was able to "fine-tune" the styling details (border colours, spacing, etc.).&lt;/p&gt;

&lt;p&gt;So, following my list and deviating from the model suggested by ChatGPT, I started by adding my header, which also includes the application's logo.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;topBar&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;itemTopBar&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;My ChatBot v.1.0&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;imageTopBarContainer&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt; &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./assets/icon.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;imageTopBar&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

  ...
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I then added the area for listing sent and received messages (using the &lt;code&gt;FlatList&lt;/code&gt; element), as well as the last part of my interface: &lt;strong&gt;input area&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;FlatList&lt;/span&gt;
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;renderItem&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;renderItem&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;keyExtractor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
  &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;refFlatList&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;inputContainer&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TextInput&lt;/span&gt;
    &lt;span class="na"&gt;multiline&lt;/span&gt;
    &lt;span class="na"&gt;cursorColor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"#00FF41"&lt;/span&gt;
    &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;placeholder&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Votre message..."&lt;/span&gt;
    &lt;span class="na"&gt;placeholderTextColor&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"#777"&lt;/span&gt;
    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;inputValue&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;onChangeText&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;setInputValue&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;TouchableOpacity&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;onPress&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;handleSend&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt; &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./assets/send.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;TouchableOpacity&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interface is extremely simplistic, so all the elements needed to make the application work are already there. All that's missing is message management with the bot !&lt;/p&gt;

&lt;h3&gt;
  
  
  Messages
&lt;/h3&gt;

&lt;p&gt;To "manage" messages, you first need to start by adding what you're sending to the list of messages, which is directly linked to the &lt;code&gt;FlatList&lt;/code&gt; element in the interface. To do this, we'll use what React Native calls a &lt;code&gt;state&lt;/code&gt;, a special kind of variable which remains between each reload of the display of an interface element.&lt;/p&gt;

&lt;p&gt;Here, we use the &lt;code&gt;useState()&lt;/code&gt; hook to get the &lt;code&gt;state&lt;/code&gt; variable and its setter :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We initialise the list of messages as an empty array, which we then fill using the setter &lt;code&gt;setMessages()&lt;/code&gt; method. Two methods are used to display the message :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;renderItem()&lt;/code&gt; (inserts the component which represents the message into the &lt;code&gt;FlatList&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;handleSend()&lt;/code&gt; (adds the message to the state messages)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My request to ChatGPT has already given me the &lt;code&gt;renderItem()&lt;/code&gt; method, which I then modify to add my CSS classes :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;renderItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sender&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;botMessageContainer&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;myMessageContainer&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt; &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sender&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;botMessage&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;styles&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;myMessage&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I then retrieve the &lt;code&gt;handleSend()&lt;/code&gt; method given to me by ChatGPT, which will be activated each time the "Send" button is pressed :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSend&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inputValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nf"&gt;setInputValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nf"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;bot&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}]);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this stage, I can start testing the application via Expo and send messages within the application to adjust the CSS of the message bubbles.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnb-dev.fr%2Fimages%2Frn-chatbot%2Ftest-message-chatbot.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnb-dev.fr%2Fimages%2Frn-chatbot%2Ftest-message-chatbot.webp" alt="bulles.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that the list exists and the CSS is correct, we can try to have a real conversation with our GPT-3 instance. This is the most important part of our application, and it was at this point that I encountered &lt;strong&gt;the first real errors from ChatGPT&lt;/strong&gt; in my initial request, not to mention the few inaccuracies I'd already encountered in its response, but which I was able to correct immediately.&lt;/p&gt;

&lt;h2&gt;
  
  
  ChatGPT's imperfections
&lt;/h2&gt;

&lt;p&gt;I encountered my first problem with ChatGPT when implementing the dialogue with the GPT-3 instance. I encountered two blocking errors when trying to follow ChatGPT's instructions :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using OpenAI with React Native&lt;/li&gt;
&lt;li&gt;Accessing environment variables in a React Native application&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the first case, after querying ChatGPT several times to no avail, I decided to look directly in the OpenAI documentation (the doc never gives you away!), which gave me the lines of code I needed.&lt;/p&gt;

&lt;p&gt;In the second case, I also made several requests to ChatGPT, all to no avail. This time, there wasn't really any documentation available, but I was able to find the solution to my problem thanks to &lt;a href="https://medium.com/swlh/how-to-properly-use-environment-variables-in-an-expo-react-native-app-7ab852590b30" rel="noopener noreferrer"&gt;a Medium article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;As for the reason for these erroneous responses, part of the answer to this question lies, I think, in two facts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ChatGPT data only goes up to 2021&lt;/li&gt;
&lt;li&gt;ChatGPT is not connected to the Internet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From these two facts, we can see that there's a good chance that he's basing his thoughts and answers on deprecated documentation, which is problematic in the case of a framework that continues to evolve. What's more, it's impossible for him to correct himself by checking other sources on the Internet, since it only works with the data that was used to train him.&lt;/p&gt;

&lt;p&gt;In short, as many people have already pointed out, &lt;strong&gt;ChatGPT is not yet ready to replace a human developer&lt;/strong&gt; (well, that's true for GPT-3).&lt;/p&gt;

&lt;h2&gt;
  
  
  Completing the application
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Messages, part 2
&lt;/h3&gt;

&lt;p&gt;After successfully setting up communication with the GPT-3 instance, a problem arose: the messages were only displayed once the bot had responded. I had noticed that it was impossible to make a double call to the setter of a state work, so I looked to see if it was possible to do this in some way. Here, no request to ChatGPT, a standard Google search led me to &lt;a href="https://www.andreadiotallevi.com/blog/how-to-handle-multiple-set-state-calls-on-the-same-object-in-react" rel="noopener noreferrer"&gt;a developer's blog post&lt;/a&gt; that contained the solution to my problem (and a detailed explanation of the problem's origin).&lt;/p&gt;

&lt;p&gt;This changes the nature of what I send to the setter &lt;code&gt;setMessages()&lt;/code&gt; in my &lt;code&gt;handleSend()&lt;/code&gt; method :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// How to send messages "one by one"&lt;/span&gt;
&lt;span class="nf"&gt;setMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;previousMessages&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;([...&lt;/span&gt;&lt;span class="nx"&gt;previousMessages&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;previousMessages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}]));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  A little style, part 2
&lt;/h3&gt;

&lt;p&gt;In terms of the application's style, I wanted to emphasise the difference between the bot's messages and those of the user. So I chose to change the font of the bot's messages to monospace (a bit of a cliché, but it's in the spirit of the application, after all).&lt;/p&gt;

&lt;p&gt;I also wanted to adjust the spacing between the &lt;code&gt;FlatList&lt;/code&gt; and the rest of the interface elements. At first I'd opted for &lt;em&gt;padding&lt;/em&gt; but, after several attempts, it still wasn't what I wanted. While doing some research (again without the help of ChatGPT), I came across a &lt;a href="https://github.com/facebook/react-native/issues/15707" rel="noopener noreferrer"&gt;&lt;em&gt;issue&lt;/em&gt; Github&lt;/a&gt; on the React Native project repository.&lt;br&gt;
Finally, the solution was simple: change the &lt;em&gt;padding&lt;/em&gt; to &lt;em&gt;margin&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Additions and embellishments
&lt;/h2&gt;
&lt;h3&gt;
  
  
  A modal, an application
&lt;/h3&gt;

&lt;p&gt;Most applications have an 'About' section, dedicated to displaying various information about the application or the person who produced it. So I wanted to add this to my application!&lt;/p&gt;

&lt;p&gt;To do this, I used the &lt;code&gt;Modal&lt;/code&gt; element in React Native, which I bring up by pressing on the application icon in the header. In this modal, the information appears in the form of a bulleted list, which I display via their Unicode code (I found the trick on &lt;a href="https://www.atomlab.dev/tutorials/react-native-bullet-list" rel="noopener noreferrer"&gt;this article on the atomlab.dev website&lt;/a&gt;). For some of this information, I wanted to integrate a hypertext link, so I used the &lt;code&gt;Linking.openURL()&lt;/code&gt; method to achieve this.&lt;/p&gt;

&lt;p&gt;As I wanted the modal to be displayed above the &lt;code&gt;FlatList&lt;/code&gt; of messages, I also had to add an &lt;em&gt;overlay&lt;/em&gt;, and make a few changes to the CSS (particularly to the &lt;code&gt;z-index&lt;/code&gt; of the elements).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnb-dev.fr%2Fimages%2Frn-chatbot%2Fmodal-app.webp" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fnb-dev.fr%2Fimages%2Frn-chatbot%2Fmodal-app.webp" alt="modal.png" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Loading spinner, for feedback
&lt;/h3&gt;

&lt;p&gt;As its name suggests, a &lt;em&gt;loading spinner&lt;/em&gt; is an element designed to indicate &lt;strong&gt;a loading state&lt;/strong&gt;. It's therefore necessary to have one, so that the user knows that the bot is going to respond, and that it's not just the application that's crashing!&lt;/p&gt;

&lt;p&gt;As this is a common feature these days, when it came to adding this element to my application, I preferred to follow an old adage from developers that says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't reinvent the wheel.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So I chose a simple &lt;em&gt;spinner&lt;/em&gt; whose style is easy to adapt: &lt;code&gt;react-native-loading-spinner-overlay&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Auto scroll to last message
&lt;/h3&gt;

&lt;p&gt;For this first version of my chatbot, something trivial yet very common in messaging applications was missing: &lt;strong&gt;scrolling to the last message&lt;/strong&gt;. In most applications, when a new message appears in the list, the view moves to display the message in its entirety (or at least to display the end of the message). However, when I tried to add this "harmless" behaviour, I came up against a thorny problem: an 'index out of range' problem (classic, but not always obvious).&lt;/p&gt;

&lt;p&gt;After a few quick searches with no conclusive results, I decided to turn once again to ChatGPT. Armed with my new understanding of how a state and its &lt;em&gt;setter&lt;/em&gt; work, I explained my hypothesis as to why my scroll wasn't working, and asked it, on the basis of this hypothesis, how it would solve the problem.&lt;/p&gt;

&lt;p&gt;And I have to admit two things :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;My hypothesis was correct&lt;/li&gt;
&lt;li&gt;ChatGPT very quickly understood the problem and provided me with a suitable solution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This solution boils down to executing my scroll at the right moment, i.e. &lt;strong&gt;at the end of the animation showing the message&lt;/strong&gt; in the &lt;code&gt;FlatList&lt;/code&gt;. This gives a function such as :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="nf"&gt;requestAnimationFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;refFlatList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;current&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;scrollToEnd&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;animated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I don't think I would have found this method so quickly, without the help of ChatGPT, and that's one of the advantages that can't be denied: &lt;strong&gt;it saves a lot of time&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build v.1.0
&lt;/h2&gt;

&lt;p&gt;Satisfied with the elements added so far, I thought it was time to install version 1 of this project !&lt;/p&gt;

&lt;p&gt;To &lt;em&gt;build&lt;/em&gt; my project, I used the Expo documentation as a guide to set the various parameters required for the process to run smoothly. I also noticed something : the environment variables as I was using them were not embedded in the APK produced by the build. As a result, there was no API key, and therefore no bot !&lt;/p&gt;

&lt;p&gt;To remedy this, I had to create a &lt;em&gt;secret&lt;/em&gt; with an EAS command (the tool that manages Expo builds) and modify the code slightly. And there you have it, a first version !&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This little project has no other purpose than to allow me to work on React Native, and incidentally to pretend I'm Tony Stark. It's still very basic, but I'll probably come back to it later to add other features that will bring my chatbot closer to the level of the famous Jarvis.&lt;/p&gt;

&lt;p&gt;All the code is available &lt;a href="https://github.com/Mar-Nb/react-native-chatbot" rel="noopener noreferrer"&gt;on my GitHub repository&lt;/a&gt;. You can find the article &lt;a href="https://nb-dev.fr/2023/react-native-chatbot-v1/" rel="noopener noreferrer"&gt;on my blog&lt;/a&gt; and you can also follow me &lt;a href="https://twitter.com/da_whistler" rel="noopener noreferrer"&gt;on twitter&lt;/a&gt;, where I mainly talk about tech and my dev activity.&lt;/p&gt;

&lt;p&gt;Until next time! 👋&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>reactnative</category>
    </item>
  </channel>
</rss>
