Andrew Ashall | Full-Stack Developer

Personote - Free and Open Source Notebook Web App

JavaScript - 6th July 2017

Personote is a free and open source cloud based notebook web app with a focus on speed and simplicity. I created personote out of my frustration with existing web based notebooks, as I found the few I tested all felt slow and clunky. So I decided to build a tool that would fulfill my needs of fast loading, fast saving and simple.

A Bit of Background

I have been using evernote as both my work and personal notebook since around 2013 and have amassed roughly 5000 notes, admittedly most of these are now redundant or garbage but they are still there clogging up my views and making the whole experience slow. Using the evernote windows client on my work machine was starting to feel slow and it felt like finding notes was a chore and as evernote doesn't have an official linux client I found the web app mostly unusable except for in emergency situations.

I also tried NixNote2 but found this equally unusable as my changes weren't being saved or the server was overwriting my local changes.

Requirements

So I wanted a simple and fast web app with no frills, just text based notes. No folders as I found I was creating folders for any subcategory I could place a note in. No note tagging (I was a bit unsure of this in the beginning as it would provide a quick server based search approach but by using a logical naming system never really found myself needing to use tags as the react client side search works so well). Auto saving notes after edits, functionality to archive a note when its no longer relevant but contains useful info and delete to remove unneeded and created in error notes.

Design

I wanted to keep the design as minimal and distraction free as possible as I found myself using all the possible features in other cloud based notebooks which distracted me from focusing on the content of the Note.

Login Page

Open Note

Note Archive

Advanced Editor

the advanced editor adds buttons to insert LI tags for lists, code tags for code snippets and input tags for check boxes as I found these were the things I used most in evernote. As my note taking style has changed to a more minimal text only notes and as I use git for all my code, I haven't really used any of the advanced editor features but I think I'll leave them in just in case.

Tech Stack

After switching from meteor for web app development to react / redux / webpack / express etc. for 2017 I decided to try out inline styling with the goal of a 100% JavaScript app. For the database I used mongoDB but any DB can be switched out by tweaking the api.

I used redux for all front end data manipulation to reduce server gets. The only one get is used on loading the web app and more can be called to either load more or by refreshing the page.

How it works

On load an api call is sent to receive the latest 10 notes that were edited, this object array is then saved to the redux store. If the number of notes received is equal to 10 it sets the moreAvailable state to true which shows the click for more notes component which when clicked will fetch ALL non archived notes. (although I found having a limit of 10 notes is a great reminder for managing and the arching of notes, general readability and ability to find notes at a glance rather than having to use the search. it also speeds up the request and search).

When editing a note either a change or a key-press will start a 1 second timer and change the saved state to false, this changes the status component text to "changes not saved" if another change is made or key pressed the timer will restart. After the timer is up it will trigger the save note function which sets the saved state to "Saving...", create a body preview of the note by removing all tags and take a substring of the first 300 characters then send a post to the api with the notes new data. When an OK is received from the call it then finds the current note based on the _id in the notes redux store and update it with the new content of the notes component title, body and modified date states, when this is complete an action is called to update the notes array with the new array triggering the nav component to update with the new array of notes.

Learning

Initially I didn't want any fixed components but found as notes got longer I couldn't see when the note was saved so I changed to note controls to display as sticky.

Optimization - I really tried to keep the main.min.js file as small I as could to reduce the loading time, as of writing it is 318kb webpacked and 81.4kb downloaded through chrome and getting a balance of performance vs file size / loading times.

CSS isn't a must but it has a lot of handy features - I think for my apps going forward I'll try using less CSS (mainly for :hover :active :focus etc. as doing these in react pure JS can be a bit cumbersome but use in-line for fixed elements like containers to get the initial view structure)

Simplicity - I found myself adding a few optional feature e.g. advanced editor but found I rarely use this feature so in theory I could remove it and also reduce the file size and increase performance.

Check out the app at https://personote.herokuapp.com and the source on github.