This release was done on 2012-02-24 and handled the migration of the app from Heroku's bamboo stack, to the cedar stack.
This release was done on 2013-02-12, and patched the version of the rails gem to v3.2.12 in response to a security vulnerability.
This release was also done on 2013-02-09, and altered the site-wide message such that it would only appear if someone was logged in. Anonymous users could not possibly be affected by the changes in Google OAuth, so I made it so only logged users would be notified.
This patch was released on 2013-02-09. It was discovered that Google OAuth2 uids had changed from the users' email address to a unique integer. This meant that previous users who logged in both before and after Google made this change would lose their star-menu list, because that list is tied to your uid, which had changed.
I added a site-wide message to the top of the page that asked users to contact me if they weren't seeing things that they expected to see in their star menu, but it either didn't affect anyone else, or no one cared, because I didn't get any contacts of this sort.
This site-wide message was later removed in release 119, which was deployed earlier today.
The "canvas" theme is no more. It has been replaced with a theme called "light". That means that cortex has only two themes, light and dark, with the dark theme being the new default.
In other news...
In release 110 (not noted in this blog) I upgraded to Rails 3.2.11 in order to patch the two critical security bugs found in ActiveRecord and elsewhere. However, this update also broke the jQuery support, which broke the ability to drag-and-drop notes to reorder them.
As a result, in release 113 I applied a patch to jQuery to fix the drag-and-drop reordering problem.
I've got some bugs and exceptions to handle in my app currently, but none of them are critical, or even visible to the user, I believe. After 36 days of work, and 3 days of documenting it via this blog, I'm ready to break away from cortex for a couple of months, let it simmer, try to get some additional user feedback, and then I'll dive back in with another round of enhancements from users.
I hope this is been insightful for many people. The goal here, of course, is to give back to the open source community that has already given me so much value. While cortex certainly isn't a groundbreaking app, I feel that sharing what we do benefits everyone in the long run by giving us multiple examples and resources from which to learn.
The net effect of all this seems to be that the level of innovation in software just keeps accelerating. As far as I'm concerned, this is almost universally a good thing.
Adding to the work done in creating multiple themes, issue #34 added multi-layout support.
- 787a5f4 - Added 2x
- a3bfb75 - Added layout selector to the control bar.
- 79379b5 - Tweaked the layout to look exactly the way I wanted, and moved the layout-list image up by two pixels so that it would line up properly with everything else.
- fd29bfe - Refactored theme-selection code. Made it much simpler, following the [theme] selection code model.
- 21805a7 - Refined the list layout.
- f01f3ff - Refactored a couple of things with thoughts and effe… …cts, to make them consistent. Code cleanliness.
- 64ffbe8 - Tweaked a couple of layout things for consistency.
- bc79029 - Corrected the animation of new thought widths. Tweaked the list view to be more vertically dense.
- 8f20179 - Updated README
- 4f03452 - Updated README (again).
- 228de69 - Refactored a lot to get the new layout change and persistence functionality in place.
This commit started the final set of modifications necessary to get layout changes to apply across all clients.
Unlike visual theme, layout is brainstorming page specific. The reason is because the physical layout is more of a functional thing, while color scheme is a matter of personal preference. In terms of physical layout, when you're working on a list you want a list, and you want it to look that way for everyone.
- 09e204c - Fixes an issue where new ThoughtWalls were having their layout reset to an undefined value.
- 9fa1721 - Tweaked layout so that items in the list view will have their drag-and-drop targets set properly.
This commit fixed a problem where the size of the DOM elements on the page was too large, causing a though appearing later in the list to overlap the though just previous to it. This made drag-and-drop much more difficult, because it was too easy to grab the wrong thought box when you wanted to rearrange thing.
- f429f32 - Updated the
slideThoughtfunciton so that it would remove the style attribute from the thought being slid in, after the movement is complete. This prevents the strange width problems we were seeing. Also rebuild the assets for deployment.
And we're done with multi-layout support.
Omniauth is a great gem that makes adding 3rd party login support a breeze. It supports a ton of services, and is being improved all the time. I've used it on three apps in the past, so I was really able to get through this functionality pretty quickly.
The point of adding login functionality to what was previously a 100% anonymous app, was to allow users to build an in-app list of brainstorming pages that they wanted to save and go back to in the future. Before login was supported, it was absolutely possible to do this on your own, but it required you to bookmark the pages manually in your browser.
The in-app bookmarking (and login, for that matter) are controlled through the "star" menu in the upper-left corner of cortex's page layout.
CanCan users will notices that my authorization file allows managing of all assets for all users. This is intentional (since no one can edit user info currently, and cortex has always supported anonymous, free-flowing brainstorming for everyone).
In the future I plan to add functionality that allows users who "own" a brainstorming page to make it private if they choose, but for now realize that I'm fully aware that the app is wide open to editing, and that this is intentional. There are no actions exposed to the public that allow deletion/editing/viewing of users, or even deletion of
ThoughtWalls, so there should be no danger yet.
- 51a21a4 - Google login is supported by default at this point.
- 1d51a67 - Login and logout now works, with login buttons from https://github.com/intridea/authbuttons
- e429fdf - Added star menu hiding.
- 40ee9d0 - Rebuilt assets for deploy.
- f8533ff - Added a missing
endfor the authorization code.
Strangely, the missing
end wasn't throwing any errors in development, but it was failing on heroku - as it should.
This migration is what makes the star menu work - by creating the relationships between users and their in-app bookmarked brainstorming pages.
- 4cf63de - Removed some debugging messages, and took out the debug gem... Code cleanliness.
- e0eeed6 - Updated styling for the star action, and added supporting controller code to handle this.
- 68a27fd - Added code to list the starred items in the control bar menu. There are still a few things to be worked out.
- 21f0e71 - Adjusted the ordering of the items under the star menu, such that they are always in alphabetical order, ascending, ignoring case.
- 511cb79 - Made the login menu show up if the user clicks a star for a ThoughtWall, but isn't yet logged in. You cannot star a ThoughtWall if you aren't logged in.
- a1b0a06 - Fixed a bug where the page title was being improperly updated.
- aea521b - Fixed a bug where the login div would show up at a time that actually didn't make sense.
- f43d18f - Fixes the issue that items in the star menu didn't have their titles updated when the ThoughtWall title was changed in real time.
- 9a1a7b2 - Converted the list of starred pages from links separated by breaks, into a simple unordered list with the proper styling.
- 414bcf5 - Added code to make sure that when you star something, it's added to the star menu, and it's inserted into the correct position.
- 1e39138 - Rebuilt assets for deploy.
- 8859578 - Added a vertical scroll bar to the list of starred pages, so that the height of the list is chopped at a certain maximum.
- 6dbe1af - Google, Facebook, Twitter, and Github logins are all supported now.
This was the point at which multiple login services were actually enabled in production.
This was a fix to an issue where one of the OAuth providers'
uid field was being interpreted as an integer, even though I store that field in my database as a string.
- 4ada0ce - The string coercion actually needed to happen in the controller.
- bc3501b - Added [the names of the login providers) to the login menu [when you hover over a given login button.]
And that pretty much wrapped up login support for now.
Lots of little tweaks to get things to look the way I wanted.
- 90fd085 - Fully rounded all the edges of the control bar buttons, added a slash between the -/+ votes buttons, and rebuilt assets for deployment.
- d132ddb - Tweaked the layout to better control the layering and stacking of elements.
- 9955af3 - Removed the remnants of the share link form the main page. Everything about the share link is now in the control bar.
- 093bb0b - Fixed a problem with the share link disappearing at an inappropriate time.
- fe8c093 - Tweaked the look of the bottom section controls on thoughts.
- d4151c3 - Added the theme selector control, and confirmed that it properly changes the class on the body.
- 8faf0f0 - Solved the theme selection not being applied problem.
So, at this point, we had two themes in the app, and I was about to deploy all the final tweaks to get them into production.
Not sure why I was committing theme related code against a .CSV export issue, but here they are nonetheless. Probably just an oversight on my part.
.JPG/.PNG export was also requested, but found not to be practical, so that functionality was canceled. The reason image export isn't practical is twofold: first, why send an image to someone when you can just send them the link, and second, can you imaging the export UI? Which resolutions should I support? Which formats? How would I capture the screen?
Instead I decided that creating a theme that was printer friendly (which is what my user really wanted - something they could print out and mark up with a pen) was a better approach to image export. Not only that, I wanted to support more themes long term anyway, so I figured this was a good time to get started on this work.
The once planned, but now scrapped "paper" theme (it was replaced with the "canvas" theme, which I'm not sure that I actually like all that much) was simply another visual theme in addition to the original dark-themed layout. Implementing a second theme forced me to refactor my theme code to support an arbitrary number of future themes. This meant breaking up my CSS so color schemes were kept separate from physical layout on the page.
- ab69876 - Beginning of refactoring for paper layout.
- 2db2d57 - Split the stylesheets into structural size/layout and colors.
This was the big commit. It put forth the overall plan that I would follow when adding future layouts and themes. As of this writing, cortex supports two themes, and three layouts, thanks largely to the work done in this commit, and following commits, to separate colors and style from physical layout on the page.
- 0d4e611 - Added fonts used in the new paper font.
- 083b9c6 - Worked with Paula to get a few of the colors worked out for the paper theme.
- b0f8018 - Removed some extra whitespace. Code cleanliness
- 47ff1aa - More tweaks, and a demo background image for the paper theme.
- c0b8277 - Converted paper theme to canvas theme. This is where I abandoned paper for canvas. Really just a visual difference.
- 70b0c95 - Added final canvas background image, and color scheme.
- b065b48 - Added code that would dynamnically fill in the theme and layout.
The theme is user specific, not brainstorming page specific. This means multiple people can be looking at the same brainstorm, but each individual gets to see it in their preferred visual style.
- 5aa0da7 - Rebuilt assets for deploy and master merge. Pulled in the latest commits from master in preparation for deployment.
- 3e174a8 - Refactored the navigation bar to have its own, global styling, regardless of the theme applied to the rest of the page.
In this commit, the control/navigation bar got a revamp which made it neutral grey. This control bar never changes its look and feel, regardless of the theme selected. This is primarily about separating responsibilities, and only adding abstractions and splitting up the code when and where it's necessary.
At this point I started referring to the "navigation" bar as the "control" bar, FYI. I think it's consistently called the "control" bar hereafter.
One other thing I noticed here is that I was using confusing terminology throughout the implementation of this feature. So, cortex has two visual elements that you can currently alter, the theme, and the layout.
The theme is the color scheme, essentially. The layout is the physical layout of elements on the page, especially their size and arrangement relative to one another.
Whenever possible, all size/arrangement CSS is in a layout CSS file, while all color scheme elements are in a theme CSS file.
This is the single largest feature in all of cortex, in terms of the number of commits it took to get it working both locally and collaboratively (31 in all). The work on this feature is probably what I'm most proud of in cortex, because it's not only a cool feature, but it caused me to refactor so much of the code involving real-time collaboration. This made the overall code quality much higher, I think, and got the architecture of the app heading in a better direction.
I think this massive commit message (on the final "drag-and-drop ordering feature) covers most of what I spent time on in all these details - trying to get collaborative changes to work consistently:
So, in using cortex, something that I observed was that if you moved an item up in the order everything was fine; it would find that out of order item in the client first, and move it. However, when moving items DOWN in the order, instead of just moving that one item, it would instead move all the intermediate items to acheive consistency with the server, even though the net effect was the same. That meant, when moving items down in the list, you'd move lots more thought boxes a short dista nce in order to acheive consistency, instead of a few boxes a large distance.
This was terribly inefficient for two reasons. First, every shift requires a server request, so the number of requests to the server was significantly higher than the most efficient move possible. Second, it was inefficient for the client because it meant more total moves (and more time the user spends watching the screen, waiting for it to become consistent).
When thinking about how to solve this problem I originally thought that I would need to implement the diff algorithm to find the differences between client and server, and then perform the first move in the diff list with each server request. This seemed like a complex solution to what seemed like a pretty simple problem, so I punted on the solution and waited to see if I could come up with something better.
It turns out that, instead of calculating the diff for the whole list, that you could instead take the client list and the server list, and calculate an array of integers that represent the distance between elements. So, if the client and server lists were identical, you'd have an array of zeroes - meaning that nothing was out of order on the client, when compared to the server ordering. However, in the case that you move something down in the visual ordering, say by seven spaces, you'd get an array of distances that contained seven 1s, and one 7. Once you have that array of distances, instead of trying to move all the items that are out of order, you simply move the one that is furthest out of order. To say it another way - instead of moving the seven items that were off by one, you could achieve the same result by moving the one item that was off by seven. The net effect is that, whenever the client can shift just one item in order to make many items consistent in their ordering with the server, it will prefer to move that one item by a larger amount one time, rather than move a lot of items a smaller amount over several server requests.
So far this has proven to be both effective, and much less complicated a solution when compared to implementing a diff.
Tracking the proper order of the thoughts on the page is actually just a matter of a single column. Getting it to work collaborative, in real time, and to be "eventually consistent" across all client browsers? That's another story.
This added some scopes to the
Thought model to make retrieving the order of thoughts based on various criteria, a trivial thing.
- 4e3b49b - Added method for determining the highest sort order value on the Thoughts in a ThoughtWall.
Prerequisite for figuring out what the "next" sort order value should be for new
Thoughts added to the page.
- 4277e1e - Added model method to determine the next
manual_ordervalue that should be assigned.
- c89e524 - Added custom jQuery UI with sortable support.
jQuery actually does most of the heavy lifting when it comes to making drag-and-drop functionality work in the UI.
- 86e3870 - Made thought wall thought list sortable (i.e. actually added the jQuery code that actually turned on drag-and-drop)
- 4dd8334 - The sort/drag order that the user specifies is not persisted on the server
At this point I'm getting pretty deep into the problem. You can see me relying on a lot of debug output to figure out what's going on client and server side. This will continue for some time.
- 3b38b2c - Added both down-sorting, and up-sorting (i.e. you can drag items up or down the list, and they both work)
- 6cfbeaf - Made a few small changes to the code to clean it up
- 0445de9 - Successfully moved the loading of scripts to the end of the page. This causes the page to load more quickly for the user.
- 1ee32ff - Drag-and-drop order is persisted on the server, and the UI now successfully blocks updates under the user's foot while dragging things around the screen.
This step was important. While a user is dragging an item on the page, you want updates from other users to be temporarily suspended so you can drop a thought in the intended position. From there, collaborative updates can resumes.
- fa6dd91 - Old comments and debug statements removed.
- 9ea7453 - Added a corrective migration that re-numbers all the manual order values
- 4a08504 - Merge branch 'master' into ordering.
This took changes from the master brach and updated the
ordering branch. This is what is supposed to happen when you're doing proper branching and merging - develop logically isolated features on their own branch, and integrate them when you're ready. It makes development of any kind a lot easier the more complex a piece of software becomes.
- 1f8b3ea - Added
position_updated_atfield to Thoughts. Also, refactored the slide in (and new slide out) animations into their own functions.
- f49febb - Dynamic slide in/slide out has been added, but it's not working on remote clients.
Sometimes, even when you know something isn't working, you have to commit what you've got before you forget where you were.
shift Thought(from, to)function, which takes the thought nearest the specified
fromindex, and inserts it at the
- 4e28a98 - Dynamic/reflected inserting seems to be working 90% or so.
- be92c10 - Several more refactors, getting us closer to fully synchronized clients.
This commit included code that was entirely for debugging and testing. I clearly was confused as to why it wasn't working. I don't really add big debugging functions like this unless I'm confused about something.
- 5499ee7 - A little closer to the final version. Committed the code that I had at the time.
- dbd0a27 - We have "eventual consistency" at this point, meaning that all clients, on all browsers will eventually show the correct size.
- dd54903 - Removed debugging output to the console.
- 6e23969 - Rebuilt assets for deploy.
- 1f7453d - Added functionality to remove duplicates from among the thought list.
Duplicates were sometimes generated during weird drag-and-drop operations. This commit corrected those problems.
When coding on the bus, this would happen to me all the time. This commit makes it so your connection can drop, you can put your computer to sleep, etc., but when you come back the periodical refresh will just come back to life, letting you pick up where you left off.
I also removed those huge JavsScript debugging functions.
- 055a114 - Rebuilt assets for deploy.
- 015d19d - Re-ordering of items appears to be done.
- a08f078 - Made the sorting of the list on remote clients much more efficient.
At long last, I breathed a sigh of relief, knowing that I could move on to another feature, ending six days of continuous work on nothing but this feature.
- 1c35113 - Reworked some layout in the full screen mode to get scrolling and text to always fit.
- 8df03d9 - Corrected a small CSS issue that caused vertical scroll bars to show up (in full screen mode) when it wasn't necessary.
- ebe7603 - Changed the name for a div. Code cleanup.
- 772f1bf - Full screen editing re-enabled after several small changes made.
- 819e4fd - Disables resizing of new thought textarea, so as not to confuse people.
The last commit in this group came from the fact that, the layout of the page allowed you to resize the new thought form, but you couldn't resize it back to smaller dimensions after that point. I felt it was best at this point to simply disable resizing altogether.
Issue #33 represented an important feature: the ability to edit thoughts (to correct typos, add more information, etc.), and to retain the most recent five versions of that though, allowing you to rever to them at any time.
While developing this feature I also saw, and added, a couple of other tweaks.
This commit mostly added view and layout bits. Nothing was wired up to control anything at this point.
If I had been more careful, this migration never would have been necessary. I discovered this error the day after it had been pushed to production, and making this corrective migration, while helping a lot in terms of usability, once again wiped out all the votes. Drive me crazy when I make mistakes like this.
As mentioned in the previous commit, I had to apply a corrective migration to the production server. Because of this, I had to diable to the "edit thought" UI control before deploying because otherwise a control that did absolutely nothing would have been visible to users.
It's been a few weeks, but my guess as to why I had to do this is because I was probably developing directly on master, instead of developing on a feature-specific branch.
This is yet another mistake. If thought editing had been on an isolated branch, the corrective migration could have been applied in its own branch, and I wouldn't have needed to disable this control in the first place.
Let this be a lesson as to what happens when you build directly on the master branch.
- d3a812f - Removed the "close" button from the overlay.
This is where I decided to basically drop support for mobile devices.
In working on thought editing, I realized that simply truncating the thought text to 100 characters, as I'd been doing up to this point, wasn't going to work long term. after a little research I found this CSS property that would accomplish the same thing so I didn't have to constantly tweak the truncation to make it fit.
- 9742567 - More tweaks to the visual thought truncation, instead of physical truncation.
- 32144ef - Really basic display of history with sample text. Nothing real yet.
- a31c423 - ThoughtHistories are limited to a maximum of the most recent 5 entries. More layout tweaks as well.
- 859a09b - History display now gets hidden when you click away from it.
- cf1a61c - Re-compiled assets for deploy.
- d5352f4 - Fixes local storage issues in Firefox.
This commit came from stopping and testing it on Firefox and Safari. I tend to develop on Chrome exclusively these days, but it's good to stop and try other browsers from time to time, to make sure things work the way you expect them to.
- b947d5a - Recompiled assets for deploy.
- db05933 - Editing, with hitory, and restore capability is now in place.
Editing and history was already working on a functional basis before this final commit, but the final commit adds some layout tweaks and rebuilt the assets.
Several commits that replace the happy/sad/neutral functionality with voting.
- de9066a - Initial schema change and alterations to the convenience methods
- da5360c - Style updates, convenience method changes, layout changes, asset rebuild
- 7574b6f - Precompiled assets for deploy (was this a duplicate rebuild?)
- 5bd4266 - Had to modify the DB migration to only use methods available in the version of the DB that exists on heroku
This migration change resulted from the fact that I should have migrated the heroku database at the same time that I altered the schema. In fact, schema changes should often be done alone for reasons like this. As a result, I actually destroyed data - something very dangerous if cortex had been getting used by lots of people. Not a good thing.
This was primarily code cleanliness/maintanability. You want logical chunks of your view code to be in partials. Be careful - its easy to overdo this. You don't want to build such a large, complex hierarchy of partials that you have to open five files just to find out where to make a simple change, but you do want things to be broken up into logically related elements so you can make simple, clean changes to those elements in the future.
This was a big refactor of the refresh timing. A major part of what makes cortex useful for collaborators is the real-time updates.
This update made a lot of small changes that added up to an overall better experience, at the cost of greater server load. There's so little load on the server at this point, however, that this is a small concern. I'd rather the app be more useful anyway.
Changes to a brainstorming page's title should be reflected in the title of the page, as well as the recent list.