thaiWitter

thaiWitter was a web-based Twitter client that I have written back in 2009, when I was 16 years old.

It is one of my first project of considerable size (codebase is more than 7000 lines). It got several happy users who gave me a lot of great feedback for me to improve it. I felt really good about improving this project. They are mentioned in the Changelog page. Needless to say, this is one of the projects I’m most proud about.

But back at that time, I lacked software engineering skills. I just threw a bunch of things I learned into this project. So, the project becomes less maintainable, and eventually, I stopped maintaining it in 2013 due to its immense technical debt.

In 2018, I decided to open-source this project for posterity.

Source code on GitHubhttps://github.com/dtinth/thaiWitter3

https://github.com/dtinth/thaiWitter3/raw/master/docs/images/screenshot1.png

thaiWitter timeline view, showing a conversation thread (focusing on tweets related to the reply chain). The underlined username shows which tweet is being replied to.

Features

Here is a list of feature with some (edited/paraphrased) testimonials (text in brackets are my interpretations).

Super smooth

thaiWitter is designed to be lightweight and very responsive. It has a lot of user interface animations that works very smoothly. It can handle hundreds of tweets on the timeline without problems.

It has a handcrafted custom scrolling equation for the smoothest timeline scrolling experience in any Twitter client.

Translation: thaiWitter runs on Prism, an ancient technology, but it’s just the best Twitter client... (Mozilla Prism is discontinued since 2010, this tweet is in 2014.)
Translation: Some people asked me, “Isn’t it cumbersome to use Twitter on the web?” Answer: No! Because I use thaiWitter.
Translation: Temporarily switched to thaiWitter. This computer has a low spec and this is the smoothest client.

Real-time streaming

With Twitter Stream API, new tweets gets displayed instantly. This makes Twitter feel very much like a chat room, so you can keep on tweeting! Requires an extension to be able to do streaming.

Translation: I put thaiWitter on the side for chatting about TV dramas — even better than a chat room!
Translation: I just hit my API rate limit for the first time. Aww...
Translation: You couldn’t answer to tweets that fast because you are not using thaiWitter. I’m serious!
Translation: thaiWitter is so great for tweeting in bursts!

Simple dark theme

Designed for readability, I used a simple dark theme with a font that’s optimized for easy reading on screen (Verdana).

Translation: thaiWitter is easy on the eyes when you’re in the dark.
Translation: The Twitter client that’s easiest to “read” on is thaiWitter.

Natural reading flow

When you read books, you read from top-to-bottom. thaiWitter puts newer tweets at the bottom too, so you can follow the flow of the conversation in a natural way.

Translation: In the end I had to switch back to thaiWitter. It’s faster and it’s easier to read. (after switching to MetroTwit)

Keyboard based

You can tweet, favorite, reply, retweet, view threads, view images, and so on... all using keyboard.

Undo Tweet

Press Ctrl+Z after tweeting to delete it tweet and put the tweet text back into the input box.

Translation: Just made a mistake in last tweet. Thanks to thaiWitter’s Undo Tweet feature, I can fix it instantly.

Keyword Highlight

You can put in a list of keywords (or people), and they will be highlighted in blue.

Translation: “I like thaiWitter — it highlights the tweets from people I care about”

Custom CSS

Allows you to put your own CSS to customize the UI.

Other features

  • Desktop notifications — Get notified even when you’re working on something else.
  • Show Client — See who uses what to post to Twitter.
  • Auto Scrolling — Auto scroll to the bottommost tweet when loaded.
  • Image Preview — View images in tweets without leaving thaiWitter.
  • View Conversation — Press Shift+Enter on a tweet to view a conversation.
  • User/List Timeline — Press Ctrl+U and type in the username or username/list-slug to view it.
  • List Updates Timeline — Press Ctrl+U and type in the username/list-slug! to view only the latest tweet of each member in the list, sorted chronologically. Very useful if you have a list of your friends and want to see what they up to after you haven’t used Twitter for a while.
  • Retweeting — thaiWitter supports retweeting, years before Twitter finally implemented it. You can even retweet private tweet or even direct messages (but it will give you a warning.)
    • Mutated tweet (MT) — In Thai Twitter culture around that time, it’s common to retweet someone, but modify the text a bit for humorous effect. thaiWitter has a feature to track down the original tweet.
  • Mention Highlight — Tweets that mention your name will be highlighted in red.
  • Filter Keywords — Filter out some keywords from your timeline.
  • Hardcode Mode — Removes the top bar and tweet input area at the bottom (you have to remember the keyboard shortcut). Start typing to activate the tweet input box.
  • Smart Username Autocomplete — Completes the user name as you type. It uses an algorithm to determine who you might want to tweet to the most, and rank the suggestions accordingly.
  • Lots of easter eggs. Can you find them all?

https://github.com/dtinth/thaiWitter3/raw/master/docs/images/screenshot2.png

thaiWitter’s settings panel

Tech stuff

This project is developed from 2009 to 2013. Here are some interesting technical information:

Client

  • No 3rd party frontend framework. I manage all DOM elements manually, but this gave me complete control of DOM animations, which allowed me to optimize the performance as I wish. (Back at that time, it’s very hard to create smooth animations. CSS transitions and animations didn’t exist back then.) It can handle up to around 10,000 tweets while performing reasonably well, while many other Twitter clients would stutter severely when there are thousands of tweets.

    My thaiWitter window contains 6,666 tweets in the timeline but it’s still running smoothly.

  • 3rd party front-end libraries:

  • Self-written front-end libraries:

    • DtJS 2, a rewrite of DtJS, my web animation framework and utility functions for front-end programming in 2009 era. Provides change observer, DOM node generator, animation system, DOM utilities (element/scrolling/viewport size/position queries, events), AJAX, JSONP, and color manipulation.
    • twcs, thaiWitter Class System.
    • T.js, my utility library, provides function generators, JSON parser, change observer, digit padder, date formatter/parser, and tweet parser.
  • Frontend code is written in a custom compile-to-JS language, thaiJS, which adds classes (transpiles to twcs), method bindingprotected and private fields to JavaScript. The compiler is written in CoffeeScript and is 260 lines long.

    At first I thought this was a good idea. Back then there is not many JS tooling. JSHint was not released back then. So I only need to create a transpiler and Vim syntax file and that would be it.

    Nowadays, there are many tools like ESLint, Babel, and free modern IDEs that offers JavaScript IntelliSense. They won’t work with thaiJS.

  • 6000 lines of code in one file.

  • I even implemented support for touch scrolling in iOS 3.x, which required me to implement touch handling and momentum scrolling myself, as -webkit-overflow-scrolling didn’t exist yet.

  • No automated tests. This is one of the big reason I cannot keep maintaining this. As I add more feature and code gets more complex, I become less confident in changing code.

  • Lots of monkeypatching. To avoid changing old code, I try to adopt an approach where I don’t have to modify old code, but writing new code to patch old code at runtime. I thought it would be great. As it turned out, it leads to even harder maintenance.

  • No module system. Most stuffs are declared as global variables.

Server

  • Node.js based.
  • Development server with server module reloading on each refresh (no need to restart the server. Just save and refresh like PHP).
  • Self-written asset pipeline. On development, compile on the fly. On production, compile and save in memory, so that the whole app can be served without disk I/O.

thaiWitter’s more settings

thaiWitter’s zen mode where everything is hidden except the tweets

Screenshots

https://github.com/dtinth/thaiWitter3/raw/master/docs/images/screenshot4.png