************************************************************************************
twitterAIR
Author: Aaron S. West (aaron@trajiklyhip.com, trajik210@gmail.com)
http://www.trajiklyhip.com/blog

twitterAIR was built using Flex Beta 3 and the Adobe Integrated Runtime Beta.
twitterAIR is still in development and there are bugs (see below). Your feedback
is welcome (positive or otherwise) and should be sent to the above e-mail address.

The Adobe Integrated Runtime (AIR) must be installed in order to use twitterAIR.
You can get AIR for either Windows or Mac here:
http://labs.adobe.com/downloads/air.html

FEATURES (Overview):
************************************************************************************
twitterAIR is an Adobe Integrated Runtime (AIR), Flex 3 application that integrates
with the services provided by twitter.com. Users can view the public Twitter timeline,
their friends tweets, and configure automatic refresh settings.

FEATURES (Detailed):
************************************************************************************
--Integration with twitter.com
All of the integration with twitter was done with custom HTTP calls and XML
processing. Twitter provides an AS3 API but it could use significant improvement as
it's lacking in several key areas. I only use the API for specifying the event handler
event types.

--Complete custom skinning and chrome
The design was created in Photoshop (png's) and pieced into Flex as a completely custom
"look and feel." This includes the background image, all buttons, chrome, logos,
scrollbars, and fonts (excluding the text input font). Also, there's no native
windowing elements in the app; all windowing mechanisms were written in AS3.
The scrollbars were created in PhotoShop and displayed via CSS.

--Embedded fonts
In order to provide as clean a UI as possible 3 typefaces are embedded into the
application and used in every area text shows (excluding the text input font).

--Date localization and manipulation
In order to display the "4 minutes ago" or "8 hours ago" text for each tweet some
cool date manipulation was written. This involved doing some minor conversions
between UTC time and the client's localized time and determining there difference
in milliseconds.  Then, configuring the text that says how old each tweet is when
compared to the client machine.

--View components
The settings window and error windows were created as view (the V in MVC) components.
All communication between these view components and the main application occur
via the Flash event model. The settings view component functions as an ItemRender
to a List component.

--Aggressive no-cache
The Twitter servers do a good job of caching data to the client. For an application
like Twitter, this can prove frustrating when you're trying to keep up with what
your friends are doing on Twitter. To combat this, I've employed some anti-caching
mechanisms to ensure each HTTP call to Twitter returns the most up-to-date tweets
possible.

--Custom Form Validation
In order to validate the form controls in the settings window, I wrote a custom
validation package/class that extends the Validator class and is fed by a defined
Model (vanilla XML with data binding). It's a decent example of validating an
entire Flex form with a custom validator and having results dispatched back to
the settings window via events. The tooltips that display when there are
form errors are skinned in CSS.

--File-system API integration
All information gathered in the settings window is stored on the client machine.
The username and password fields are encrypted to provide a small level of security.
You don't want anyone to obtain your Twitter username/password do you?

--AS3 Timer
The update minutes and seconds are configured into the proper milliseconds value
which is used as the source for a Timer instance. When the timer runs it executes
ActionScript that facilitates communication with Twitter. This can be retrieving
the public tweets or friends tweets. The timer is started and reset based on
different user activity in the app.

--Auto-update Frequency
Auto-update can be configured from 59 seconds to 1 hour to never. Of course, the user
can always force an update by pressing Refresh. I envisioned someone wanting to
refresh on a manual basis so this is accomplished by setting the update frequency to
0 minutes, 0 seconds, and then using the Refresh button. Keep in mind that at
the time this documentation was written Twitter was allowing a maximum of 70 HTTP
pings per hour per client. The auto-update settings are restricted to keep this
from happening, but the refresh button is not, so be careful or you might not
receive any tweets for awhile.

--Internet connectivity monitoring
Admittedly, the application does not utilize the connectivity monitoring provided
by AIR. However, network monitoring is accomplished and error messages will display
if you disconnect from the Internet.


THINGS THAT STILL AREN'T RIGHT (blatant issues):
************************************************************************************
The Settings TitleWindow and the form validation is not working like I want it to. I
would like to have the validation routine point to the field with the problem. This is
supposed to be possible with custom validators but I can't seem to get it working. The
built-in Flex CreditCardValidator, which extends Validator, *does* have this ability.
Since I can't get this working all error text displays in relation to one of the form fields.

I can't figure out how to get the red asterisks to be a different color. Also, when there
are validation errors there's a red outline around the Save Settings button. I'd like to
get these to be the blue color.

Fix the bug with the SettingsView error tooltip hanging around after resolving a form
error (like not supplying a username) and successfully filling out the form.


THINGS THAT COULD BE BETTER (All of these features are slated for version 2):
************************************************************************************
Create code that tracks the number of Twitter pings over the course of an hour. Stop allowing
users to refresh, and stop the pings when the number reaches 70 (within 60 mintes). Clear the
limitation tracker every 60 minutes. Doing this would keep people from reaching the limit and
having their requests (HTTP) blocked.

Fix the If-Modified-Since date code so it's dynamic based on the last time twitterAIR
pinged Twitter. Make it return 20 results though each time. So if one new tweet comes
in based on the If-Modified-Since timeframe, one tweet from the bottom of the list will
be removed.

Add code that utilizes the AIR connectivity API to sense when the user is offline and
halts the timer. Restart the timer when the user goes online.

Incorporate a 3rd party URL shortening mechanism and detect URL's in tweets.

Add the ability to "friend" people on the public timeline.

7.12.2007
Several people have requested the app be resizeable. Because the app is built on a fixed
design (fixed width and height on almost all externally loaded images) I don't think
this will be possible. Still looking into it though.

Add a way to direct message folks from within each tweet. Perhaps have an '@' logo that
can be clicked to load the users "@username" text in the inputbox.

When the entire 140 characters are used for a tweet, the enter key is not accepted
which keeps people from submitting their tweets.

CHANGELOG:
************************************************************************************
1.1.3 (September 29, 2007)
--Application has been recompiled to work with Beta 2 of the Adobe Integrated Runtime
being released on October 1, 2007 at MAX.

1.1.2 (July 29, 2007)
--Fixed a bug where clicking any link in a tweet would cause tweets to randomly lose
their text. As you scrolled up and down - with the scrollbar arrows or the scrollbar
track - tweet text would be missing from different and seemingly random messages. As
you continued scrolling, tweet text would be appear and disappear randomly. In order
to resolve this I had to switch from my custom HTMLText component to the built-in
Text component and dump the rollover affect on links.
--Fixed a bug where clicking the Twitter user links (http://twitter.com/[username])
in each tweet would open up two browser windows.
--Fixed a bug where the error pop-up window would be created more than once if several
errors occurred before the original error window was closed. When this happened there
was no way to get all the error windows closed.
--Added support for displaying the app name in the "from" text in the tweets displayed
on twitter.com. This was accomplished by working with the folks at Twitter to set up
the super secret (not really) handshake between the app and their servers. Thanks to
Alex at Twitter for taking care of this!!
--Added tooltip styling to areas of the tweet messages.

1.1.1 (July 16, 2007)
--The previous version (1.1.0) had the friends list hard-coded to my friends list.
This was testing code not removed before releasing 1.1.0. This has now been corrected.

1.1.0 (July 16, 2007)
--Added minimize button.
--Switched the twitterAIR and trajiklyhip.com logo positions.
--Added support for typing "@username" in the input box. If you begin a tweet with @username,
the typed username will be matched against your friends list.
--Added support for sending direct messages with "d username message."
--Added support for viewing direct messages. Press the DIRECT button to view your messages.
--Added hyperlink support for the twitter.com/username links in the top right of each
tweet. Clicking the text will now load the user's twitter page.
--Added support for the @username callouts and URL's. Any @username text and hyperlink
(http://, https://, or www) can now be clicked.
--Separated the e-mail and blog parts of the feedback text (in the Settings window)
so my e-mail address can be copied/pasted while my blog URL can still be clicked.
--Added support for version tracking. When new versions of the app are released you
will be prompted to update.

1.0.0 (June 30, 2007) - Initial Release


NO WARRANTY
************************************************************************************
Aaron West is furnishing this software "as is". Aaron West does not provide any warranty
of the item whatsoever, whether express, implied, or statutory, including, but not
limited to, any warranty of merchantability or fitness for a particular purpose or
any warranty that the contents of the item will be error-free.

In no respect shall Aaron West incur any liability for any damages, including, but
limited to, direct, indirect, special, or consequential damages arising out of,
resulting from, or any way connected to the use of this software, whether or not
based upon warranty, contract, tort, or otherwise; whether or not injury was
sustained by persons or property or otherwise; and whether or not loss was sustained
from, or arose out of, the results of, the software, or any services that may be
provided by Aaron West.