Using the LG Voyager as a Smartphone

Recently, I purchased an LG Voyager. Since my previous phone was a smart phone, I did a massive amount of reading and debating before purchasing the Voyager - I actually wanted to downgrade my phone, but not lose a lot of functionality that I was used to having. The Voyager is not a smart phone, but it has a lot of features that allow me to maintain the same features, which is what I want, and it does so for less than half the cost. After using it for a few weeks and finding that I do not miss my smart phone at all, I figured I’d share my thoughts of my experience with some of the features of the Voyager that allow me to maintain all of the same functionality as a smart phone (for much cheaper).

A note about Outlook and Google services
It’s important to note that if you’re looking to know if the Voyager will sync with Microsoft Outlook for email and calendar, then this review is not going to cover that topic. I sync everything with Google services and Google provides a lot of functionality that makes it easy to push their services to cell phones via SMS. I also want to add that the Voyager comes with a full HTML browser so it is possible to check your Outlook email via the web interface, but that’s not the focus of this post.

What I wanted out of a phone
As previously mentioned, aside from making calls and sending/receiving text messages, I want my phone to provide access to my email, my calendar, and to have the functionality that will allow me to casually browse the internet to, say, read my RSS feeds. In addition to access to these services, I’d like my phone to ping me when I’ve received a new email and whenever I’ve got a calendar event about to occur.

Additionally, as much as I love having the full QWERTY keyboard, I found that I actually missed sending quick text messages using the numeric keypad. Smart phones are wide enough such that it basically requires two hands to type any type of message and that frustrated me at times. Luckily, the Voyager has both.

Lastly, I ended up disliking Windows Mobile - I probably should have seen that coming, but either way, I digress as that isn’t the point of this post. Basically, I wanted to “de-grade” to a dumb phone from a smart phone in order to save money, but maintain smart phone functionality all the while.

HTML Browser
The first thing I want to point out is the quality of the browser on the LG Voyager. It’s a full HTML browser (versus the usual WAP browser found on most dumb phones), so, excluding things such as JavaScript, the phone renders pages almost exactly the same as you’d see on your desktop. Matched with the speed of the Verizon EV-DO network, you get a really solid browsing experience. The browser was one of the selling points of the phone for me - with this browser, the touch screen, and the EV-DO network, I have web access to almost all of the usual pages that I use. Most major sites also have mobile version available, such as YouTube, Facebook, Flickr, and Google, if the standard version doesn’t load.

Getting Email
Because I maintain everything using my Gmail account (with the exception of work email), I had been syncing my previous phone’s email client using IMAP with Gmail. This proved to be nice, but, seeing as how I’m at a computer most of the day, the benefits of IMAP weren’t as strong as I could basically just respond to the email from my machine. The phone ended up, more often than not, notifying me of whenever I had received a new email. In the rare case that I wasn’t near a computer, it was nice to be able to send an email from my phone.

Since the Voyager is not a smart phone, it has no true email client that most phones like the Treo or the Blackjack have; however, Gmail offers the ability to automatically forward emails as they are received. Since you can send a text message to any phone on the Verizon network at [phone-number]–>

Obviously, this doesn’t allow me to respond to an email, and the email is truncated because of space limitations of cell phones, but it provides notification that I do have an email so I can respond whenever I get back to a computer, or I can open up the browser on the phone to respond if I absolutely need to respond at that time.

Calendar Notifications
The second major point that I want out of my phone is the ability to have my schedule available with me, and to have the ability to add, remove, and update items on the go. With my previous phone, I was able to do this; however, I’d then have to run the synchronization application in order to have both calendars updated. With Google Calendar, I can keep all of my data centralized, and, by using Google Calendar sync, I can sync my work calendar with my Google Calendar automatically.

Similarly with email, I’ve setup SMS calendar notifications to be sent to my phone 15 minutes prior to an event starting. This works much in the same way that Outlook notifies me on my desktop at work, and also the way that Windows Mobile’s calendar works. If I need to see a more detailed schedule, I can again launch the browser to view and/or modify my events without having to initiate a syncing process.

Miscellaneous
The phone also has other good features, but the primary thing I wanted to show was the ability of using the Voyager as a smart phone though it lacks features that most smart phones have. In addition, Verizon’s BroadbandAccess plan for smart phones cost $50 a month whereas dumb phones have unlimited web access for $15 month. With this phone, I’ve been able to save money without losing any features of a smart phone.

Until later,
Tom

Testing 1, 2, 3…

Recently, I’ve been working on a project that will ultimately require new users of the system to create their accounts with stronger passwords than the application has typically allowed. Existing users will be required to update their accounts with stricter passwords. The software is a distributed web application, and the code that I am working is a the application layer.

I’ve used a couple of design patterns to essentially build a framework that allows us to setup a password object and add and remove policies to it at runtime via XML flags. Policies are nothing more than rules that will evaluate the password against a single requirement, such as its length or whether or not it contains a specified number of digits and/or symbols. For every policy that the password is evaluated against, the framework will generate a set of error messages as well as a password strength rating and will return them once the rating process has completed.

Ultimately, this will all be bound to the front-end when the overall project is completed; however, for now, there’s no UI against which to test the framework’s performance. Since testing is arguably one of the most important phases of software development and since there’s no true UI to provide any level of feedback from this framework, I chose to take a true test-driven development approach to the password and its policies.

Write Test Cases First
Because we designed the software upfront, we new how the system should behave before we actually began building it. This made it relatively easy to write test cases first - we new what our inputs were going to be and we new exactly what outputs to expect for each case. After writing these cases, I found myself to be more conscientious of the code I was writing for the actual system.

Although it’s wrong, it’s not uncommon for developers to first build their application and then right the test cases (numerous articles are available online about this). This is incorrect for a number reasons primarily because you’re basically writing tests for a system you’ve already built - in the same way that writing code after the test cases made me more aware of what I was writing, writing your test cases after building the components will likely result in writing cases that fit the existing system. This completely misses the mark on the purpose of Test Driven Development. Writing test cases to fit the software is backwards - write your software to fit your test cases.

How long did it take?
This took a little bit longer to do for several reasons. First off, writing a test suite to cover branches, statements, outputs, etc. of your system adds to the amount of time to complete the project (or phase of the project). Couple that with updating various components and then developing new test cases for those changes, you’ve got a pretty full plate of things to maintain. Ultimately, it may result in a slightly longer period of time to complete, but if this is taken to account in project planning it shouldn’t be that big of a deal. Additionally, you’re only increasing the quality of the software, so I’d argue that it’s worth it more often than not.

Combinations and Permutations of Policies
This was the fun part. Initially, we started off with a small set of policies; however, as the project matured and we gathered more input, we had to create additional policies. This resulting in us testing possible error messages as well as the various strength ratings for each arrangement of the policies. It’s really not that big of a deal if you’ve got a couple of people working on the project, but it’s easy to see how fast something can increase in complexity by simply introducing one or two more components.

Overall Impressions

Building this framework using Test-Driven Development was great. It prevented the project and it’s various combinations of outputs from getting away from us very early in development. It also resulted in a great feedback of a system that doesn’t have an interface with which to interact. Finally, it generated a strong sense of software quality once the system was developed and all of the test cases passed.

Maybe I’ll revisit this project to show off the interface once we’ve finished it, but that’s not really something I’m planning to focus on showcasing. We’ll see.

That’s it for now,
Tom

Open-Source Usability

With the next version of Ubuntu Linux coming out in about a month, many of the Ubuntu blogs have been buzzing with a range of topics - discussions on new features, examples of the improvements, reports on bugs that have been addressed (and new ones that have popped up) - most of which are relatively normal. One recent post, however, caught my attention - The #1 Problem in OSS Usability and What I’m Going To Do About It. I’ve been tossing around the things that she’s discussed in that entry, and figured I’d post my thoughts here.

The author makes some really good points in her article and so I’m going to try to avoid repeating too much of what she has already said. Before getting into it, though, I’d like to concisely summarize my opinions on development and usability without going off on a tangent:

1. Programmers should not be the sole people responsible for building the interface. They should be responsible for designing the software and building the interface around specifications determine by designers - not throwing in an interface element for every single function in the software.

2. Designers should not pretend that they are programmers, but should have a solid understanding of what the software is supposed to be doing. Don’t decorate the interface with unnecessary elements - minimalist, intuitive design is key.

Unfortunately, one of the down sides of open-source software is that a large majority of the interfaces for software that is developed is done so by programmers. That’s why it’s not surprising to see something like this, versus seeing something like this
on any given Linux distribution.

So why is her idea awesome?

First off, she not only understands usability, but she understands what the problem is with regard to usability in the open-source community. Usability is something that is already greatly ignored in software development, but even more so in a community that is primarily made up of geeks and software developers. We care more about something working versus how it looks, and it shows whenever you look at almost any piece of software that’s been hacked together.

Secondly, she’s got direction on how to address the issue. Because lack of research is the largest factor contributing to low-levels of usability, and because there’s no set standard or method of documenting the research, there’s no way to move forward with improving usability if there’s no reference on what to improve. Developing formalized documentation from the open-source community is an awesome place to start.

Lastly, she knows where to begin. She doesn’t really have a half-baked idea - she’s not only addressed the problem or how to solve it, but she’s addressed how to get it started, has explained how’s she’s going to do it, and has the personal investment in the project to keep it going. She’s got direction and you can’t drive anywhere without good directions.

Why I think this will work

Having “Open-Source Usability” is something that I’ve never really thought about, despite the fact that it makes sense. I’ve typically associated the open-source community with geeks - people that care more about good looking code rather than graphical user interfaces, people that care more about decreasing the number of cycles their algorithm costs just for the sake of decreasing it, and, generally speaking, people that care more about increasing functionality rather than experience.

When I first read this article, I was kind of quick to write it off - not because I thought it was a bad idea, but just because I didn’t think it was feasible. I’ve read the article several times and have been thinking about it for a few days. The more I thought about it, the more interested I became in this whole initiative. I then began to think about the open-source community and if it would be, well, open for something like this. I kept thinking about all of the ways in which people who care about design, usability, etc. would be deterred from Linux - then I realized it has nothing to do with the operating system. It has to do with what you’re passionate about doing, and being able to see the manifestation of your work - Linux is definitely provides a platform for doing this. I then began to think about other platforms that was open to a wide array of different users each with a range of different interests where they all cooperate - Wikipedia. I’m sold.

Open-Source Usability is step in the right direction for not only continuing to bring Linux into the mainstream (because I hold the opinion that it still isn’t ready despite so many awesome advances in the past three years), but for improving on the open-source model that has worked so well over the past several years (over a decade, even!). I’m pretty excited to see where this will go.

Joel on Software on Web Standards

Joel on Software is a site that anyone and everyone oriented in application or web development should read. Nearly every post he makes has value to it, but his most recent post on web standards is excellent. It does an amazing job of saying absolutely everything that should be said and nothing that shouldn’t be said and it does so in best way possible.

Regarding Slideshow JS

Over the past few days, I’ve noticed that a number of people are downloading Slideshow JS. That’s great, but I also noticed that I never formally discussed the script here, so I thought I’d take the opportunity to do that now.

I’m not going to belabor the project here as you can read much more about it on the project’s page, but I thought I’d highlight some of the features of the script here, what it seeks to do, and how to contact me regarding bugs, feature requests, etc.

About The Script

The purpose of the script is to provide a very simple way of cycling a set images in an HTML document. It doesn’t require any knowledge of CSS, JavaScript, or nuances of browser performance - it only requires that you know how to actually add script tags to the head section of your page.

The one caveat to using the script is that the images that you wish to cycle must be placed in a div container. All of the styles for this container are managed by the script, so you won’t have to write any CSS. The script is flexible in that it won’t interfere with any of your current styles, and that you can customize the placement of the images however you wish. Details on how to do this can be found on the project’s page.

Slideshow is cross-browser compatible between IE6, IE7, Firefox, Safari, and Opera. It also has two modes of cycling the images - it can fade the images, or cycle them with no transitions. Unfortunately, IE6 does not support opacity so fading does not work in the browser.

For more technical information about the libraries that Slideshow uses, and how it operates with respect to the DOM, see the project page.

Contacting me regarding feature requests or bug fixes

I was initially only developing the script for myself, but as a few friends showed interest in the script, I decided to try to make it as robust and flexible as possible for others to use. I’ve attempted to test it as much as possible, but it’s impossible to test every single use case.

If you find a bug, definitely send me an email and let me know exactly what you did to discover it. I’ll do my best to address it.

Slideshow’s purpose is to provide a simple way for you to cycle your images without worrying about CSS, JavaScript, or cross browser quirks. If you’ve got a feature request that you think falls in-line with this purpose (such as showing an image title overlayed on the image), then also send me an email.

Anticipating Dropbox

With sites like YouTube and flickr providing a seemingly endless amount of storage, it’s becoming increasingly easier to find places to backup all of your various media. I personally don’t use many of these services either because I don’t agree with their privacy policy, their price, or their vague details of how my information is kept secure.

I have no reason to believe that Dropbox will do anything different in these areas, but if this service goes above my expectations and has a really good price tag, then I’m sold on it. I don’t wanna get my hopes up, but I’d be lying if I said I weren’t a little excited about it.

Using local variables with JavaScript’s replace() function

Recently, I’ve been working on some client-side code for a web application that needed to encode some data prior to invoking an AJAX request, and then needed to decode the response data upon receiving a successful response; however, I discovered a nuance in JavaScript’s replace() function that required a little bit of extra work to get it operator with the degree of flexibility that I wanted.

Because ampersands are usually used to delimit query string parameters, the server wasn’t handling the submitted data correctly. To mitigate this issue, the ampersand character needed to be encoded. We stored the encoded representation of the ampersand in a local variable [creatively] called _ampersand.Next, we wrote a function that takes in the data to be sent across the wire, encodes the characters, and does some additional processing, before returning the encoded data:

function encodedData(strInput) {

return strInput.replace(/&/g, _ampersand);

}

It worked fine; however, the replace() function proved to require a little additional work for it to decode the data correctly. Since we needed to do a global replacement of the ampersand token, we were using the g operator, but inserting a variable into the replace() function does not work. Actions speak louder than works, so here’s what I mean:

// this does not work…
function restoreAmpersands(strInput) {

return strInput.replace(”/” + _ampersand + “/g”, “&”);

}

At first, it seems as if it work work fine - concatenate /’s on the value stored in _ampersand and then let JavaScript get to it. Unfortunately, this isn’t how it works. One solution would be to simply hardcode the value of the _ampersand variable into the replace() function, but that’s poor coding. The solution I ended up using is actually extremely simple and it makes perfect sense.

Because replace() requires a regular expression to work its magic, giving it a concatenated string literal will not work. Instead, I ended up first creating a regular expression that includes the _ampersand variable and the global operator, then I passed it into the replace() function. Have a look:

var sRegExInput = new RegExp(_ampersand, “g”);
return strInput.replace(sRegExInput, “&”);

Extremely simple solution to a problem that, in my opinion, shouldn’t have been much of an issue at all. Oh well, at least I know that I wasn’t alone.

Zuckerberg said the episode taught him an important lesson. "Almost all…

Zuckerberg said the episode taught him an important lesson. “Almost all of the mistakes we made, we didn’t give people enough control,” he said. “We need to give people complete control over their information. The more control and the more granular the control, the more info people will share and the more we will be able to achieve our goals.”

One of the main problems I have with Facebook is exactly this. I’m glad that Zuckerberg acknowledges his mistake, but how many times can you keep making the same mistake before you learn from it? Furthermore, I think he, and others, should realize that not everyone wants to share everything.
Read more from the article here.

Issues with Opera, Prototype, and dom:loaded

I’ve been working on a small JavaScript library that is built using Prototype, and discovered a small quirk that caused Opera and Safari to respond differently than IE and Firefox when using the dom:loaded event with the document.observe function.

According to the Prototype documentation dom:loaded will “fire immediately after the HTML document is fully loaded, but before images on the page are fully loaded.” My script manipulates a set of images that are on the page, and I needed to process each image before the page loaded. If I waited until the document had fully loaded, then a flicker would occur in a couple of browsers. Unfortunately, it wasn’t happening in every browser so this made it difficult to diagnose.

Initially, my approach was to first intercept the images, hide them (save for the first image), and instantiate my object all before the DOM had finished actually loading the images. This is basically what I was doing:

document.observe(’dom:loaded’, function() {

// error checking, reading images into an array here
images.each(function(i) {

if(i != images.first()) {

i.hide();

}

});

// apply some specific margin styles here

});

The end result worked well - it behaved exactly as I had anticipated across IE6, IE7, Safari, Opera, and Firefox but the problem didn’t occur until I uploaded everything to a web server and began running tests across these same browsers. That’s when I found an ugly bug: Opera appeared to be completely ignoring all of the initial processing. Safari occasionally demonstrated the same exact error, but it was inconsistent - sometimes it worked, sometimes it didn’t.

Rather than try to hack the code to get it to bend just enough for Opera, I wanted to investigate it and figure out exactly what was going wrong. Sadly, Opera doesn’t have a nice DOM debugging console (at least not that I found), so I had to resort to creating some test cases to pinpoint the issue.

First, the reason that the error didn’t show its face until the script was running on a web server is because the images were stored locally so there was close to no time required for the images to load - on a web server, that’s obviously different.

Secondly, regarding the script, I’m not 100% positive that this is the problem, but it’s as close as I could come based on the results of my tests. What I found is this:

Earlier, I mentioned that the dom:loaded event is triggered prior to when the images are loaded, right? Well, I was initially trying to access the image.height property during this processing. Whereas the other browsers were already parsing each image’s properties, Opera was not. From what I gather, the other browsers are loading up the properties of each image prior to actually displaying them, and Opera is delaying all of this until the dom:loaded event has completed. Basically, this makes it impossible to process any of the images until they are visible on the screen.

After discovering this, I made some changes to the code. I was somewhat reluctant to do this at first because I didn’t wanna sacrifice some of the slight performance issues that would come as a result of the fix; however, the cost of flexibility outweighs the minimal performance decrease, in my opinion. Here’s what I did:

document.observe(’dom:loaded’, function() {

// error checking, reading images into an array here
images.each(function(i) {

if(i != images.first()) {

i.hide();

}

});

});
Event.observe(window, ‘load’, function(evt) {

// apply some specific styles to the images here

});

Ultimately, this still allows me to hide all of the images prior to them being displayed so none of the actual visuals are affected, but I delay the image processing until the images are actually loaded by the browser. This proved to completely fix the bug in Opera and also stopped the inconsistency issues in Safari.

As I mentioned before, I’m not 100% positive that the results of my testing are correct, but it seems to be close based on the results. Additionally, this fix ended up addressing the cross-browser quirks so I’m content with the solution. If any of you are familiar with the issue that I was having, or have had any similar experience, leave me a comment.

Later, I’ll go more in depth on this library that I’ve been working on, but I’m not quite done with it so there may be more issues to discus.

Until then,
Tom

IE & The Ajaxian Injection Rejection Problem

Recently, I’ve been working on an application that, upon the successful completion of an AJAX request, injects some HTML into the current DOM. While working on this project, I kept getting an “Unknown runtime error” message in IE6 and IE7 all the while Firefox was responding the request by injecting the HTML exactly as I wanted. Before you go hating on IE and loving on Firefox (which I was guilty of doing), read on - IE was actually doing the right thing, just in a poor way.

What was wrong?
Here’s a snippet of my JavaScript as well as a comment as to which line was causing the problem:

if(response.get_responseAvailable()) {


var div =
document.getElementById(’divJobInformation’);
// here’s the problem…
div.innerHTML = response.get_responseData();

} else {

} // end if/else

Basically, what’s happening here is that, permitting the response has completed successfully, it brings back a chunk of HTML that I want to place in my current page. Unfortunately, it was halting on both versions of IE and displaying this error:

Just to make sure I had covered all my bases, I double checked my Firebug console and it wasn’t reporting any error at all. I ended up trying out a couple of test cases to see if I could pinpoint the problem. First, I tried to simply inject a string literal into the DOM. It worked. Next, I echoed the response data into a JavaScript alert box. Everything was displaying fine.

So what did you do?
After coming up empty there, I ended up going through some of the application code that was responsible for handling some pre-processing of the page into which I was trying to inject this data. Now, I’m someone that tries to comply with W3C standards in every way possible, but I failed here: What I ended up finding was that some of the data that was coming back from the AJAX request contained a block level element and it was being injected into an inline element. That’s bad style, and I should have caught it sooner, but I was knee deep in code and I failed to catch it. I couldn’t see the forest through the trees, so to speak.


Did you bother verifying this?

Yep. After I got the rest of the application working, I wanted to make sure that I fully understood what the problem was, and to verify that it was repeatable in all (or almost all) cases. I ended up making a quick sandbox page that would allow me to dynamically choose a single containing element and then trying to inject a collection of other elements into it. One example would be trying to place a header element in a paragraph element. IE threw an error for every one of the tests I ran, Firefox let it slide.

But there’s a catch: If you were to place a header element inside of a paragraph element in your HTML source and then load it up in a browser, it works fine - IE will actually parse it and display it with no errors. If, however, you attempt to inject a header element into a paragraph element after the DOM has loaded, it will throw an error every time.

Surprisingly enough, IE (instead of Firefox) is actually doing the right thing by rejecting this attempt to insert response data in an ill-formed manner. Unfortunately, the error message that it returns gives you almost no direction into which way to really start debugging the script. Maybe I should have caught this from the get go, but judging by a quick Google search, it seems as if others have experienced similar pains.

If you’ve got any thoughts, comments, questions, or more experience with this stuff, leave me a comment!
Tom