Tuesday, June 5, 2007

Come work with us!

We just updated our jobs page at work with some new positions. We're looking for great people to work with, including contractors, that are interested in doing kickass work for great clients.

http://terralever.com/about-us/careers

The flash positions are in the Phoenix or Tucson areas. All other positions are in the Phoenix area.

Peace!

Friday, June 1, 2007

Facebook Platform API for AS3, and group.

I mentioned briefly that we're building an api for working with Facebook's new Platform. As part of the 'release early, release often' open source mantra, we're releasing what we have right now. Its not fleshed out, but I think that the model that we've built is extensible and easy to use.

Download the API here

Our Facebook Group with more information, documentation, etc.


Here's some of our current features -

Authentication- The Facebook object handles authentication and security automatically. Its transparent, you just don't have to think about it.

Ease of use- Authentication can either be 'desktop' or 'web' style. This essentially means that you can test your app locally in desktop mode, and then deploy it web style. Our current testing model is to check a configuration xml to see what our authentication style should be:


if(configXML..mode == "desktop")
{
//start us up in desktop mode
var config_api_key:String = configXML..api_key;
var config_secret:String = configXML..secret;
fBook.startDesktopSession(config_api_key, config_secret);
}
else
{
//start us up in widget mode
fBook.startWidgetSession();
}

And so we deploy a different configXML file on our server which doesn't contain our secret for use in 'widget' mode, but we can test the flash locally, dramatically speeding development time!

Proxy support - When developing a Facebook application, you'll want to pass all requests to the Facebook API through your server for security reasons. This server should just mimic the Facebook api, and work in the same way:

fBook.useRedirectServer = true;
fBook.rest_url = configXML..redirect_server_url;

Extensibility - The Facebook AS3 object is extensible. This means that you can extend your proxy on the server with new methods, and extend the Facebook object with new FacebookDelegates to handle your application-specific service calls.


What we're currently looking at improving is fully implementing the Facebook API. After that we'll be adding more helper functions to improve the usability of the api. Things such as automatically grabbing all images in an album, etc.

Enjoy!!

Thursday, May 24, 2007

Facebook opens the gates! And they're off!

Well, about an hour ago, Facebook just announced their new Platform integration API. And we had an announcement ourself.

We've been having a TON of fun as a launch developer, seeing what's possible with their api. We've learned a lot of tricks along the way, specifically about integrating securely with a third party in a stateless REST environment. And all that we've learned should be released soon. We're developing an ActionScript 3 API for Platform, which we will be releasing soon.

Right now Jason is over in San Francisco taking part in a hack-a-thon with the Facebook guys. I knew I shouldn't have let him have all the fun. *sigh*

Why I like Facebook is the sort of 'extroverted internet' approach they've taken. I'm not a big MySpace fan, and a marginal extrovert myself. But I can understand what makes Facebook a great social application.

Facebook understands the concept of signal-to-noise ratio better than any existing social networking site. If you have to surf through tons of crap to find what you want, it makes it less accessible, and less valuable. Google understands this. Getting the user from point A to point B quickly is paramount to user experience. What about in the sphere of social networking? In terms of relationships, Facebook is speed dating, and MySpace is a noisy, loud night club.

Of course there is a place and time for both. Facebook has used discretion in allowing access to its users. It doesn't want to lose its integrity, and the high signal-to-noise ratio. But it has to be competitive on features, without opening the flood gates to the noobs. And so the new 'Applications' features have been developed.

Applications are Facebook's equivalent to MySpace codes. But unlike MySpace codes, which is basically just html, Facebook uses FBML to include html in its pages. Applications must also be registered with Facebook, requiring a certain level of proficiency, and removing anonymity from the application developer. That's important when you've got 27 million+ users to keep secure.

Overall I'm really happy to see a social networking platform rolled out that has this kind of smarts. We'll see where it goes from here!

Centering in Safari and IE off by one pixel

If the size of the browser window is an odd number, you'll run into problems with the centering not matching the centering of your html. A friend of mine needed this fixed, as his page elements could not match up with the background. This fix here suggests resizing the browser window to fix the problem. Well, while that is feasible workaround, I'm not sure how usable it is for a user to have their browser modified like this.

And so I cobbled together some javascript for him that basically overrides the background positioning and centers it manually via javascript. Like so:


function positionBackground(){
//set this to the width of your background image
var backgroundImageWidth = 760;

var size = getPageSize();
var body = document.body;
if( navigator.userAgent.indexOf('Safari') != -1 || navigator.appVersion.indexOf("MSIE") != -1)
{
if(size.width % 2 == 1){
size.width -= 1;
}
}

body.style.backgroundPosition = size.width/2 - (backgroundImageWidth / 2);
}

function getPageSize() {
var myWidth = 0, myHeight = 0;
if( typeof( window.innerWidth ) == 'number' ) {
//Non-IE
myWidth = window.innerWidth;
myHeight = window.innerHeight;
} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
//IE 6+ in 'standards compliant mode'
myWidth = document.documentElement.clientWidth;
myHeight = document.documentElement.clientHeight;
} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
//IE 4 compatible
myWidth = document.body.clientWidth;
myHeight = document.body.clientHeight;
}
return {width:myWidth,height:myHeight};
}

window.onresize = positionBackground;
window.onload = positionBackground;


Unfortunately you're required to input the background image's width by hand, but since this is usually consistent I think its acceptable.

Alas, I'm really unsure that this is a better way of thinking about how to fix things. It really bothers me that the current mentality for rigorous CSS and tableless layouts requires such elaborate javascript fixes to get them to work. But that is a topic for another rant. :)

Tuesday, May 22, 2007

Cool trick: Re-instating deleted files in subversion.

One of the problems with version control in general is dealing with large amounts of binary data. If you add a large chunk of data, say an image sequence, its in there...for good*. If you delete it, and you want it back, well, is it possible to get it back without having to put it back in, increasing the size of the repository? With Subversion you can.

Earlier today we had a subcontractor who's new to using Subversion make the classic subversion mistake: copying a directory using Windows Explorer's copy and paste, instead of using Tortoise. So he copied his files to a new location, then used TortoiseSVN->Delete to remove the files from the repo, and supposedly committed his updates (which didn't move any files like he thought). When we asked him where the files went he was like 'i can see them'. So I went ahead and im'ed back 'i'll fix it'.

I reverted just the deleted branch to before he deleted the files. Then I moved them to where I wanted them to be in the current branch using the proper right-click and drag method with Tortoise.

The 'cool' part of this is that I'm actually moving files that aren't part of the current revision, and don't even exist in the current revision, from a previous revision. Remember that in Subversion all file revisions are really just links with data attached. All I'm doing is telling Subversion to link the data from a previous version to the latest revision, and Subversion just does what its told. Awesome!

* It is possible to use stream editing to remove files from SVN repositories, if you are braver than me.

Monday, April 16, 2007

jEdit Flex Compiler Shell Integration

Last night I stumbled across a great little hack that's really been a missing piece of the Flex action for me. Flex Builder's zippy compilation is one of the best features of the commercial Flex product, and one I sorely missed. But now I've figured a way to integrate the Flex Compiler Shell into jEdit, and so now my text editor of choice works very well with my compiler of choice.

jEdit's Console plugin allows you to integrate a shell into the interface. This shell is scriptable via jEdit's quite extensible macros. So we have two macros, one to initialize the compiler shell, and another to re-compile once initialized.

First macro:

//Initiate the compiler
runCommandInConsole(view,"System","/path/to/fcsh");
runCommandInConsole(view,"System","mxmlc ... very long list of arguments for your compile :P ...");

Recompile macro, bound to Ctrl-Enter:

runCommandInConsole(view,"System","compile 1");

This makes me a very happy boy! I have verified that these instructions should work on Windows, too (as I'm doing this on Linux).

Wednesday, April 11, 2007

Trace Output on Linux with Flash Player 9

I just spent about 45 minutes getting my flash player to trace to a text file. So as of this writing, here are the current things that you should watch out for when attempting to trace() out with flash on linux:

Make sure that you have the debugger version installed. If you are using Ubuntu, or another distro that uses package management, remove the flash player package. On Ubuntu Feisty Fawn, this is the flashplugin-nonfree package. Open synaptic and uncheck the package. It will warn you that you are removing the ubuntu-restricted-extras package also. Don't worry about this, as its a dummy package.

Install the debugger version from the adobe site. This is pretty straightforward.

Once installed, you must turn on the trace reporting by creating a file in your home directory called mm.cfg with the following contents:

TraceOutputFileEnable=1
ErrorReportingEnable=1
MaxWarnings=1

So what exactly will these three lines do? Well the first says that we should print out all trace() function calls to the file ~/.macromedia/Flash_Player/Logs/flashlog.txt. The second option says that we should also print out our stack traces and exceptions to the log file. Lastly MaxWarnings is how many lines the log file will contain until the player stops. This page goes more in depth.

A couple important points: The documentation is incorrect, and the output file is NOT ~/macromedia/Flash_Player/Logs/flashlog.txt but ~/.macromedia/Flash_Player/Logs/flashlog.txt . This is important because files with a '.' in front are hidden, so you won't see a 'macromedia' folder pop up in your home dir.

Secondly, the flash player is smart enough to create the ~/.macromedia/Flash_Player/Logs/flashlog.txt path, directories and all. So you do not need to create this path manually.

Ok, so now you've installed the debug version, and you've created your mm.cfg. Your logging to the file, and now you want to watch the output! Well, you have many options at your disposal. A favorite option is the FlashTracer extension for FireFox. Here is a special version that works on Linux.

Another option is to use 'tail' a basic command line program that displays the tail end of files:

tail -f ~/.macromedia/Flash_Player/Logs/flashlog.txt

As with all command line programs, you can pipe them to do fun interesting things :)

tail -f ~/.macromedia/Flash_Player/Logs/flashlog.txt | grep DEBUG

To just get all the lines with DEBUG on them.

tail -f ~/.macromedia/Flash_Player/Logs/flashlog.txt | grep -C 3 DEBUG

Get the lines that have DEBUG on them, and the lines around them (useful for seeing what happened before and after the line in question).

And here is a simple script that encapsulates the above tail usage into a simple program:

#!/bin/bash
if [ -z "$1" ]
then
tail -f ~/.macromedia/Flash_Player/Logs/flashlog.txt
else
tail -f ~/.macromedia/Flash_Player/Logs/flashlog.txt | grep $1
fi