Zune Backgrounds

Uploading lots of images with my new image uploader is fun, so I’m throwing up all of the backgrounds I’ve collected for my Zune. They’re mostly cropped versions of my wallpaper collection, with a few I’ve found around the Internet scattered here and there.

  • whiteringszune.jpg

  • Ultimate Strands.jpg

  • LEGO R2-D2.jpg

  • LEGO Boba Fett.jpg

  • moon to earth.jpg

  • Organica Grey.jpg

  • GOW Logo.jpg

  • Organica Green.jpg

  • Atmosphere.jpg

  • Earth-Space.jpg

  • Flow Red.jpg

  • domo.jpg

  • 3805_small.jpg

  • logogreyzune.jpg

  • LEGO Rebel Pilot.jpg

  • blackringszune.jpg

  • I Love Summer.jpg

  • Altered Bliss.jpg

  • Brigade Damaged.jpg

  • qqwl.jpg

  • LEGO Darth Vader.jpg

  • GOW Lancer.jpg

  • LEGO Stormtrooper.jpg

  • LEGO Batman.jpg

  • Sound Crushing.jpg

  • Halo 3 CG Trailer.jpg

  • Flow Green.jpg

  • Nemo Gull.jpg

  • Yarr.jpg

  • Gathering Storm.jpg

  • Blurry Fireworks.jpg

YUI Uploader Implementation

Image Uploading using YUI Uploader Widget

A few days ago the YUI team released the latest and greatest version of the YUI Library, YUI 2.5.0. Along with the usual round of bugfixes and speed improvements this release came with several new components. I personally was the most excited about the Uploader component, as the technology that powers it also underpins the upload process on Yahoo! Video. I didn’t write the upload pages but I’m expected to be able to provide bugfixes and enhancements to those pages, so what better way to learn how they work than from the ground up with the Uploader?

Yes, I know there’s quite a few better ways. This was the most fun sounding way. What can I say, I like 4 day projects in my spare time instead of just reading the existing code. Besides, I wanted a better understanding of it from a lower level than just how the upload code on VYC works.

As mentioned in the YUI Blog posting about 2.5.0, the Uploader is what not only powers VYC uploads but Flickr uploads as well. Flickr exposes more of it due to their allowing of multiple files uploaded at once. That’s not really very easy to do on VYC due to the much larger file sizes being used. Still, it’s there. I promise.

I’ve had a free-for-all, open to anyone image uploader chilling out for quite some time at http://tivac.com/upload/. I wrote it to solve a problem, namely the other image uploading services available at the time sucked. It was just a quick little thing, with some basic JS that would hide the form element and create a new one so you could upload more than one file at a time. When you were done it would barf out thumbs of the images along with some common types of link code for forums and the like. Nothing fancy at all. Well, the new YUI Uploader seemed pretty much tailor-made to work instead of creating new form elements.

Here’s a good representation of my thought process while I contemplated redoing the image uploader.

Method Select multiple files from one dialog? Progress feedback available for updating the UI? Smart enough to not totally hose the browser while uploading? Able to dynamically update UI on completion?
Form + JS No No No Sorta
Uploader + JS Yes Yes Yes Yes

I think that paints a pretty compelling picture of why I’d go with the YUI lib over the original solution. Aside from requiring Flash 9 and not working on the latest OSX because Adobe and Apple are feuding, there’s really no downside. It’s provably better in every way. Since this is just a junky little personal project and not something important, I don’t even provide a fallback HTML form any more. That’s just how I roll.

Actual implementation was pretty basic. The YUI documentation is excellent as always. It more or less started life out as a copy of their Simple Upload Example and then I hacked the crap out of it. The flow ended up being something along the lines of the following.

  1. Browse for image files.
    upload step 1
  2. If you selected one you don’t actually want to upload, clicking it’s filename will remove it.
    upload step 2
  3. Upload the files, watch all the fun progress bars whiz around.
    upload step 3
  4. As each file completes, its filename is replaced with a thumbnail and various different pre-filled link codes for HTML and forums.
    upload step 4
  5. You can also hit the Export button to just get a list of the URLs of the uploaded images.
    upload step 5

It sounds complicated because I’m an engineer and don’t explain things well. The cool nerdy thing about this is how very event-driven it is. For example, take a look at this code chunk.

 

//certain things can only happen once the SWF is ready to rock
this.uploader.addListener('contentReady',   this.swfReady);
//event handlers
this.uploader.addListener('fileSelect',         this.onFileSelect);
this.uploader.addListener('uploadStart',        this.onUploadStart);
this.uploader.addListener('uploadError',        this.onUploadError);
this.uploader.addListener('uploadProgress',     this.onUploadProgress);
this.uploader.addListener('uploadCancel',       this.onUploadCancel);
this.uploader.addListener('uploadComplete',     this.onUploadComplete);
this.uploader.addListener('uploadCompleteData', this.onUploadCompleteData);

There’s an event fired by the flash object for pretty much everything you could want. The only event I found myself wishing it supported was a “allUploadsComplete” method. As it was I had to create a cache of all the file ids being uploaded, and in my handler for uploadComplete I would remove each id from the cache. If there’s no more files left to upload, hey presto we’re done! A little roundabout, especially when having to watch out for files that were selected and then removed.

The other fun thing I decided upon was that instead of using innerHTML and getting back big chunks of HTML from the server (wrapped in JSON, of course) I’d instead use skeleton structures hidden in the DOM. A quick

YUD.get('upload_skeleton').cloneNode(true);

and you’ve got yourself a nice chunk of HTML just waiting for some delicious data to be inserted. The actual insertion is pretty boring DOM traversals, but by using a skeleton as the base it avoids heavy node creation/appending or a massive innerHTML dump. The page’s DOM is a little heavier because it contains these stubs, but there’s only two of them and page weight isn’t a big concern for this project.

The progress meters are basically a total ripoff of Flickr, I feel a little bad about it but I really liked their approach of using a background image and just changing the x offset each time uploadProgress was called. It’s so simple and to the point that I didn’t see any reason to make it more complicated.

So that all works fine, but I was worried that if I didn’t copy the URLs correctly right away the images would be lost forever. That meant that I had to write a little PHP script that would output linked thumbs of all the images that had been uploaded. Since this is a totally unrestricted image uploader there’s been a few instances of people uploading porn and the like. I’d rather not deal with that, so there’s a little delete script as well. It’s protected by a .htaccess/.htpasswd basic auth setup. Nothing fancy, but it keeps other people from being able to delete my images.

image browser

The images are laid out in a big floating grid using Hedger’s very awesome work on getting display: inline-block to work across browsers. Item List Grid : Practice with display:inline block across browsers. It’s a technique we also used extensively on VYC so it was the first thing that came to mind when just floating a bunch of images that weren’t the same height went all crazy.

Oh, right. All the icons are the insanely awesome work of Mark James, specifically his Silk set of icons. I’m sure you’ve seen them used pretty much everywhere. There’s a good reason for that, they rock.

I’ve zipped up the source for anyone who wants it, it’s all pretty well-commented. You will have to handle the file permissions yourself though. UPDATE: Sitzmar wanted me to point out that all the paths are hard-coded for my uploader.  He says I should be ashamed, I say he should shut up.  Also I don’t think I included the .htpasswd (obviously) or the .htaccess.  Those are easily set up, a quick search on the internet will answer all questions.

upload.zip

Senior Project

I’ve tossed a copy of my senior project up at http://patcavit.com/dev/classfinder/, a quick inspection makes it look like it’s working fine but I can’t say for sure.

For those that don’t know this is an attempt to make the Classfinder tool at Western Washington University not only easier to use but also cleaner and faster with more emphasis on getting out of the way. To that end it has a few features that the original Classfinder doesn’t have, including a freeform search box that will guess what you searched for and dynamic scratchsheet handling. You can add classes instantly without having to go to a seperate page. No screenshots for now.

It’s not the prettiest thing out there but it’s very functional and tries to take better advantage of screen real-estate than the previous Classfinder. I’m pretty happy with how it turned out overall.

Tech Demos

I was looking for a better way to show interaction with some of the apps I’ve built than my old method. The old method consisted of lots of print-screens, ImageReady, and making an animated GIF. It wasn’t pretty, but it got the job done. In search of a better method I asked a friend of they had any ideas and he pointed me to the excellent vnc2swf package. A quick trip to go get the required Python libraries and a VNC server, and I was up and running. Here’s what I came up with today while experimenting.

Saving time with Ajax

A simple javascript event handler with a small regex, a short DB-enabled PHP script, and some reasonable error-handling makes it so you don’t even start filling out the form if a user doesn’t have proper paperwork on file. It’s neat and saves lots of time for all involved.

(Yes I’m posting this just because the planet has been too quiet lately.)

New Surveys

Much like the rest of the legacy code that still rattles around at ResTek, the old version of Surveys was a beast. Lots of SQL scattered throughout, poorly-implemented OO, invalid HTML, and a truly horrifying series of Javascript form submittal links. It was a scary place to try and bugfix, and not something that we were very thrilled about sharing. Surveys is pretty unique in that it is far and away our most popular shared application. We offer up a lot of the code that we’ve written and even host stuff for other departments on campus. No other application is used by as many people for as many things as Surveys.

It’s surprising that old Surveys survived as long as it did, a testament to the amount of quickfixes that we’d been able to shove into it to keep things moving along. As is my way from time to time I had become sick of it. Finishing up Answerline (as seen in “Done Done Done”, “So Close To Done”, “More New Answerline UI”, and “Rethinking Answerline”) gave me the ability to pick a new project. First in my crosshairs, Surveys.

Getting a handle on how I wanted the new interface for surveys to work wasn’t easy. My first choice was to have user-draggable questions that combined the old preview and edit modes into one seamless interface while also adding live updating for all the actions that used to require a page reload. In Old Surveys the page would reload if you: added a question; removed a question; changed a question’s type; added an answer; reordered questions, etc. It was frustrating to try and use, because the responsiveness just wans’t there. Feeling good about JavaScript after the Answerline Revamp, I tried to address all of these issues. The page reloads were simple, I’d replace them with degradable JavaScript making AJAX calls via my current favorite Library, SACK. It’s lightweight and just does the AJAX transport/receiving stuff. I’m a fan of lightweight libraries, the big ones like Prototype and Scriptaculous just don’t interest me that much. Too much overhead for what I’d need.

Back to New Surveys UI design decisions. My biggest regret about this project is that I was unable to get a flexible and fast enough drag/drop library for the list elements. Dragging the DOM stuff around was cake thanks to Aaron Boodman’s excellent DOM-Drag library. I found several wrappers for it that took care of limiting motion and shifting list elements around for me. It was awesome to see, but once I had it up and running the problems started to crop up. The ToolMan DHTML library looked like it would do everything I needed, and at first blush it worked flawlessly. The effect was really very slick and much more intuitive than selecting numbers from a drop down. Unfortunately, the shortcomings of the library made it impossible to keep. You couldn’t drag a question past the bottom or top edges of the screen, a deal-breaker any survey longer than a few questions. It also tended to apply the drag-drop to list elements within the main list. This was not particularly undesirable behavior, but proved to be so buggy as to be a liability instead of a feature. When I couldn’t get much of a response to my inquiries I had to eventually abandon my drag and drop dreams. It was a sad day. Fortunately the rest of my ideas had worked out well, allowing for New Surveys to be much faster when creating a new survey or editing a pre-existing one.

The creation of New Surveys required more attention to ease-of-use considerations than I’d run into before. I don’t recall ever purposefully designing a hard to use webpage, but as someone who is very comfortable with computers it’s quite easy for me to fall into the trap of designing for myself and not the end user. I had to pay careful attention to labelling and the organization of elements on the screen in an attempt to guide those who might not be as familiar with the system. Now that it’s out there and normal users are getting their hands dirty in it I’ve come to the realization that even my best UI efforts are not really enough. I wish I knew a UI expert that I could ask questions and have critique my stuff. I find the whole thought process behind that really interesting but a lack of real studying means that I mostly make slightly educated guesses.

I’m sure that everyone is bored to tears now, so I’ll post an image. Just one this time, because it took a while to make and I’m kinda tired at this point.

More new Answerline UI

New config editing method

Old style config editing worked ok, this is neater. Idea totally stolen from Flickr. The alignment is a recent CSS bug that I haven’t gotten around to fixing yet, it’ll line up better in a bit.

Rethinking Answerline

A big (omg huge big) part of this whole Answerline re-writing was coming up with a new, sleeker interface for people to interact with. The old interface was nice to look at and an awesome clean design thanks to gunner’s mad design skills, but ended up having some usability issues. The small text underneath the student name was tough to read and emphasized the field, not the value. In an attempt to remedy this, I created a new way of display tickets. Not only is this display smaller vertically, but it reduces the required number of buttons and makes important information easier to find.

The other big change is the switch from a traditional paged interface where each button click takes you to a new page. Due to our small user set, we can require certain things. Javascript is one of those, and that allows for a more interactive and dynamic user interface. Thanks to the awesomely simple Simple Ajax Code Kit (haha sack), integrating AJAX functionality into Answerline has been pretty simple. I’ve tried to follow the guidelines of unobtrusive javascript. Lots of adding event handlers on page load, etc. It’s worked out great, and allows the page to function in a limited capacity even without javascript.

There’s an animation of a sample workflow down at the bottom of the post. Assuming the user has javascript the “Ticket Detail” button expands the ticket from the compressed first/last display to show all the comments on that ticket. It also includes two sections at the bottom. On the left is a form for adding a comment, assigning the ticket, changing tier or closing the ticket. The right side is the old email popup transformed and shrunk down. Both of these will modify the ticket (emailing adds a comment w/ email body and pertinent details) and then in-place reload the ticket with the new information. The animation shows adding a comment w/ no actual text. This isn’t such a big deal any more, as per Nick’s idea the safe comments are now much more visible. You can see the ticket reload itself to display the new comment, what may not be quite so obvious is that it also recalculates its border color and will redraw that depending on certain criteria.

So that begs the question, how does it work if a user has no javascript? Ignoring the lack of in-place content reloads the answer is “remarkably similar to the javascript version”. Hitting the Ticket Details button takes you to the Ticket Details page, which shows the same view as you see in the js version. The main difference is you’ve moved pages and now you only see the one ticket. Adding a comment will force a page reload, as will sending an email. That’s it, this whole unobtrusive javascript thing makes adding failovers for non-js browsers retardedly easy. As has been pointed out, I love XHTML 1.0 Strict and this page validates entirely. There is no javascript in the actual page, it’s all stored in an external .js file, so the code stays clean and lovely.

Old Answerline

New Answerline

Old Answerline interface New Answerline interface

Example of New Answerline Interactivity

Animated example of new Answerline interface