The idea of Skypad came from my colleague, Howa. He threw out one of his random ideas in our office chats, “Why don’t you write Skypad like Firepad?”
Firepad is associated with Firebase, which is a serverless solution just like my company’s. After checking it out, I said, “That’s a little complex”. I didn’t like the style. I wanted something simpler — something a hacker would use.
I already had a full plate doing Oursky’s Playground side projects, so I knew if I didn’t do it that day, I’d forget about it. I never expected that this 2-hour late night project would make the Hacker News front page.
Below’s how I built it.
To get started, keep it simple
I started the project at 11pm after a night out and I rolled out the first version at around 1am. For the hosting, I enabled GitHub Page settings to host the static page from the GitHub repository directly since it would be open-source anyway.
My timeline was:
- 5 mins: Set up the Skygear Serverto take advantage of a serverless backend. I used the cloud database API for saving and fetching existing notes, and the pub/sub API for real time synchronization.
- 10 mins: Created a simple text area layout with MUI. I decided to use
<textarea>
for the user input area. - 20 mins: Implemented saving and loading a note.
- 30 mins: Made the real-time sync.
- 20 mins: Added a note public URL generation and add sharing options.
- 20 mins: Final touch ups and styling.
- 10 mins: Wrote up a betterREADME file for the GitHub repository.
15 mins: Setting up the Skygear server and downloading a CSS Framework.
I already have a free account for Skygear.io, which has a developer portal where I can just create a new app. Every new app will have its own API key and the portal has quick start guides (I used Web for JS). With my account, I can use any of the Skygear functions, but for this project I only needed to set up CloudDB and Pub/Sub (which takes 5 mins). You can sign up here follow the quick start.
As I mentioned, I used MUI for the frontend CSS framework. MUI uses Google’s Material Design guidelines and has sample layouts for blogs, e-mails, and landing pages.
20 mins: Implement saving and loading a note
1.Create a new note if the URL does not come with a note’s id:
// The code is ultra simple to create a new note function createNote() { var note = new Note({ content: "" }); return skygear.publicDB.save(note); }
2.If a user visits Skypad with a specified note id, Skypad will load back the existing note:
function loadExistingNote(noteId) { const query = new skygear.Query(Note); query.equalTo('_id', noteId); skygear.publicDB.query(query) .then(function(records) { if (records.length == 0) { flask.update( "// ❌ 404 not found.\n\nYou can create a new pad at " + config.baseURL<br /> ); return; } const note = records[0]; //We can then update the note content }, function(error) { console.error(error); }); }
30 mins: Make the real-time sync
I implemented synchronization using pubsub. The mechanism is simple: a client opening the note with id
aaa-bbb-ccc
subscribes to the channel note/aaa-bbb-ccc
. When there is an update on the note, the corresponding client publishes an event to the channel. If there are other viewers on the same note, they will get the update event with the latest content.
skygear.pubsub.publish('note/' + thisNote._id, { token: ramdomToken, content: content });
I’ve added a random token which binds to each client (you can imagine it as a unique tab id). So that the current client that initiate the update event won’t get into the infinite update loop.
20 mins: Add a note public URL generation and add sharing options
I added basic sharing for Skypad that includes a Facebook and Twitter share as well as a direct URL to the note. A sample note URL is: https://skygear-demo.github.io/skypad/#5e2fd94d-5d9d-4838-bd21-40db164f15ef where 5e2fd94d-5d9d-4838-bd21-40db164f15ef
is the ID of an existing note.
20 mins: Final touch ups and styling
After scaffolding the application logic, I went back to styling the app with the following:
- made the sharing option bar sticky at the bottom
- fixed the screen size being too small for mobile devices (even hack projects deserve to be mobile first!)
- fixed some CSS errors I had made
10 mins: Wrote up a better README file for the GitHub repository.
The updated README includes a features summary, demo link, setup and deployment guides, and credits to other open source libraries. *A good README is the key to communicating with users! *
By the way, I recommend using Toggle as a free time tracker.
For all the tasks and technical decisions I made, this was the only principle I remembered at midnight:
“Keep it simple, stupid”
I love great UI designs too, but it would have eaten into my coding time and also would have made the product more complicated. I just wanted to build something just for kicks.
Show HN.
And, since I finished, I figured there wasn’t anything to lose by sharing it on HackerNews before I hit the sack.
Also check out my company, Oursky’s, free developer tools and open source backend *that were made for developers!