<?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: Visnalize</title>
    <description>The latest articles on DEV Community by Visnalize (@visnalize).</description>
    <link>https://dev.to/visnalize</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%2Forganization%2Fprofile_image%2F7434%2F9de7e3ec-0bbb-4545-b7d8-3f30b3490ccc.png</url>
      <title>DEV Community: Visnalize</title>
      <link>https://dev.to/visnalize</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/visnalize"/>
    <language>en</language>
    <item>
      <title>Ranking Microsoft Windows versions - 2025 Edition</title>
      <dc:creator>Khang</dc:creator>
      <pubDate>Sun, 20 Jul 2025 04:03:58 +0000</pubDate>
      <link>https://dev.to/visnalize/ranking-microsoft-windows-versions-2025-edition-14g0</link>
      <guid>https://dev.to/visnalize/ranking-microsoft-windows-versions-2025-edition-14g0</guid>
      <description>&lt;p&gt;Everyone has their own preferences and opinions on which Windows version is the best, so in this fun little post, I'm going to rank the Windows versions from best to worst in my opinion.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;As biased as this sounds, this list is actually backed by facts, statistics, and market share trends (source).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🏆 Windows 7 - the GOAT, no debate
&lt;/h2&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqirqvh07df19onfjrm9n.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqirqvh07df19onfjrm9n.png" alt="Windows 7" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Windows 7, without a doubt, is the best Windows version to this day. It was fast, stable, and had the best user interface. The perfect balance between performance and aesthetics. It took everything people hated about Vista and... didn't do it. Whether you were gaming, working, or just customizing the hell out of your desktop, Windows 7 made you feel like your PC got you. Even after Microsoft ended support, many users clung to it for years, including enterprises, businesses, and individuals.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;If you disagree, you're against a civilization!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🥈 Windows XP - that startup sound *chefs kiss*
&lt;/h2&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh9ous4pw5fggphyvg1cv.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh9ous4pw5fggphyvg1cv.png" alt="Windows XP" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Blue skies, green hills, and a startup sound etched into memory. Windows XP was ridiculously lightweight, reliable, and compatible with almost everything. It was the first Windows version to really nail the user experience. It became the backbone of businesses, schools, and homes for years. Paint, Pinball, Clippy, Windows Media Player with custom skins. Enough said. It was the golden age of Windows.&lt;/p&gt;

&lt;h2&gt;
  
  
  🥉 Windows 10 - when Microsoft finally listened
&lt;/h2&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F75zc9g95wybwsrxb62ty.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F75zc9g95wybwsrxb62ty.png" alt="Windows 10" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Okay, this one is not on a nostalgia trip, but Windows 10 is a solid operating system. After the mess that was 8 and the "meh" 8.1, this was the comeback we needed. It brought back the Start Menu, improved performance, and finally had users agreeing on something. It was a step in the right direction, even if it had its fair share of bugs and issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  4️⃣ Windows 98 - if you know, you know
&lt;/h2&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzfc120p9nprooixhud6i.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzfc120p9nprooixhud6i.png" alt="Windows 98" width="640" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yet another classic. Windows 98 was &lt;em&gt;the&lt;/em&gt; Windows for anyone growing up in the late 90s. It introduced several features which would become standard in future versions. The aesthetics it inherited from Windows 95 remained iconic. Remember Half-Life, Rollercoaster Tycoon, or Quake? Those games were the reason many of us fell in love with gaming and computers.&lt;/p&gt;

&lt;h2&gt;
  
  
  5️⃣ Windows 11 - trying hard to be cool
&lt;/h2&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7jwgbfxc1hh9gh9phk6d.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7jwgbfxc1hh9gh9phk6d.png" alt="Windows 11" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The latest version of Windows at this point in time. Windows 11 is a mixed bag. It has a sleek design, but it feels like Microsoft is trying too hard to be trendy. The new Start Menu and taskbar are... different. Some people love it, some hate it. It's fast (kinda, if you have the right hardware), but it feels like a glorified Windows 10 update. The new features are nice, but it doesn't feel like a major leap forward. It's like that friend who tries to be cool but ends up being cringy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honorable mentions and conclusion
&lt;/h2&gt;

&lt;p&gt;🎀 &lt;strong&gt;Windows Vista&lt;/strong&gt;: beautiful but slow and buggy, still a solid attempt that paved the way for Windows 7.&lt;/p&gt;

&lt;p&gt;🎀 &lt;strong&gt;Windows 8.1&lt;/strong&gt;: a decent attempt to fix the mess of Windows 8, but just not enough.&lt;/p&gt;

&lt;p&gt;In conclusion, Microsoft has had its ups and downs with Windows versions. Some were revolutionary, while others were just... there.&lt;/p&gt;

&lt;p&gt;But one thing is for sure: if you want to experience the best of Windows 7 and every other Windows version mentioned above, you can always check out &lt;a href="https://visnalize.com/win7simu/about" rel="noopener noreferrer"&gt;Win7 Simu&lt;/a&gt;. It's the closest thing to reliving the glory days of Windows 7 without the hassle of installing it on your machine, or messing around with virtual machines and technical stuff. Just pure nostalgia and fun.&lt;/p&gt;

</description>
      <category>watercooler</category>
    </item>
    <item>
      <title>I built a Nokia Composer with AI's assistance</title>
      <dc:creator>Khang</dc:creator>
      <pubDate>Mon, 10 Mar 2025 04:17:53 +0000</pubDate>
      <link>https://dev.to/visnalize/i-built-a-nokia-composer-with-ais-assistance-a4f</link>
      <guid>https://dev.to/visnalize/i-built-a-nokia-composer-with-ais-assistance-a4f</guid>
      <description>&lt;p&gt;I have recently released a new update to &lt;a href="https://visnalize.com/brick1100/about" rel="noopener noreferrer"&gt;Brick 1100&lt;/a&gt; a few days ago, this update includes the new &lt;a href="https://visnalize.com/brick1100/changelog#_0-0-14-mar-6-2025" rel="noopener noreferrer"&gt;Composer feature&lt;/a&gt; allowing users to make their own ringtones in a monophonic style. It's a feature that I never thought I would be able to implement on my own, having no prior knowledge of music theory and even never having used the Nokia Composer before. However, with the help of AI, I was able to build it, in a considerably short amount of time. In this post, I would like to share the process of building the Nokia Composer and how AI has evolved remarkably to make it possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Nokia Composer?
&lt;/h2&gt;

&lt;p&gt;Composer was a built-in feature on several classic Nokia phones, allowing users to create their own monophonic ringtones. It provided a simple interface where users could manually enter musical notes, defining their pitch and duration. This feature was a popular way for users to personalize their phones in the pre-polyphonic and MP3 ringtone era, enabling them to compose famous tunes, TV theme songs, or even their own musical creations.&lt;/p&gt;

&lt;h3&gt;
  
  
  How it works
&lt;/h3&gt;

&lt;p&gt;The interface allow users to input notes using the phone's keypad. Each key corresponds to a different musical note, and additional options let users adjust the octave and duration of each note. Once a melody is created, it can be saved and set as the ringtone.&lt;/p&gt;

&lt;p&gt;A typical composing process included:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Opening the Composer – Accessible through the phone's menu, a blank canvas would appear for users to start composing.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Composing the tune – Users could input notes using the phone's keypad:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Numeric keys &lt;code&gt;1&lt;/code&gt;-&lt;code&gt;7&lt;/code&gt; are used to assign musical notes&lt;/li&gt;
&lt;li&gt;Keys &lt;code&gt;8&lt;/code&gt; and &lt;code&gt;9&lt;/code&gt; change the note's duration&lt;/li&gt;
&lt;li&gt;Key &lt;code&gt;0&lt;/code&gt; adds a rest&lt;/li&gt;
&lt;li&gt;Key &lt;code&gt;*&lt;/code&gt; shifts the note's octave&lt;/li&gt;
&lt;li&gt;Key &lt;code&gt;#&lt;/code&gt; makes the note sharp&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Editing the tune – The melody could be played back, and individual notes could be modified or deleted as needed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Saving and setting as ringtone – Once satisfied, users could save their custom melody and assign it as the default ring&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;



&lt;h3&gt;
  
  
  Deep dive
&lt;/h3&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%2Fvisnalize.com%2Fassets%2Fnote-structure.C8Lt6fjU.svg" 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%2Fvisnalize.com%2Fassets%2Fnote-structure.C8Lt6fjU.svg" alt="A note's structure" width="368" height="265"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;All possible combinations of a note's structure&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Nokia Composer follows a structured approach to note input, using a simplified notation system. Below is a breakdown of the key components involved in composing a melody:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Musical notes:&lt;/strong&gt; Each numeric key, &lt;code&gt;1-7&lt;/code&gt;, is assigned a specific note:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;1&lt;/code&gt; = C (Do)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2&lt;/code&gt; = D (Re)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;3&lt;/code&gt; = E (Mi)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;4&lt;/code&gt; = F (Fa)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;5&lt;/code&gt; = G (Sol)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;6&lt;/code&gt; = A (La)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;7&lt;/code&gt; = B (Ti)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Duration:&lt;/strong&gt; Keys &lt;code&gt;8&lt;/code&gt; and &lt;code&gt;9&lt;/code&gt; adjust the note's length. The default duration is a quarter note (1/4 length of a whole note), which is represented by number &lt;code&gt;4&lt;/code&gt;. Pressing &lt;code&gt;8&lt;/code&gt; halves the duration, while &lt;code&gt;9&lt;/code&gt; doubles it. The corresponding values are:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;1&lt;/code&gt; = whole note&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2&lt;/code&gt; = half note&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;4&lt;/code&gt; = quarter note&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;8&lt;/code&gt; = eighth note&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;16&lt;/code&gt; = sixteenth note&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Dotting a note increases its duration by half. For example, a dotted quarter note is 3/8 (1/4 + 1/8) of a whole note.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Octave:&lt;/strong&gt; The &lt;code&gt;*&lt;/code&gt; key is used to shift a note's octave, typically covering 3 octaves.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rests:&lt;/strong&gt; The &lt;code&gt;0&lt;/code&gt; key is used to insert a rest (pause between notes). Duration keys can also apply to rests, adjusting their length accordingly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sharp notes:&lt;/strong&gt; The &lt;code&gt;#&lt;/code&gt; key is used to make a note sharp, raising its pitch by a semitone, not applicable to the E and B notes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tempo:&lt;/strong&gt; The beats per minute (BPM) value to control the speed of the melody.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Example
&lt;/h4&gt;

&lt;p&gt;Let's take &lt;code&gt;4c2&lt;/code&gt; as an example, this represents a quarter note C in the second octave, which is also the default note for the Composer. By common convention, a quarter note equals to 1 beat, hence if we set the tempo to 120 BPM, the duration of this note would be 0.5 seconds (60 / 120 = 0.5s). In the same manner, we can interpret other note combinations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;8c2&lt;/code&gt; = eighth note C in the second octave with a duration of 0.25s (half a beat)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;2c2&lt;/code&gt; = half note C in the second octave with a duration of 1s (2 beats)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;4.c2&lt;/code&gt; = dotted quarter note C in the second octave with a duration of 0.75s (1 and a half beats)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;4#c2&lt;/code&gt; = quarter note C# in the second octave with a duration of 0.5s&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;16.#d1&lt;/code&gt; = sixteenth note D# in the first octave with a duration of 0.125s (1/4 beat)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  How I built it
&lt;/h2&gt;

&lt;p&gt;I hope the above explanation gives you a good understanding of how the Nokia Composer works, because that's something I didn't know prior to building it. I had never used the Composer feature on a Nokia phone either, so I wasn't sure if I would ever get to implement it in Brick 1100. However, the project wouldn't fulfill its purpose as a Nokia 1100 simulator without this iconic feature, and become a let down for users who were expecting it. I decided to give it a shot, and with the help of AI, anything now seems possible.&lt;/p&gt;
&lt;h3&gt;
  
  
  With AI's assistance
&lt;/h3&gt;

&lt;p&gt;In summary, I used &lt;a href="https://cursor.com" rel="noopener noreferrer"&gt;Cursor&lt;/a&gt; (an AI code editor) with the Claude 3.5 Sonnet model to build, the entire process took me 11 prompts, around 3 days to make the Composer fully functional and integrated with the project's codebase.&lt;/p&gt;

&lt;p&gt;It's amazing to see how AI has evolved in such a short time, enabling developers like me to build complex features without prior knowledge or experience in a certain field. I remember just months ago, AI tools like ChatGPT or GitHub Copilot are just making dumb, made-up suggestions when it comes to coding, but now they can actually provide helpful assistance. This is even more impressive with Cursor + Claude's model, which could generate for me a fully functional Composer in the very first prompt. Though to be fair, quite a few iterations were needed to refine the code, especially in handling the core logic of the Composer and integrating it with the existing codebase, but the AI's suggested code was an excellent starting point. It's not an exaggeration to say that, as a software developer, I should be worried about my job security due to the rapid growth of AI, but as an indie maker, it makes me feel like I have a superpower to build anything I want.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm48p1ypd8tdi6kw379zq.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm48p1ypd8tdi6kw379zq.png" alt="First prompt to build Nokia Composer" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Without much instruction, solely from my first simple prompt, the AI agent was able to gather the necessary information of how the Nokia Composer works by searching the web, it then scanned the existing codebase to understand the structure, inspected the relevant parts for the conventions, and reused for generating the code. The result was great, the Composer was functional, but it was nowhere near perfect. There were still flaws, bugs, and inefficiencies that needed to be taken care of. It couldn't understand the way the keypad input was handled (so it improvised, but completely off the mark), the composer interface didn't fit in the overall layout, and the notes' pitch and duration were not accurate. In general, if I were to give the generated code a score, it would get a 6/10, but the most crucial and hardest part was done, so I was pretty happy with it.&lt;/p&gt;


&lt;h3&gt;
  
  
  Iterations and refinements
&lt;/h3&gt;

&lt;p&gt;From reviewing the generated code, I knew where the problems lied, but I had no idea how to fix them at that point. Luckily, I found &lt;a href="https://github.com/zserge/nokia-composer" rel="noopener noreferrer"&gt;this version&lt;/a&gt; of Composer built by &lt;a href="https://zserge.com/" rel="noopener noreferrer"&gt;Serge Zaitsev&lt;/a&gt;, which has a rather simple and clean implementation to follow. I used this as a reference source to feed the AI agent, asking it to explain the code to me and refactor it to be more readable and follow the project's coding style.&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fodqnoz02430kywd3pg00.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fodqnoz02430kywd3pg00.png" alt="Feeding the AI with a reference source" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The generated code this time addressed most of the issues related the core logic of the Composer, once again, AI has been proven to be a wonderful tool for learning and adapting as it evolves. After some manual clean-up and adjustments, the Composer was finally in a good shape, the most crucial part of the Composer's logic was then encapsulated within the below function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="cm"&gt;/**
 * @param {Note[]} sequence The sequence of notes to play
 * @param {MediaStreamAudioDestinationNode} [destination] The stream destination to record audio
 */&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;playSequence&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;oscillator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;audioContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createOscillator&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;gainNode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;audioContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createGain&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

  &lt;span class="nx"&gt;oscillator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gainNode&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;audioContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;oscillator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;square&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;oscillator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&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;destination&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;gainNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;destination&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;currentTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;audioContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setAudioParam&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;param&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&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;param&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setValueAtTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currentTime&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;clamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;min&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

  &lt;span class="nx"&gt;sequence&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(({&lt;/span&gt; &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;octave&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isSharp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hasDot&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;noteChar&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;charCodeAt&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// ASCII value of note&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;noteStep&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;noteChar&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mf"&gt;1.6&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// map note to the 12-tone scale&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;octaveOffset&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nf"&gt;clamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;octave&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="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;noteIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;noteStep&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isSharp&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;octaveOffset&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;isRest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;noteChar&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;adjustedVolume&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;volume&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// adjust volume based on keypad volume&lt;/span&gt;

    &lt;span class="nf"&gt;setAudioParam&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;oscillator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;frequency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;261.63&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="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;noteIndex&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// convert to frequency (Hz)&lt;/span&gt;
    &lt;span class="nf"&gt;setAudioParam&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gainNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;isRest&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;adjustedVolume&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;noteDuration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tempoValue&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nf"&gt;clamp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;duration&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;64&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;hasDot&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="nx"&gt;currentTime&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;noteDuration&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nf"&gt;setAudioParam&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;gainNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// add a small pause between notes&lt;/span&gt;
    &lt;span class="nx"&gt;currentTime&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;noteDuration&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;wait&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;currentTime&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;audioContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;currentTime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&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;In simple words, the function above takes a sequence of notes and plays them back in the correct pitch, duration, and tempo. It uses the Web Audio API to generate the sound, and the function is called whenever a note is inputted or a melody composition is played. It also takes the destination stream as an optional parameter, allowing the composition to be recorded for exporting as a ringtone, an enhancement that wasn't available in the original Nokia Composer.&lt;/p&gt;

&lt;p&gt;From this point, I just had to make some more manual tweaks to make the Composer's UI fit in the project's layout, and used a few more prompts to fix some unknown issues as they popped up when testing the feature on Android and iOS. As mentioned earlier, the total time spent on building it was around 3 days with 11 prompts, and we had a production-ready Nokia Composer in Brick 1100.&lt;/p&gt;

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

&lt;p&gt;Building the Nokia Composer was a challenging yet rewarding experience, and it wouldn't have been possible without the help of AI. I wouldn't know where to start to get a sufficient knowledge of music theory, let alone implement a feature like this in a short amount of time. Regardless how you perceive AI, it's undeniable that it has revolutionized the way we build software, and it's only going to get better from here. I'm excited to see what other features I can build with AI's assistance, and I hope you are too.&lt;/p&gt;

&lt;p&gt;If you haven't tried out the Composer feature in Brick 1100 yet, I encourage you to give it a go, and let me know what you think (there's also a &lt;a href="https://discord.gg/6AQDnZa4Xm" rel="noopener noreferrer"&gt;Discord server&lt;/a&gt; to hang out, leave feedback, or share your creations, join us if you're interested).&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>showdev</category>
      <category>ai</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Turning my codepen into an actual app - Brick 1100</title>
      <dc:creator>Khang</dc:creator>
      <pubDate>Sat, 07 Oct 2023 05:26:48 +0000</pubDate>
      <link>https://dev.to/visnalize/turning-my-codepen-into-an-actual-app-brick-1100-on3</link>
      <guid>https://dev.to/visnalize/turning-my-codepen-into-an-actual-app-brick-1100-on3</guid>
      <description>&lt;p&gt;Some time ago, in one of my very first posts on DEV, I shared a silly codepen made from learning for pure fun:&lt;/p&gt;


&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/khangnd/nokia-1100-simulation-2hef" class="crayons-story__hidden-navigation-link"&gt;Nokia 1100 Simulation&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/khangnd" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F493557%2F95de03d9-1145-4565-bd1b-cfe5f5340693.png" alt="khangnd profile" class="crayons-avatar__image" width="460" height="460"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/khangnd" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Khang
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Khang
                
              
              &lt;div id="story-author-preview-content-546477" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/khangnd" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F493557%2F95de03d9-1145-4565-bd1b-cfe5f5340693.png" class="crayons-avatar__image" alt="" width="460" height="460"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Khang&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/khangnd/nokia-1100-simulation-2hef" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Dec 18 '20&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/khangnd/nokia-1100-simulation-2hef" id="article-link-546477"&gt;
          Nokia 1100 Simulation
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/codepen"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;codepen&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/html"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;html&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/javascript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;javascript&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/css"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;css&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/khangnd/nokia-1100-simulation-2hef" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;173&lt;span class="hidden s:inline"&gt; reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/khangnd/nokia-1100-simulation-2hef#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              Comments


              10&lt;span class="hidden s:inline"&gt; comments&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            1 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


&lt;p&gt;Turned out people found it interesting somehow as the post and the codepen itself was seen receiving a few interactions. Years later, after gaining more skills, and more experience, I came back to this idea to actually complete it. From a mere silly codepen that was barely functional, it has become a full-fledged app (though still in beta) and made its way to &lt;a href="https://play.google.com/store/apps/details?id=com.visnalize.brick1100" rel="noopener noreferrer"&gt;&lt;strong&gt;Google Play&lt;/strong&gt;&lt;/a&gt;. In this article, I'm happy to share the progress, how and what I used to build it, and let's explore some cool and unique features I have brought out with this app.&lt;/p&gt;

&lt;h2&gt;
  
  
  A silly idea that got realized
&lt;/h2&gt;

&lt;p&gt;We, developers, tend to look for project ideas where we can challenge ourselves and put our knowledge and skills into practice. Just like everyone else, when I first got myself into web dev, I had plentiful ideas of what I could build to learn coding more easily, enrich my portfolio with more useless projects, and dazzle the recruiters to land a fulfilling job. However, a little bit out of the ordinary person I am, I actually wanted to build something cool, something original that not many people had thought of and done, so I came up with the idea of replicating the look of an old phone (whoa, how innovative...) and simulate some of its functionalities (so original...). As a result, we have the "Nokia 1100 simulation" codepen above.&lt;/p&gt;

&lt;p&gt;At that time, I stopped where I thought was sufficient for a silly idea as it was, even if I wanted to go further, my skills at that point wouldn't allow it, because I was still a NOOB! (though I still am). I just left it there and forgot about it. Sometime later, after having gained some experience working for companies and leveling up myself a bit, I revisited some past projects to see if I could advance any of them with my new abilities. The Nokia simulation was at the top of that list, considering how much traction it gained at the time (maybe not much for you, but that was a lot for a NOOB!). And here we are, a pet project that actually got finished and made it to the public.&lt;/p&gt;

&lt;h2&gt;
  
  
  The making process
&lt;/h2&gt;

&lt;p&gt;The idea initiated in codepen was made with pure HTML/CSS/JS as I had just started learning the fundamentals. However, this time, applying the wealth of front-end development knowledge I have earned over the years, I rebuilt the project from scratch, making good use of modern web technologies and frameworks to speed up the development, and ease the feature addition and maintenance process as it grows.&lt;/p&gt;

&lt;p&gt;I started spending my free time outside of work hours and weekends to get into it. After about two weeks, I finally made it an MVP (minimum viable product) with most of the &lt;a href="https://visnalize.com/brick1100/changelog.html#_0-0-1" rel="noopener noreferrer"&gt;core features covered&lt;/a&gt;, sort of. So far, the most prominent stuff that I used to build it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vue 2.7&lt;/strong&gt; - the main framework that empowers its UI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pinia&lt;/strong&gt; - the state management library to handle shared state across components.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vue Router&lt;/strong&gt; - the routing library to ease the navigation within the app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Capacitor&lt;/strong&gt; - the MVP that helps transition a traditional web app into a mobile app effortlessly.&lt;/li&gt;
&lt;li&gt;And lastly, the most incredible database for managing user data - &lt;strong&gt;localStorage&lt;/strong&gt; 😂&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are a few other packages and libraries that enhance the developer experience and contribute to the feature feasibility, e.g several &lt;strong&gt;Capacitor plugins&lt;/strong&gt; wiring up certain native mobile features for the app, &lt;strong&gt;dayjs&lt;/strong&gt; providing out-of-the-box utils to work with date and time, or &lt;strong&gt;voca&lt;/strong&gt; for handy string utils without the needs of reinventing the wheel.&lt;/p&gt;

&lt;h3&gt;
  
  
  Breaking down the components
&lt;/h3&gt;

&lt;p&gt;At a high level, the app is composed of the following major building blocks:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F65aigdwqjto881os3uax.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F65aigdwqjto881os3uax.png" alt="Brick 1100 components" width="304" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The container, which is just a freaking image, is layered below the other components. It also holds the responsibility of resizing the app to adapt to the device/browser window's size.&lt;/li&gt;
&lt;li&gt;The screen plays a vital role in rendering what would be otherwise visible to the users.&lt;/li&gt;
&lt;li&gt;The keypad/numpad is in charge of the interactivity of the whole app. The pattern here is that with the help of Pinia, the keypad/numpad would emit respective global events as the users interact with it and the other components then behave accordingly. It is easily the toughest part that I had to deal with as meticulously as possible, to capture the essence of a nostalgic feeling back when we all still used these pads to operate a phone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's an outlook on how the above design is implemented for your reference:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;phone-container&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;phone-screen&lt;/span&gt; &lt;span class="na"&gt;:state=&lt;/span&gt;&lt;span class="s"&gt;"state"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;menu-screen&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Menu"&lt;/span&gt; &lt;span class="na"&gt;:index=&lt;/span&gt;&lt;span class="s"&gt;"index"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;menu-select&lt;/span&gt;
          &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"main"&lt;/span&gt;
          &lt;span class="na"&gt;:items=&lt;/span&gt;&lt;span class="s"&gt;"items"&lt;/span&gt;
          &lt;span class="na"&gt;:current=&lt;/span&gt;&lt;span class="s"&gt;"index"&lt;/span&gt;
          &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;[Event.Back]=&lt;/span&gt;&lt;span class="s"&gt;"handleMenuBack"&lt;/span&gt;
          &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;[Event.Select]=&lt;/span&gt;&lt;span class="s"&gt;"handleMenuSelect"&lt;/span&gt;
          &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;[Event.Change]=&lt;/span&gt;&lt;span class="s"&gt;"handleMenuChange"&lt;/span&gt;
        &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;/menu-screen&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/phone-screen&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;phone-keypad&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;phone-numpad&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/phone-container&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A simplified snippet of the keypad/numpad implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// PhoneKeypad.vue&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;startTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;isHolding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&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;span class="na"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;mapStores&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;useKeypadStore&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;clearTimer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;clearTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;press&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clearTimer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keypadStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;press&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;HOLD_TOLERANCE&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;release&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clearTimer&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="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startTime&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;HOLD_TOLERANCE&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isHolding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keypadStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;release&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isHolding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&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;span class="nf"&gt;hold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isHolding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keypadStore&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&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;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// keypad.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useKeypadStore&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defineStore&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keypad&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="na"&gt;state&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="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;event&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="na"&gt;_diff&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="c1"&gt;// workaround to observe the keypad interaction,&lt;/span&gt;
      &lt;span class="c1"&gt;// as the key before and after the interaction may be the same key.&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_diff&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;press&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Gesture&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Press&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;release&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Gesture&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Release&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="nf"&gt;hold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Gesture&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Hold&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&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;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Adding some twists
&lt;/h3&gt;

&lt;p&gt;While the project originally aimed to replicate the phone experience faithfully, it also presented an opportunity to add unique twists that, to me, might turn out to be the selling points for the app to be more useful: a collection holder of &lt;strong&gt;mini-games/apps&lt;/strong&gt; where newbie devs can also &lt;strong&gt;learn&lt;/strong&gt; coding by submitting to this collection.&lt;/p&gt;

&lt;p&gt;Due to the simplistic nature of the app and its design, I have a strong belief that it can be perceived as a code playground where people can get their ideas implemented in the rawest form, text-based apps, or apps with pixelated, monotonic graphics. Let's take a look at the simple model below:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcllsehc05yilq0orszfc.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcllsehc05yilq0orszfc.png" alt="Bridge 1100 model" width="536" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Brick 1100 was built in a way that we could easily extend its functionalities with external games/apps. These external games/apps can communicate with Brick 1100 itself back and forth via an interface called Bridge 1100, you can read more about that &lt;a href="https://github.com/Visnalize/bridge-1100" rel="noopener noreferrer"&gt;in this Github repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It's nothing sort of any kind of innovation (as expected from a noob). Those external apps/games are just being gathered and pulled from &lt;a href="https://github.com/Visnalize/brick-1100-apps" rel="noopener noreferrer"&gt;this Github repo&lt;/a&gt;. By the time of this article, you can see from that repo, there are only 2 apps available:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pwd Generator&lt;/strong&gt; - a simple password generator from a length input.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Randomizer&lt;/strong&gt; - a simple randomizer app that outputs a random result each time depending on the selected mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both of them are super simple, plain text-based apps that can be completed in no time. However, they were developed using different web techs, with the first one using pure HTML/CSS/JS while the latter using the Mithril.js framework. This gives you the freedom of choice when it comes to the web tech that you want to learn by making and takes relatively little of your time and effort to complete an app idea.&lt;/p&gt;

&lt;p&gt;How those apps show up in Brick 1100:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F53cw2mjrfxzu6dpo0zwo.jpg" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F53cw2mjrfxzu6dpo0zwo.jpg" alt="Brick 1100 online apps" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Final words
&lt;/h2&gt;

&lt;p&gt;Despite how silly and ridiculously simple this project looks, I had a really great time building it and felt super proud to see a pet project that actually came to light and got installed on a few user devices. If it has somehow captured your interest and want to try it out, you can install it from &lt;a href="https://play.google.com/store/apps/details?id=com.visnalize.brick1100" rel="noopener noreferrer"&gt;&lt;strong&gt;Google Play&lt;/strong&gt;&lt;/a&gt;. And feel free to join &lt;a href="https://discord.gg/6AQDnZa4Xm" rel="noopener noreferrer"&gt;our Discord&lt;/a&gt; to have some little chit-chat, or if you want to build something on it but getting stuck somewhere, I'm happy to help out there.&lt;/p&gt;

&lt;p&gt;And now, if you will excuse me I have an app to develop, and some users to satisfy. Thank you for reading ✌&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>android</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
