Ramblings on Technology, Gaming, and Life in General

Menu

FeedSpider Dev Blog: Finished!

Well, finished in as much as a software product can ever be finished. On Thursday morning, I delivered a 1.0 version to the Firefox Marketplace for review – a week in advance my deadline, so I’m pretty happy about that.

This last week was mostly under the hood stuff, and dealing with little things that were not huge components, but just needed to get implemented, like mark all read, logout, tap the title to scroll to the top, etc., as well as a few little bugfixes and the like that cropped up during the process.

My big projects for the week were finishing up with the list rewrite, getting event handling working, and getting recurring notifications working.

Even after last week, I wasn’t quite happy with how swiping in the article list was working. The original FeedSpider implemented a method where you could pull over on an article to mark it starred or read without needing to complete the swipe. However, this doesn’t quite work with Enyo lists. There is an event raised when a swipe is completed, but no event raised on an incomplete swipe.

Fortunately, due to the nature of Enyo inheritance, it is very easy to build a custom Kind to fix this. The first method that I tried was to raise an event when the list finishes the process of backing out of a swipe. The problem with this is that the last part of backing out of a swipe is to start an animation using Enyo.job, to hide the container. Since Enyo.job is deferred, the event fires before the animation is complete, leading to some very ugly UI issues. So, that was out.

The second method was to copy the method that handles the animation into my Kind wholesale, overriding the parent Kind, and have it raise an event when the animation is complete. This has the side effect of firing the event any time the animation completes – both on a completed swipe and an incomplete swipe. This meant that when the swipe completed successfully and swipe container stayed on screen for a couple of seconds, the event fired, causing the list to change behind the swipe container. Better, but still ugly. This was half the solution.

Based on the original behaviour, I never actually need the swipe to complete, the user just pulls to one side or the other, the icon underneath changes, and then the list item “springs” back. The List Kind defines a variable: percentageDraggedThreshold, that defines how far (in percent) the user has to drag the list before it will trigger the swipe being completed. By default, this is set to 20%. By setting it to 150%, the swipe will never complete unless the user pulls it a significant distance beyond the end of the window (impossible on a phone/tablet, and will only happen in a desktop browser if the user is really trying), solving the UI problem.

The other bit of work that I did on the article List was to get it to load more articles. A suggestion from Garfonso pointed me in the right direction. An Enyo List is based on a Enyo Scroller, so I was able to tie into the scroller’s underlying scrollEvent to detect if the scroller was in its final “screen” based on the test (inEvent.scrollBounds.top >= inEvent.scrollBounds.maxTop – inEvent.scrollBounds.clientHeight). If so, and if it there were more articles to load (and it wasn’t already loading them) it could then load more articles and refresh the list.

Event handling (for article state change and folder deleted events) was interesting. The way that the app is structured and the objects are created, the objects that trigger these events don’t always exist in the same tree as the panels that are supposed to be receiving them, so standard Enyo event handling doesn’t work. The solution that I came up with was to take advantage of the “feedspider” object – define a method in the app.js that is called and passed the event information, which then waterfalls down the appropriate event to the panels, which handle them. Not super elegant, but it works.

Alarms and Notifications were surprisingly straightforward. (Notwithstanding some sort of state condition in the simulator that had me stymied for a couple of hours. Re-installing the simulator fixed the problem) Following the direction in the Alarm API, and with a little help from Stack Overflow, I pulled together a simple wakeup alarm that would pop up a notification on a timer telling the user how many unread items they had in the feeds that they specified, just like the original FeedSpider.

With that complete, all of the major features of the app were done. It was just a matter of zipping it all up and submitting it to the Marketplace.

Reflecting back on the porting process, it was interesting. Whats nice is that I was just moving from one javascript framework to another, so there were very few changes to the core logic (the fact that I was able to continue using prototype.js helps too). Much of it was a UI re-write, as well as making some components work in a more Enyo-y manner. The biggest change was moving from the Mojo style of defining the different components as html pages and then tying Javascript into them (as in more traditional web design) to the Enyo style of *everything* being defined in Javascript and CSS (well, technically using LESS.js).

I mean that quite literally. I moved from having 29 html pages defining my scenes and html components such as dividers to having 1. And the entire content of the that page (aside from loading Javascript, css, and a little metadata in the header is:

<body class="enyo-unselectable">
</body>

It’s a very different style of thinking. But, at the end of the day, it’s all Javascript, its all portable, and once you get it, it all makes a lot of sense.

So what happens next? It’s been a busy couple of months, so I’m going to take a few days off while waiting for the Marketplace review to finish, then it’s time to start looking at the next platform. I promised a webOS port, so that will be next, and should be *relatively* straightforward. Then, after that, probably Blackberry, or Chrome Web Store. (I might throw in a Firefox desktop browser build while I’m at it – I’ve had requests).