<?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: Abdul Samad</title>
    <description>The latest articles on DEV Community by Abdul Samad (@iabdsam).</description>
    <link>https://dev.to/iabdsam</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F725667%2F803b9e47-9181-471b-b677-e156cb58e7f5.jpg</url>
      <title>DEV Community: Abdul Samad</title>
      <link>https://dev.to/iabdsam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/iabdsam"/>
    <language>en</language>
    <item>
      <title>comeback post</title>
      <dc:creator>Abdul Samad</dc:creator>
      <pubDate>Tue, 25 Aug 2026 07:48:35 +0000</pubDate>
      <link>https://dev.to/iabdsam/comeback-post-a1c</link>
      <guid>https://dev.to/iabdsam/comeback-post-a1c</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/iabdsam/giving-back-to-my-favorite-bookmarks-manager-making-it-better-for-everyone-513p" class="crayons-story__hidden-navigation-link"&gt;Contributing to one of my personal Bookmarks manager - and making it better for everyone&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
      &lt;a href="https://dev.to/iabdsam/giving-back-to-my-favorite-bookmarks-manager-making-it-better-for-everyone-513p" class="crayons-article__context-note crayons-article__context-note__feed"&gt;&lt;p&gt;Summer Bug Smash: Clear the Lineup 🐛🛹&lt;/p&gt;

&lt;/a&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="/iabdsam" 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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F725667%2F803b9e47-9181-471b-b677-e156cb58e7f5.jpg" alt="iabdsam profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/iabdsam" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Abdul Samad
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Abdul Samad
                &lt;a href="/++"&gt;&lt;img alt="Subscriber" class="subscription-icon" src="https://assets.dev.to/assets/subscription-icon-805dfa7ac7dd660f07ed8d654877270825b07a92a03841aa99a1093bd00431b2.png"&gt;&lt;/a&gt;
                
              
              &lt;div id="story-author-preview-content-4471407" 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="/iabdsam" 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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F725667%2F803b9e47-9181-471b-b677-e156cb58e7f5.jpg" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Abdul Samad&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/iabdsam/giving-back-to-my-favorite-bookmarks-manager-making-it-better-for-everyone-513p" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Aug 24&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/iabdsam/giving-back-to-my-favorite-bookmarks-manager-making-it-better-for-everyone-513p" id="article-link-4471407"&gt;
          Contributing to one of my personal Bookmarks manager - and making it better for everyone
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devchallenge"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devchallenge&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/bugsmash"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;bugsmash&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/opensource"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;opensource&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/productivity"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;productivity&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/iabdsam/giving-back-to-my-favorite-bookmarks-manager-making-it-better-for-everyone-513p" 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/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;5&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/iabdsam/giving-back-to-my-favorite-bookmarks-manager-making-it-better-for-everyone-513p#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              2&lt;span class="hidden s:inline"&gt;&amp;nbsp;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;
            9 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>opensource</category>
      <category>softwaredevelopment</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Contributing to one of my personal Bookmarks manager - and making it better for everyone</title>
      <dc:creator>Abdul Samad</dc:creator>
      <pubDate>Mon, 24 Aug 2026 04:37:10 +0000</pubDate>
      <link>https://dev.to/iabdsam/giving-back-to-my-favorite-bookmarks-manager-making-it-better-for-everyone-513p</link>
      <guid>https://dev.to/iabdsam/giving-back-to-my-favorite-bookmarks-manager-making-it-better-for-everyone-513p</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/bugsmash"&gt;DEV's Summer Bug Smash: Clear the Lineup&lt;/a&gt; powered by &lt;a href="https://sentry.io/" rel="noopener noreferrer"&gt;Sentry&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This is a submission for &lt;a href="https://dev.to/bugsmash"&gt;DEV's Summer Bug Smash: Smash Stories&lt;/a&gt; powered by &lt;a href="https://sentry.io/" rel="noopener noreferrer"&gt;Sentry&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Background
&lt;/h2&gt;

&lt;p&gt;When I first got to know about this bugsmash challenge, I was like I only have a few decent projects, and it was amusing to revisit the long forgotten repos and searching for any fix or optimization I could do.&lt;br&gt;
The focus shifted on the opensource software that I personally use (confidence). Fortunately, Canonical and Gnome have an amazing community and patch the interesting issues promptly.&lt;/p&gt;

&lt;p&gt;So, this was not happening, until I revisited my current manager Chrome Bookmarks and the several old stashes on multiple other platforms I once used in search of a particular link saved long back. &lt;/p&gt;

&lt;p&gt;I found the link, and then decided to refactor all my managers and distribute data among them for future ease. &lt;/p&gt;

&lt;p&gt;Among the archived managers was Raindrop, which had a decent volume. So, I installed its open-source desktop app to refactor, but found this.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdtms5z393u3xnvqx2g48.gif" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdtms5z393u3xnvqx2g48.gif" alt=" " width="376" height="61"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The native app was refreshing at every action. I quickly turned off the net, and yes, it was unusable. A disappointing limitation for my personal use case.&lt;/p&gt;

&lt;p&gt;Or maybe I can fix the issue myself and make it better for everyone...&lt;/p&gt;

&lt;p&gt;Here I am, having opened the PR and trying to write an intrigue.&lt;br&gt;
.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started ✦
&lt;/h2&gt;

&lt;p&gt;How does someone who is now more into ideas and less into code from last few months, quickly understand a codebase written by someone else.&lt;br&gt;
The one thing I follow when working on open source is to work within the scope. Hence, I didn't put my time into understanding the code first, since I had no extra stake in it. &lt;br&gt;
Got the code into antigravity app for linux from the start.&lt;br&gt;
.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's up
&lt;/h3&gt;

&lt;p&gt;Initial thought was that I would store loaded bookmarks into some storage in the desktop (from my perspective there was no storage at all on client side), so opened the source code of desktop with webapp submodule.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6etahc6dq8d346snmq5j.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6etahc6dq8d346snmq5j.png" alt=" " width="790" height="118"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I asked for opinions and ways to store the bookmarks while the refreshed data gets fetched (not a true cache but not my decision to make either).&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxvpbaobfgl2ffho6e94a.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxvpbaobfgl2ffho6e94a.png" alt=" " width="790" height="137"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and surprise&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu9sxnu86wgxefu8h3fmt.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fu9sxnu86wgxefu8h3fmt.png" alt=" " width="790" height="90"&gt;&lt;/a&gt;&lt;br&gt;
.&lt;/p&gt;

&lt;h3&gt;
  
  
  Visual Deception
&lt;/h3&gt;

&lt;p&gt;The cache is there according to this, but then is it not working? Reading more in the response, the subheading was Collections. I again checked the behavior, and saw I had no collections after I had deleted them for refactor and was navigating in sidebar filters only.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn7ix6a1klr4bp6qnqo8o.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn7ix6a1klr4bp6qnqo8o.png" alt=" " width="307" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Collection pages were indeed cached. Moreover, report told me that the whole logic was in the webapp repo, and not the desktop wrapper.&lt;/p&gt;

&lt;p&gt;This time I did carefully read the architecture report. Skimmed through some code as well and switched active directory to webapp repo.&lt;/p&gt;

&lt;p&gt;Deeply tested out the behavior, and gave the revised query.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F86ex2pe8xk07ga9o1zsi.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F86ex2pe8xk07ga9o1zsi.png" alt=" " width="790" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;thankfully&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your inference is correct. Here’s the precise mechanism.....&lt;/p&gt;
&lt;/blockquote&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk4xxe1ky20u5e27vtymw.jpeg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk4xxe1ky20u5e27vtymw.jpeg" alt=" " width="150" height="150"&gt;&lt;/a&gt;&lt;br&gt;
.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pointing the Pin
&lt;/h3&gt;

&lt;p&gt;Webapp's bookmark cache is a KV store keyed by the first route segment: state.bookmarks.spaces[spaceId].&lt;/p&gt;

&lt;p&gt;Collections get their own id &lt;strong&gt;collectionId&lt;/strong&gt; key, but every non-collection route -&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;all-bookmarks&lt;/li&gt;
&lt;li&gt;every filter&lt;/li&gt;
&lt;li&gt;every tag&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;collapses onto the single key &lt;strong&gt;'0'&lt;/strong&gt;. So bookmarks list of  &lt;code&gt;/my/0/type:article&lt;/code&gt; and &lt;code&gt;/my/0/#nature&lt;/code&gt; overwrite each other on every switch.&lt;/p&gt;

&lt;p&gt;Raised the issue at &lt;a href="https://github.com/raindropio/app/issues/253" rel="noopener noreferrer"&gt;#253&lt;/a&gt;&lt;br&gt;
.&lt;/p&gt;

&lt;h3&gt;
  
  
  I can't run this app?
&lt;/h3&gt;

&lt;p&gt;What do we do before making edits. We run the dev server.&lt;br&gt;
But we can't. Why? Because the repo is not configured for local usage. It relies heavily on original environment, and hardcodes.&lt;br&gt;
I went back and forth in another session, and could get the signup screen after editing a lot of files by myself too, but the api is apparently only configured to take auth requests from the deployed url only. It also never signed in to the local session.&lt;/p&gt;

&lt;p&gt;After learning so much about the code and getting so close to the solution, I was not ready to withdraw.&lt;/p&gt;

&lt;p&gt;Decided to have a second agent replace the visual review.&lt;br&gt;
Main session does the edits and commits them, a second (review agent) as adversary on the git diff (plus point if you can tune the jealousy-driven development).&lt;/p&gt;

&lt;p&gt;The first commit in PR is actually the final work of over 20 commits locally.&lt;br&gt;
.&lt;/p&gt;

&lt;h2&gt;
  
  
  Back and Forth
&lt;/h2&gt;

&lt;p&gt;(These are not exact prompts and results, but semantic partitions. The sequence is however intact. I am showing the &lt;strong&gt;most valuable&lt;/strong&gt; segments.)&lt;/p&gt;

&lt;p&gt;💬 &lt;strong&gt;Proposal&lt;/strong&gt;&lt;br&gt;
Since filters are predefined as links, articles etc. then why not assign negative keys, like -11 to -20, just like trash is assigned -99&lt;/p&gt;

&lt;p&gt;✦︎ &lt;strong&gt;Gemini Main Agent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pointed out that filters types come from api and are subject to change.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frzheiyotmzlevijhsep3.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frzheiyotmzlevijhsep3.png" alt=" " width="737" height="90"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[spaceId refers to the key used to query cache]&lt;/p&gt;

&lt;p&gt;👤 &lt;strong&gt;Me&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Focusing on these 2 points was the most important decision that saved a lot of compute and time. It also reminded me that this was not my codebase and I can't just make big changes.&lt;/p&gt;

&lt;p&gt;The whole logic of keys in cache is mirroring the routing decisions and is hence are coupled in the code too. This includes rehydration, updates, invalidation etc. As pointed earlier, the '0' comes from the first route segment of all these pages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Forces at work&lt;/strong&gt;&lt;br&gt;
spaceId is threaded through the entire bookmarks tree&lt;/p&gt;

&lt;p&gt;✦︎ &lt;strong&gt;Main Agent&lt;/strong&gt;&lt;br&gt;
suggests&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6cr6f0dpjlhirkqob7qr.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6cr6f0dpjlhirkqob7qr.png" alt=" " width="370" height="189"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👤 &lt;strong&gt;Me&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After a lot of back and forth, we agreed that '0' has to be kept the key or there would be too many changes to keep track of, in absence of a live preview.&lt;/p&gt;

&lt;p&gt;🌟 &lt;strong&gt;Instead, there would be multiple composite keys with the respective identifiers as suffix to '0' as shown in above response&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The clever idea is that when the consumer of this key is cache-related, then use the full composite key thus giving it a separate space in that flow. (remember these are keys, not indexes)&lt;/p&gt;

&lt;p&gt;When the consumer is not related to cache, mostly when directly fed in route as shown below, then use &lt;code&gt;parseInt&lt;/code&gt; to trim it to '0'&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv5x54zm68qjwprzlfxky.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fv5x54zm68qjwprzlfxky.png" alt=" " width="586" height="67"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This enables us to be compatible to opinions of existing logic, and also surgically apply our modification.&lt;/p&gt;

&lt;p&gt;👤 &lt;strong&gt;Me&lt;/strong&gt; again&lt;/p&gt;

&lt;p&gt;Decided to go only with filters and not tags. There were just too many bugs that could be introduced since tags are user defined and have their own flow of create and delete.&lt;/p&gt;

&lt;p&gt;Filters on the other hand are server defined and not editable. So, told Gemini my decision to do it only for filters.&lt;/p&gt;

&lt;p&gt;✦︎ &lt;strong&gt;Main Agent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Component where the key is passed down to all other consumers.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk1bd9njq2jfr4gxkeaft.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk1bd9njq2jfr4gxkeaft.png" alt=" " width="549" height="161"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That single prop becomes the cache key everywhere&lt;/p&gt;

&lt;p&gt;💬 &lt;strong&gt;Proposal&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pass a second prop &lt;code&gt;cacheId&lt;/code&gt; alongside an untouched &lt;code&gt;spaceId&lt;/code&gt;, then swap it in only where cache reads happen. Nothing else sees a changed value. Surely safe.&lt;/p&gt;

&lt;p&gt;✦︎ &lt;strong&gt;Main Agent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Audited every reachable consumer and argued against me.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2ot1q5eyext36xfz5hbd.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2ot1q5eyext36xfz5hbd.png" alt=" " width="766" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👤 &lt;strong&gt;Me&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I sorted consumers into three ways.&lt;br&gt;
Bucket 1 already calls parseInt&lt;br&gt;
Bucket 2 treats the value as an opaque string. &lt;br&gt;
Bucket 3, consumers interpolating spaceId raw into a URL: popover, info chips, "open in new tab" etc. Can Solve with with &lt;code&gt;parseInt(spaceId)||0&lt;/code&gt;&lt;br&gt;
(so all three can be handled)&lt;/p&gt;

&lt;p&gt;But right now all these use the &lt;code&gt;spaceId&lt;/code&gt; props, the consumers who are supposed to use the composite &lt;code&gt;cacheId&lt;/code&gt; prop may overlap in these, and may also pass them down in future where two different props for same route is being maintained.&lt;br&gt;
A lot of silent bugs can be introduced esp with improper documentation.&lt;/p&gt;

&lt;p&gt;Brainstormed through multiple suggestions and gave it my own, to modify the main key being passed down. Modifying it only when current route is a filter page.&lt;br&gt;
Told Gemini and it updated its plan with a hook and some refactors&lt;/p&gt;

&lt;p&gt;✦︎ &lt;strong&gt;Main Agent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Implements the plan&lt;/p&gt;

&lt;p&gt;Modified the passed prop with composite key&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcnju7z7tl7f4tcugfahh.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcnju7z7tl7f4tcugfahh.png" alt=" " width="800" height="80"&gt;&lt;/a&gt;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy6cww9x89hbz9wij1cp0.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy6cww9x89hbz9wij1cp0.png" alt=" " width="800" height="80"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Catching filter routes in a new file&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi19558vwdex9qjmnfqfl.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fi19558vwdex9qjmnfqfl.png" alt=" " width="800" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;👤 &lt;strong&gt;Me&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Added &lt;code&gt;parseInts&lt;/code&gt; to all consumers.&lt;br&gt;
Changed regex to &lt;code&gt;/^(?:[A-Za-z]+:[A-Za-z]+|❤️)$/&lt;/code&gt; as i didn't want to cache if filter was combined with a search query, for ex. &lt;code&gt;type:link &amp;amp; searchstring&lt;/code&gt;. Only pure routes should be cached.&lt;/p&gt;

&lt;p&gt;✦︎ &lt;strong&gt;REVIEW AGENT&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It is not fully correct. Composite cache keys are not integrated into mutation and refresh paths, producing stale or blank filter views.&lt;/p&gt;

&lt;p&gt;On deletion, status correction only processes numeric collection keys and bare &lt;code&gt;0&lt;/code&gt;, not &lt;code&gt;0:type:*&lt;/code&gt;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fptwb8xgonl08kbkulne3.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fptwb8xgonl08kbkulne3.png" alt=" " width="799" height="229"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Therefore &lt;code&gt;0:type:article&lt;/code&gt; can have zero bookmarks after deletion while retaining &lt;code&gt;status.main&lt;/code&gt; as &lt;code&gt;loaded&lt;/code&gt;. &lt;br&gt;
Instead of UI for empty bookmark list, the UI is of non-empty bookmark list but without bookmarks.&lt;/p&gt;

&lt;p&gt;👤 &lt;strong&gt;Me&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Confirmed that this is an introduced bug, and not already present. asked for list of status and their effects for reference.&lt;/p&gt;

&lt;p&gt;Tried to trace from where the above code gets data.&lt;/p&gt;

&lt;p&gt;One line in bookmark helper&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flstwmexdmlg51gchbgrc.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flstwmexdmlg51gchbgrc.png" alt=" " width="773" height="119"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and agent's comments on it&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhfd10s57hd5i403987p8.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhfd10s57hd5i403987p8.png" alt=" " width="795" height="154"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It parseInts. &lt;code&gt;0:type:article&lt;/code&gt; collapses back to &lt;code&gt;'0'&lt;/code&gt; before it is ever looked up. So even passing the composite key wouldn't have helped.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;iterateSpaceId&lt;/code&gt; was never taught to parse the key we created. Hence, the whole actualize/insert/remove helper family is blind to it.&lt;/p&gt;

&lt;p&gt;[Note the &lt;code&gt;parseInt&lt;/code&gt; here was not added by our previous work]&lt;/p&gt;

&lt;p&gt;🌟 &lt;strong&gt;Bonus Bug&lt;/strong&gt;&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftke08yhozrcnayumk5ro.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ftke08yhozrcnayumk5ro.png" alt=" " width="773" height="115"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The issue highlighted is related to the above discussed problem and will be fixed together. &lt;br&gt;
But, that last line was a genuine bug in the deployed app where bookmark was being added to current filter page irrespective of its filter type.&lt;/p&gt;

&lt;p&gt;Raised another issue for it at &lt;a href="https://github.com/raindropio/app/issues/255" rel="noopener noreferrer"&gt;#255&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💬 &lt;strong&gt;Proposal&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In bookmark helpers &lt;code&gt;iterateSpaceId&lt;/code&gt; function, the end goal is to pass the spaceId to &lt;code&gt;func&lt;/code&gt; callback. I asked Gemini if it could make this callback available to our composite key too.&lt;/p&gt;

&lt;p&gt;✦︎ &lt;strong&gt;Main Agent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now iterates over all filter keys, and calls &lt;code&gt;func&lt;/code&gt;, hence registers them for status correction listeners.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs9ibznngdf2sc9r5dxvb.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs9ibznngdf2sc9r5dxvb.png" alt=" " width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It may seem redundant to use the loop, but we are to avoid all edge cases and also call with one key only once.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;An Important Distinction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Additionally the fix pointed out that the blank case was not exactly our doing.&lt;br&gt;
The broken view code is not our edit. The switch in &lt;code&gt;empty/view.js&lt;/code&gt; traces to upstream Raindrop, untouched by edits. The missing case 'loaded': has always been there.&lt;/p&gt;

&lt;p&gt;But whether that gap was reachable is the part we changed. Earlier, every space a bookmark could live in was either in &lt;code&gt;action.spaceId&lt;/code&gt; or explicitly actualized. &lt;code&gt;loaded&lt;/code&gt; status with zero ids wasn't realistically reachable via removal. &lt;br&gt;
The unhandled case was a harmless impossible gap.&lt;/p&gt;

&lt;p&gt;👤 &lt;strong&gt;Me&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I accepted the edits, and also asked to apply defensive guards that mitigate against the existing gaps we discussed.&lt;/p&gt;

&lt;p&gt;✦︎ &lt;strong&gt;Main Agent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;loaded&lt;/code&gt; status comes into effect only if the bookmark array is empty (ideally should never reach here).&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F18feb4y8w0l25aboes6y.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F18feb4y8w0l25aboes6y.png" alt=" " width="799" height="109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the bookmark reducer's &lt;code&gt;REMOVE&lt;/code&gt; case, the same case which calls the &lt;code&gt;iterateSpaceId&lt;/code&gt; with callback, added this line that sets &lt;code&gt;status&lt;/code&gt; to &lt;code&gt;empty&lt;/code&gt; if the cache has been emptied. &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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5pzxvynvr6lzu8knonqo.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5pzxvynvr6lzu8knonqo.png" alt=" " width="799" height="79"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thus we fixed a subtle bug that was present in upstream repo too.&lt;/p&gt;

&lt;p&gt;✦︎ &lt;strong&gt;Review Agent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It flagged a msjor issue in the AI flow.&lt;/p&gt;

&lt;p&gt;AI refresh remains pointed at raw &lt;code&gt;cId&lt;/code&gt; (0) rather than the visible cache ID (0:type:article), so it does not refresh a filter view after a tool changes bookmarks.&lt;/p&gt;

&lt;p&gt;The AI code calls &lt;code&gt;refresh(cId)&lt;/code&gt;, while the visible page reads &lt;code&gt;spaces['0:type:article']&lt;/code&gt;. Refreshing &lt;code&gt;cId&lt;/code&gt; neither fetches nor invalidates &lt;code&gt;0:type:article&lt;/code&gt;, therefore it does not fulfill the “next refresh” contract.&lt;/p&gt;

&lt;p&gt;👤 &lt;strong&gt;Me&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This was a real risk, we were finding downstream consumers of &lt;code&gt;cId&lt;/code&gt;/&lt;code&gt;spaceId&lt;/code&gt;, but then we were in the root of normal data flow of bookmarks.&lt;br&gt;
The Ai flows in header and page are detached and separate from above. (recent features).&lt;/p&gt;

&lt;p&gt;✦︎ &lt;strong&gt;Main Agent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It suggested strongly that the same &lt;code&gt;useMemo&lt;/code&gt; we used initially hook can be reused by moving to a new file. No need to undo any work.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5z9ieovw6g1gu6fquzgw.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5z9ieovw6g1gu6fquzgw.png" alt=" " width="800" height="298"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Changed original hook to import&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuqvwnlyj1jeav5fnk4xx.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fuqvwnlyj1jeav5fnk4xx.png" alt=" " width="800" height="76"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then in both AI flows which consume &lt;code&gt;cId&lt;/code&gt;, replace it with composite &lt;code&gt;spaceId&lt;/code&gt;.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkgpzc8hyox50rsa52zvn.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkgpzc8hyox50rsa52zvn.png" alt=" " width="793" height="50"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6h47b8o79ss2s3q2f2db.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6h47b8o79ss2s3q2f2db.png" alt=" " width="793" height="167"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;some more fixes here and there manually&lt;/p&gt;

&lt;p&gt;✦︎ &lt;strong&gt;Review Agent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Off you go&lt;/p&gt;

&lt;p&gt;👤 &lt;strong&gt;Me&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Off we go&lt;br&gt;
Raised the Pull Request &lt;a href="https://github.com/raindropio/app/pull/254" rel="noopener noreferrer"&gt;#254&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Issues&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/raindropio/app/issues/253" rel="noopener noreferrer"&gt;https://github.com/raindropio/app/issues/253&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/raindropio/app/issues/255" rel="noopener noreferrer"&gt;https://github.com/raindropio/app/issues/255&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Pull Requests&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://github.com/raindropio/app/pull/254" rel="noopener noreferrer"&gt;https://github.com/raindropio/app/pull/254&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Best Use of Google AI
&lt;/h2&gt;

&lt;p&gt;Included Above&lt;br&gt;
Model Used: Gemini 3.5 Flash mostly&lt;br&gt;
Antigravity&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>bugsmash</category>
      <category>opensource</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Devcycle Commerce - Live Sale and Simulation</title>
      <dc:creator>Abdul Samad</dc:creator>
      <pubDate>Mon, 23 Dec 2024 07:58:13 +0000</pubDate>
      <link>https://dev.to/iabdsam/devcycle-commerce-live-sale-2epg</link>
      <guid>https://dev.to/iabdsam/devcycle-commerce-live-sale-2epg</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/devcycle"&gt;DevCycle Feature Flag Challenge&lt;/a&gt;: Feature Flag Funhouse&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I had the aspiration to build an application with a genuine use-case of feature flags rather than a replacement of backend. This application is a theoratical blend of various services.&lt;/p&gt;

&lt;p&gt;The first-person view is of a CEO/Sales-Admin of a medium size fashion startup who are organising a single day sale of, say, New Year Eve. The company has made presence in around 6-7 countries and planning to have the sale in each of them on the specified day.&lt;/p&gt;

&lt;p&gt;The application has overall 4 components, the frontend and backend serve their  usual purpose, while a dashboard is plugged with them, that gets data in the form of metrics, clicks, usage and other terms of the sales data world. The dashboard is supposed to be used by the Sales Admin of the company who can then use the various features of dashboard to make informed decision about the correct flags for the application. A simulation mimicking the same is present on dashboard.&lt;/p&gt;

&lt;p&gt;A schedule is created on the dashboard based on timezones of various countries to activate the sale variable only when the eve arrives in their timezones.&lt;/p&gt;

&lt;p&gt;For the countries that now have an active sale, various actions can be performed from the dashboard based on insights and metrics.&lt;/p&gt;

&lt;p&gt;I have deployed the website, with different combinations of variations in different country. I have also deployed the dashboard separately.&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/AkhVOw_44NY"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Cases
&lt;/h3&gt;

&lt;p&gt;For ex, lets say company get the complaint that the experimental chatbot is using rude language. The admin can then toggle the &lt;code&gt;chatbot&lt;/code&gt; variable off.&lt;/p&gt;

&lt;p&gt;Or The products being recommended on recommend page are not being picked in cart and even leading to mid-process abandonment, then &lt;code&gt;recommend-page&lt;/code&gt; variable can be turned off.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Suppose, that after reaching cart (any layout - sheet or page), there is high cart abandonment due to high total cost, then the admin can increase the &lt;code&gt;shipping-waiver&lt;/code&gt; level that will be utilized on both frontend (to display the promotional banner of waiver) and backend (to calculate the discount on shipping).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is the chance to have different variations for different countries based on historical metrics and one of the benefits of the data structures that I have used to store and track the state of devcycle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Feature Flags
&lt;/h3&gt;

&lt;p&gt;The application consists a total of 5 features and 7 variables.&lt;/p&gt;

&lt;p&gt;The variables are as follows and affect specific parts of the UI and backend&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;sale-status&lt;/code&gt; (frontend, backend) states whether sale is active in the current user region. A prerequisite for other flags.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sort-strategy&lt;/code&gt; (backend) variable contains the strategy for sorting the categories order on home page and the order of products in them.
For ex. "profit" strategy would display first the category and products with maximum margins to the company.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;recommend-strategy&lt;/code&gt; (backend) variable also has the same values of strategies but it is used when recommending products to the user on recommend page. For ex. "stock" would mean that encourage the user to buy overstocked items. &lt;code&gt;recommend-strategy&lt;/code&gt; and &lt;code&gt;sort-strategy&lt;/code&gt; are part of same feature with variations such as &lt;code&gt;profit-aggressive&lt;/code&gt; and &lt;code&gt;stock-aware&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;chatbot&lt;/code&gt; (frontend) variable toggles an experimental ai chatbot on the website, developed just-in-time for the sale.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cart-page&lt;/code&gt; (frontend) variable toggles the new experiemntal cart layout which involves a dedicated cart page rather than currently-used sidesheet.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;recommend-page&lt;/code&gt; (frontend) variable toggles an experimental recommend page before the cart page. It only works when cart-page variable is &lt;code&gt;true&lt;/code&gt; hence part of the same feature called &lt;code&gt;cart-interface&lt;/code&gt; on devcycle.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shipping-waiver&lt;/code&gt; (frontend, backend) variable specifies the degree of waiving off of shipping fees. Products on the website have free shipping, in-house shipping and third-party shipping. Banners are toggled on the UI and cart layouts (both sheet and page) about the promotion.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The entire reference of all features/variables/variations is available on both website and dashboard. &lt;br&gt;
The website features the current variations and variable values used in that region.&lt;br&gt;
Since dashboard is for admin, it features the current state for all countries at one place.&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%2F1l8c4scme4404q9rhtvx.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%2F1l8c4scme4404q9rhtvx.png" alt=" " width="800" height="515"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Dashboard
&lt;/h3&gt;

&lt;p&gt;On the dashboard, there is a control pane and simulation pane. The control pane is like the devcycle platform custom-built for the application. The simulation pane gives an opportunity to experience the use-case of this application in first person. It mimics insights and metrics that may well be there in a company and a control flow that can be played with as long as the timer runs. &lt;/p&gt;

&lt;h3&gt;
  
  
  Simulation
&lt;/h3&gt;

&lt;p&gt;The dashboard has the control pane which is like custom-made devcycle dashboard and a simulation pane.&lt;/p&gt;

&lt;p&gt;A simulation mimicking the scenario of live-sale is added to the dashboard with carefully-made flow control of what may actually come in real experience.&lt;br&gt;
The game utilises charts and a stream of queries (or insights) which provides actionable suggestions like changing the feature flag to enhance the customer experience.&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%2Fntn5754vkdynoiqojkw3.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%2Fntn5754vkdynoiqojkw3.png" alt=" " width="779" height="543"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Local
&lt;/h3&gt;

&lt;p&gt;The website is deployed with my account credentials and various countries have various variations demonstrated.&lt;/p&gt;

&lt;p&gt;Navigating to different countries will give a different combination of feature flags and can be checked on "Flag State" dialog button&lt;/p&gt;

&lt;p&gt;Both website and dashboard can be setup locally and information is on the readme page of repo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Website: &lt;a href="https://devcycle-commerce.vercel.app" rel="noopener noreferrer"&gt;https://devcycle-commerce.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Dashboard: &lt;a href="https://devcycle-dashboard.vercel.app" rel="noopener noreferrer"&gt;https://devcycle-dashboard.vercel.app&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Repo: &lt;a href="https://github.com/mr-loop-1/devcycle-commerce" rel="noopener noreferrer"&gt;https://github.com/mr-loop-1/devcycle-commerce&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Prize Categories
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;API All-Star&lt;/strong&gt;: Awarded to a project that shines by making full use of the DevCycle API— showcase creativity and capability through effective integration!&lt;/p&gt;

&lt;h2&gt;
  
  
  My DevCycle Experience
&lt;/h2&gt;

&lt;p&gt;I heard about feature flags for first time through this hackathon itself and right after learning about them, I realized how such on-the-go onfiguration was needed in many places of my past projects.&lt;/p&gt;

&lt;p&gt;The inspiration to built this app came from the &lt;code&gt;sale&lt;/code&gt; flag only, that it can be scheduled for different timezones which was something I thought backend would have a hard time at since it involved showing a different UI too.&lt;/p&gt;

&lt;p&gt;This project was the first where I made my own context and reducer in react. It also has the most complex state management by far that I have written. The first time I have visualized data using charts and learnt a lot about reacharts library.&lt;/p&gt;

&lt;p&gt;This is also the first time I have made a game, let alone making it playable and I am quite happy with the way it turned out to be.&lt;/p&gt;

&lt;p&gt;I look forward to have more interaction with Devcycle's software and community.&lt;/p&gt;

&lt;p&gt;One thing I liked about devcycle dashboard is the powerful API and the readymade hooks that made the integration very seamless.&lt;/p&gt;

&lt;p&gt;I also realized that need of conditional flagging where my &lt;code&gt;recommedn-strategy&lt;/code&gt; variable is only relevant when &lt;code&gt;recommend-page&lt;/code&gt; is true. I will submit this feature request after finishing the app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenges
&lt;/h3&gt;

&lt;p&gt;I am happy that I was able to navigate through the various APIs and create a way to mimic the dashboard while keeping up with the complex data structures used to set and update feature flags for various time-zones. The biggest challenge was to update the target after storing the variation_ids.&lt;/p&gt;

&lt;p&gt;The biggest time-consumer was the self-development of both apps from ground up as I wanted the app to behave a specific way.&lt;/p&gt;

&lt;h3&gt;
  
  
  Simulation Panel
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The dashboard was planned to involve a 1-minute simulation of a live sale, with players playing as the sales manager of the website and changing feature flag variations based on live insights from various sales teams and metrics.&lt;br&gt;
I will try to complete the panel very soon, even if it doesn't get evaluated as I already have the components made and need to piece together the flow of the game.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I added the simulation panel.&lt;/p&gt;

&lt;h3&gt;
  
  
  Images
&lt;/h3&gt;

&lt;p&gt;The architecture of the application system&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%2Fqh646lclg5fosjpr1v5g.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%2Fqh646lclg5fosjpr1v5g.png" alt=" " width="800" height="692"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;insights on dashboard simulation&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%2Fsdm2y5qotn3ee9mfnb30.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%2Fsdm2y5qotn3ee9mfnb30.png" alt=" " width="779" height="896"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Live Flag state&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%2Fzo6397v7i3gk8jvz1jen.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%2Fzo6397v7i3gk8jvz1jen.png" alt=" " width="800" height="677"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Separate Cart Page with Full Discount banner&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%2F0k9c5ti9yk4t55umt0bh.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%2F0k9c5ti9yk4t55umt0bh.png" alt=" " width="800" height="526"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Normal Cart Sheet with same banner&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%2F3mrdzcbbc5hzh1w8gwny.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%2F3mrdzcbbc5hzh1w8gwny.png" alt=" " width="800" height="760"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;products with varying degree of discounts&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%2Fnvs5duh737ydbcjfxgx1.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%2Fnvs5duh737ydbcjfxgx1.png" alt=" " width="800" height="515"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;insight history in simulation&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%2Flic3chnq25cg1bly0cin.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%2Flic3chnq25cg1bly0cin.png" alt=" " width="779" height="543"&gt;&lt;/a&gt;&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%2Fb41bl98kvbz066edhfc1.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%2Fb41bl98kvbz066edhfc1.png" alt=" " width="431" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Reference of all features&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%2Fj1p3037qh5ilooj2ip85.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%2Fj1p3037qh5ilooj2ip85.png" alt=" " width="800" height="773"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>devcyclechallenge</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
    <item>
      <title>Pinata Filesystem and PinDrop</title>
      <dc:creator>Abdul Samad</dc:creator>
      <pubDate>Mon, 14 Oct 2024 06:53:26 +0000</pubDate>
      <link>https://dev.to/iabdsam/pinata-filesystem-and-pindrop-1a0h</link>
      <guid>https://dev.to/iabdsam/pinata-filesystem-and-pindrop-1a0h</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/pinata"&gt;The Pinata Challenge &lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Pinata Filesystem and PinDrop acts as a layer on top of Pinata's storage system that allows users to organise and visualise their files using folders and sub-folders.&lt;/p&gt;

&lt;p&gt;It provides an interface and at the same time extends the features of Pinata. The users can associate files with folders, as well as do most of the general functions like creating, deleting and downloading files and folders.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inspiration
&lt;/h3&gt;

&lt;p&gt;I had instantly decided to make a fast private file sharing system right on first day of hackathon since it is something I myself needed. But the idea had to be dropped since their was too much to be done. &lt;/p&gt;

&lt;p&gt;Fast forward to 1 day before deadline, I thought about leveraging the feature of groups. I could make use of a relational db to create a heirarchy through self-references and make it a full-fledged platform to store and organise files.&lt;/p&gt;

&lt;p&gt;Thankfully, with no-sleep development constantly for 24 hours, I present the first version of Pinata's own filesystem.&lt;/p&gt;

&lt;h4&gt;
  
  
  Pindrop folder
&lt;/h4&gt;

&lt;p&gt;There is a feature called PinDrop (inspired from AirDrop) that I have ideated which is supposed to be a go-to folder that is present by default in the system when a user registers. &lt;br&gt;
This folder is special in that it doesn't have sub-folders, instead a user can simply push and stack files and retreive them later. This is supposed to be for instant file shares between the user's two devices. It can even have its dedicated service and routes going forward.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://pinata-fs.vercel.app/" rel="noopener noreferrer"&gt;https://pinata-fs.vercel.app/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/mr-loop-1/pindrop" rel="noopener noreferrer"&gt;https://github.com/mr-loop-1/pindrop&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;h4&gt;
  
  
  For Future
&lt;/h4&gt;

&lt;p&gt;The best thing about the database is that nothing about actual files is being stored. It is only a hierarchical representation of groups.&lt;br&gt;
Currently it may seem redundant as the app asks for jwt and gateway on register but I got to know through discord that new auth provider is being developed and with that integrated, the app would be completly detached from actual user data.&lt;/p&gt;

&lt;h3&gt;
  
  
  tech stack
&lt;/h3&gt;

&lt;p&gt;server: expressjs, knexjs, mysql, hosted on railway&lt;br&gt;
frontend: vite react, tailwind, hosted on vercel&lt;/p&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The first greetings are the login/register pages. During registration, a valid pinata jwt and gateway url need to be provided. But it will never be exposed on client side and only for server operations.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This is the root folder mounted at "~/". All other folders are supposed to derive from here. In pinata, this group is created when a user first signsup.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&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%2Fgw8g751ndy3beosgwg6b.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%2Fgw8g751ndy3beosgwg6b.png" alt=" " width="712" height="763"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Supported file types can be added using the Add File button in any folder. The file then gets added to the folder's group in pinata&lt;/li&gt;
&lt;/ol&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%2Fkfm12tsmboza719sem44.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%2Fkfm12tsmboza719sem44.png" alt=" " width="715" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Similarly, except in pinDrop folder at root, new folders can be created anywhere.&lt;/li&gt;
&lt;/ol&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%2Fvoh9geatqctoqf3dwrsh.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%2Fvoh9geatqctoqf3dwrsh.png" alt=" " width="706" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clicking on a folder will navigate to it, a back button has been provided to navigate to previous folder. For navigating to root, remove the id param from url.&lt;/li&gt;
&lt;/ol&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%2Fw81nb6doczgdrus8869m.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%2Fw81nb6doczgdrus8869m.png" alt=" " width="706" height="415"&gt;&lt;/a&gt;&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%2Feyrpfdf75vytfqk0xrxp.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%2Feyrpfdf75vytfqk0xrxp.png" alt=" " width="706" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Files and folders can be deleting using the button provided on right. pinDrop folder can't be deleted, as is root.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Files can be opened in new tab using the download button provided. This is done through signed urls with expiry of 1 minute.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;&lt;a href="https://github.com/mr-loop-1/pindrop" rel="noopener noreferrer"&gt;https://github.com/mr-loop-1/pindrop&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;instructions to run locally are provided. Please report any bugs/questions in comments or github issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  More Information
&lt;/h2&gt;

&lt;p&gt;Please ensure&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Folder names can't contain spaces&lt;/li&gt;
&lt;li&gt;Duplicate files/filenames can't be uploaded even in different folders as on pinata they are stored together&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Way Forward
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;downloading multiple files and whole folders&lt;/li&gt;
&lt;li&gt;currently delete feature of folder leaves files in subfolders dangling. i am yet to implement the query in knex as well as Pinata's sdk for recursive deletes.&lt;/li&gt;
&lt;li&gt;some bug fixes and field validations&lt;/li&gt;
&lt;li&gt;Currently, it requires user to manually provide jwt and gateway of their pinata accounts. I want to integrate the future pinata oauth provider to the app.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>pinatachallenge</category>
      <category>webdev</category>
      <category>api</category>
    </item>
    <item>
      <title>Metro Rail Path Finder</title>
      <dc:creator>Abdul Samad</dc:creator>
      <pubDate>Thu, 13 Jan 2022 22:53:26 +0000</pubDate>
      <link>https://dev.to/iabdsam/metro-rail-path-finder-2o3k</link>
      <guid>https://dev.to/iabdsam/metro-rail-path-finder-2o3k</guid>
      <description>&lt;h3&gt;
  
  
  Overview of My Submission
&lt;/h3&gt;

&lt;p&gt;I made an &lt;strong&gt;Express application which basically calculates the path from one station to another in a particular city's Metro rail map.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It connects to the database on Mongodb Atlas. My database has collections based on maps of different cities.&lt;br&gt;
The express app passes the User-preferences over to functions that query the database to find the route.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The app is very easily scalable&lt;/strong&gt;, as to add a map, one only has to add a new collection in the database (containing Station names etc) and one option in the "Map Select" drop-down.&lt;br&gt;
Everything else, including the functions and the drop-downs are designed to get updates from the database itself.&lt;/p&gt;

&lt;p&gt;Here is the link to my &lt;a href="https://github.com/mr-loop-1/metro-path-mongodb/"&gt;Github repository&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Submission Category:
&lt;/h3&gt;

&lt;p&gt;Choose Your Own Adventure&lt;/p&gt;
&lt;h3&gt;
  
  
  Link to Code
&lt;/h3&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mr-loop-1"&gt;
        mr-loop-1
      &lt;/a&gt; / &lt;a href="https://github.com/mr-loop-1/metro-path-mongodb"&gt;
        metro-path-mongodb
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      My Mongodb Atlas Project for Devto+Mongodb Hackathon
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;h1&gt;
metro-path-mongodb&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;Note: The Mongodb database may refuse to connect sometimes. I am finding a fix for that&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is a Metro Rail Path Finder app I made for Dev.to + MongoDb Atlas Hackathon. It sources its data from Mongodb Atlas Database.&lt;/p&gt;
&lt;p&gt;Technology Used: Expressjs, MongoDb Atlas&lt;/p&gt;
&lt;h2&gt;
To run the app&lt;/h2&gt;
&lt;p&gt;Just make sure that node and npm are installed and&lt;/p&gt;
&lt;div class="snippet-clipboard-content position-relative overflow-auto"&gt;&lt;pre&gt;&lt;code&gt;npm start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;And it will be deployed on &lt;code&gt;http://localhost:3000/users/details&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The calculation may get slow for longer paths.&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mr-loop-1/metro-path-mongodb"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;h3&gt;
  
  
  Screenshots
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HnUrDAsi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9snw17frob02mmw5bsqs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HnUrDAsi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9snw17frob02mmw5bsqs.png" alt="mm" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--onmJfqDL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t9pwusvwamp7mqwr2m08.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--onmJfqDL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/t9pwusvwamp7mqwr2m08.png" alt="ss" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Additional Resources / Info
&lt;/h3&gt;

&lt;p&gt;Technology Used: Express, Mongodb, Atlas&lt;br&gt;
Contact: &lt;a href="mailto:iabdulsamad1412@gmail.com"&gt;iabdulsamad1412@gmail.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>atlashackathon</category>
    </item>
    <item>
      <title>Writing your first Client-Server Program Quickly!</title>
      <dc:creator>Abdul Samad</dc:creator>
      <pubDate>Thu, 04 Nov 2021 06:32:28 +0000</pubDate>
      <link>https://dev.to/iabdsam/writing-your-first-client-server-program-5a0b</link>
      <guid>https://dev.to/iabdsam/writing-your-first-client-server-program-5a0b</guid>
      <description>&lt;p&gt;Your College Professor asked you to prepare a basic client-server program for the networks lab next week or maybe you are yourself starting Socket programming, what's better than writing the first program and learning along that. &lt;/p&gt;

&lt;h2&gt;
  
  
  The quick theory
&lt;/h2&gt;

&lt;h3&gt;
  
  
  what is a socket ?
&lt;/h3&gt;

&lt;p&gt;well, its (an integer and) a file descriptor through which we do our desired communication.&lt;/p&gt;

&lt;h3&gt;
  
  
  what does communication looks like ? (important)
&lt;/h3&gt;

&lt;p&gt;Server - &lt;strong&gt;&lt;code&gt;Bind()s&lt;/code&gt;&lt;/strong&gt; socket to an address and port, this socket then &lt;strong&gt;&lt;code&gt;listen()s&lt;/code&gt;&lt;/strong&gt; for incoming, then &lt;strong&gt;&lt;code&gt;accept()s&lt;/code&gt;&lt;/strong&gt; the incoming request (from client).&lt;/p&gt;

&lt;p&gt;Client - &lt;strong&gt;&lt;code&gt;Connect()&lt;/code&gt;s&lt;/strong&gt; your socket via local address and port for a &lt;strong&gt;&lt;code&gt;listen()&lt;/code&gt;ing&lt;/strong&gt; socket to &lt;strong&gt;&lt;code&gt;accept()&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  what happens after connect() and accept() ?
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;accept()&lt;/code&gt; returns a new socket to be used for communicating to that particular accepted client.&lt;br&gt;
In client side, the same socket used to &lt;code&gt;connect&lt;/code&gt; is used to communicate.&lt;br&gt;
now you can &lt;code&gt;send()&lt;/code&gt; and &lt;code&gt;recv()&lt;/code&gt; from both sides.&lt;/p&gt;

&lt;p&gt;What is the first thing that you need? &lt;strong&gt;Headers!&lt;/strong&gt;&lt;br&gt;
We will be using the following&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;string.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;sys/socket.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
#include&lt;/span&gt; &lt;span class="cpf"&gt;&amp;lt;arpa/inet.h&amp;gt;&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lets build both sides one-by-one&lt;/p&gt;

&lt;h2&gt;
  
  
  Server.c
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sockID1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PF_INET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SOCK_STREAM&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A stream socket has been created in PF_INET(internet) domain.&lt;/p&gt;

&lt;p&gt;Now, we have to bind our socket to an address and port. But, the &lt;code&gt;bind()&lt;/code&gt; function asks for one struct (of &lt;code&gt;sockaddr&lt;/code&gt; type) that has all that info. Instead we pass it &lt;code&gt;sockaddr_in&lt;/code&gt; casted to &lt;code&gt;sockaddr&lt;/code&gt; because it is more specific to our needs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;sockaddr_in&lt;/span&gt; &lt;span class="n"&gt;addrPort1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;addrPort1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sin_family&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AF_INET&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// sets IPv4&lt;/span&gt;
&lt;span class="n"&gt;addrPort1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sin_addr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;s_addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;htonl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;INADDR_ANY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;addrPort1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sin_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;htons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;//htonl - host to network long, htons - host to network short&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We filled the structure. Here, &lt;code&gt;INADDR_ANY&lt;/code&gt; automatically fills a default Ip address since we don't want to bind it to particular one.&lt;/p&gt;

&lt;p&gt;5200 is the port number that we will be using. You can use your own (make sure it is not reserved) (use the same in client).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sockID1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;sockaddr&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;amp;&lt;/span&gt;&lt;span class="n"&gt;addrPort1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addrPort1&lt;/span&gt;&lt;span class="p"&gt;))&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="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Bind Failed to Port 5200&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Bind Success to Port 5200&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Binded the socket, returns -1 if fails.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sockID1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Listen Failed&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Listening...&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we are ready to accept an incoming request (&lt;code&gt;connect()&lt;/code&gt; from client).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;sockaddr_in&lt;/span&gt; &lt;span class="n"&gt;client_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;socklen_t&lt;/span&gt; &lt;span class="n"&gt;len&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client_addr&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sockID2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sockID1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;sockaddr&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;amp;&lt;/span&gt;&lt;span class="n"&gt;client_addr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;len&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Accepted a connection&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is interesting. The only thing &lt;code&gt;accept()&lt;/code&gt; needs from our server is &lt;code&gt;sockID1&lt;/code&gt;. &lt;code&gt;client_addr&lt;/code&gt; will contain info about the client it accepts and will be filled on function call.&lt;/p&gt;

&lt;p&gt;This returns a new socket (&lt;code&gt;sockID2&lt;/code&gt;) for us which will be used for sending and recieving from the client.&lt;/p&gt;

&lt;p&gt;The last step.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;countR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;countS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strcmp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"Close&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"To Client : "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;fgets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;countS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sockID2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&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="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;strcmp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"Close&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"From Client : "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;countR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sockID2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&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="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&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;Try to understand this yourself. &lt;code&gt;countR&lt;/code&gt; and &lt;code&gt;countS&lt;/code&gt; are there for error handling (&lt;code&gt;send&lt;/code&gt; and &lt;code&gt;recv&lt;/code&gt; give -1 on error). &lt;strong&gt;Sending or recieving the word "Close" is the exit condition.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What are we trying to do? First message to be sent by server. Client then recieves it  and sends something. Server then recieves it and sends ...........&lt;/p&gt;

&lt;p&gt;Finally&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;    &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sockID1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sockID2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Socket connection Closed&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without scratching heads, lets move to client.c&lt;/p&gt;

&lt;h2&gt;
  
  
  Client.c
&lt;/h2&gt;

&lt;p&gt;After the headers&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;sockID1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;socket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PF_INET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SOCK_STREAM&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="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;sockaddr_in&lt;/span&gt; &lt;span class="n"&gt;addrPort1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;addrPort1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sin_family&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AF_INET&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//sets to IPv4&lt;/span&gt;
    &lt;span class="n"&gt;addrPort1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sin_addr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;s_addr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;htonl&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;INADDR_ANY&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;addrPort1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sin_port&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;htons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;//htonl - host to network long, htons - host to network short&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is same, because connection also requires the specifics of where and via-what to connect.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sockID1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;sockaddr&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;amp;&lt;/span&gt;&lt;span class="n"&gt;addrPort1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;sizeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;addrPort1&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Connect Failed&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="nf"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Connected via Port 5200&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nearly identical to &lt;code&gt;bind()&lt;/code&gt;. Right. But remember, it complements the &lt;code&gt;accept()&lt;/code&gt; function in the server side.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;countR&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;countS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;while&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;strcmp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"Close&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"From Server : "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;countR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;recv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sockID1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&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="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"%s"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&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="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;strcmp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"Close&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"To Server : "&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;fgets&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;stdin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;countS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sockID1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I hope its easier to see the logic now.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;    &lt;span class="n"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sockID1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;printf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Socket connection Closed&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Done.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Move to the directory. Split your terminal. In one, run the server, then on other run the client. Happy connection !&lt;/p&gt;

&lt;p&gt;I have tried to keep it as short as possible and only explain the things relevant to a first program.&lt;br&gt;
Questions &amp;amp; Suggestions are welcome.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>tutorial</category>
      <category>cpp</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
