DEV Community 👩‍💻👨‍💻

Cover image for ReMaking Twitter - Part 1
Code Something
Code Something

Posted on

ReMaking Twitter - Part 1

Looks like Twitter. Talks like Twitter. It must be Ghost Messenger.

Today I'm starting a special series of articles that will follow creation of an alternative social media app Ghost Messenger (here's it's twitter bio).

I call it ReMaking Twitter but the app is not entirely the same. Specifically in the area of algorhtms that will fuel its communication patterns. It's just a quick way to communicate that basically it's a social media app.

I started working on Ghost a year ago on domain name. Originally it was never meant to be a stand-alone messenger. Just a site for posting tech articles and generally to practice coding up a Node.js web server.

But as someone who already created social media platforms in the past (for fun and to learn how to code) many of the ideas that make Ghost what it is today have been marinated on for about a decade.

Minimum Required Features

Creating an app in the same niche as Twitter you will essentially be creating the same type of underlying tech because the first task is to build a set of Minimum Required Features (MRF) - which users expect you to have or they simply won't even consider to continue using your platform.

This need exists regardless of the type of app you're creating. People generally have high expectations from modern-day apps.

Bad UX is often why many good ideas fail. People don't want to guess where features are. They want posting to be easy. They want everything to be fast.

MVP vs MRFI don't like the term MVP because there is nothing minimum about an app that's capable of working successfully. MRF is a more realistic term because you are thinking of listing a complete granular set of features.

Now this isn't as easy as it sounds. Because in order to create MRF you need a thorough understanding of the needs in your product niche. This requires a vision & some passion for the project based on positive intent toward its users.

In contrast, to create an MVP (which is the way it's traditionally done nowadays) many rely on treating their app as a side project subservient to more important things in life (watching your favorite Netflix show, keeping a decent full time job in tech, taking care of children, etc.)

Timeline Flood & Dealing With Overposting

The mental spark I had starting this post was one particular feature I was working on that you will see both on Twitter and Ghost.

Imagine a user who just posted 10 tweets in a row.

There is nothing wrong with doing that.

But the consequence is that it floods the timeline.

This creates at least two problems:

  1. Boredom. Timeline audience gets bored, nobody wants to see 10 posts in a row from the same user.

  2. More isn't always more. The user who posted doesn't benefit much either. The attention is spread across 10 posts, rather than making 1 solid point in a single message. And it looks spammy.

Solution to Same User Flooding the Timeline

Why should this user get visibility of 10 or more posts in main timeline?

They shouldn't. Only their last post should be visible. The rest of the timeline should be flooded by posts made by all other users to be fair. But due to chronological nature of the timeline it's not as simple as simply removing all other posts by same user. Because other users might be tweeting in between any of that user's post too. And this special usecase needs to be preserved.

One way of doing this would be by reading only unique entries from a Mongo's tweet collection using Mongo's distinct() function. But it's not easy to use distinct() for timeline cleanse the way it's described in previous paragraph.

It's hard to make distinct() work in a way where while it returns only 1 post from the user who posted 10 posts in a row but retain their other posts on the timeline IF other users posted a tweet at any time between those tweets.

To do this right you're better off with simple forEach loop in JavaScript:

I use this code to filter the timeline and rid it from repeated posts.

/* Get all tweets from database */
const tweets = await getTweets()
/* Create the actual list that will be displayed on timeline */
let final = []
let previousUsername = ""
tweets.forEach(tweet => {
  if (previousUsername !== tweet.username)
  previousUsername = tweet.username

/* At this point final[] should contain a list
   of tweets without copius repeats */
Enter fullscreen mode Exit fullscreen mode

Basically the logic is: skip next tweet if previous one was posted by same user.

Funny side effect I noticed: If someone else manages to post a message in between of any of those 10 posts, then their post will be sandwiched between two most recent posts by the user who posted 10 messages in a row.

Get Ghost Messenger

Help test Ghost Messenger in its early stage.

You can become one of the earliest users on Ghost Messenger 🙂

Most usernames are still available so grab yours while it's still possible.

To install open it in Safari on iPhone and add it to Homescreen.

Image description

Ghost Messenger…in the flesh.

Top comments (0)


Thank you.

Thanks for visiting DEV, we’ve worked really hard to cultivate this great community and would love to have you join us. If you’d like to create an account, you can sign up here.