Welcome to MSDN Blogs Sign in | Join | Help

I'm no longer posting at this URL and all future posts will be made at http://rhizohm.net/irhetoric. Please update your RSS.  Thanks!

Awhile back, for MIX, Tim Aidlin and I built Flitterbook.  We liked it so much that we now have version 2, renamed Flotzam, ready for your consumption.  Lots of improvements, including a new UI, RSS support, Facebook notifications and complete configuration control. Also, check out the Silverlight-created video that is a screen capture of the application in action.  So, we'd love for you to go check it out, let us know what you think on the Flotzam forum and watch the Flotzam blog.

One area that is currently top of mind for me is designer and developer collaboration with WPF and Expression Blend, in particular around animation.  I'd like to start documenting some techniques and outlining things that can and can't be done.  

Before diving in, let's quickly review the animation system in WPF.  The two ways to do animation in WPF is either declaratively (XAML) or procedurally (code).   If you use Expression Blend to create your animations, you will be in effect using the declarative (XAML) method.  What gets slightly confusing is that the two methods, declarative and procedural, are not entirely in parallel.  For example, the only way to begin an animation declaratively (XAML) is through the <BeginStoryboard> tag.  However, the equivalent call in code is to call the Begin method off a UIElement and  passing it the storyboard to fire.  The other option is to call the Begin method from a storyboard itself, passing it the UIElement to which the storyboard should be applied. And, in code, you can trigger animations that don't even have storyboards using the ApplyAnimationClock or BeginAnimation directly off a UIElement.  (More on this later if you're confused. The syntax is, like much of WPF, a little tricky.)

But all of the above -- and much of the SDK documentation on animation -- assumes that you have chosen either one or the other.  What happens if you want to mix and match these two methods?  This particularly comes into play if you are working on a project where animations get created in Blend but then need to be manipulated, triggered and recontextualized from code.  And it potentially gets more tricky if you have multiple people working on the project, the classic scenario being one person who creates the animations in Blend and another who works with those animations in code.

So, let's look at the possibilities:

1. How to trigger a storyboard from code that was created in Blend.

Let's say we have an animation in Blend to do an opacity fade on an image.  Assuming it was created  by creating a new timeline and leave the "Create as a resource" checkbox checked, we can get at it from code pretty easily.Simply grab the storyboard from the resources, cast it appropriately and begin it. 

Storyboard s = (Storyboard) this.FindResource("FadeIn");
this.BeginStoryboard(s);

Now, the reason this works is that the storyboard itself contains information about the name of the object that it wants to animate.  If you look at the storyboard in the sample code I posted, it sets the Storyboard.TargetName value explicitly to the name "image".  Thus, when the storyboard is called from the page itself via BeginStoryboard, it is able to find the element named image and run the animations. But what happens if we want to generically apply that animation that was created in Blend to other elements?

2. How to trigger a storyboard from code and apply it to another UI element

Well, to accomplish this task, we need to start hacking XAML.  If this scares you, don't read on.  But the fact is that XAML generated from Blend sometimes needs a little love. So, in this case, we are going to copy that storyboard.  We can't do that without jumping into the XAML and manually coping the entire <Storyboard> and giving it a new x:Key. Once we've done that, we have manually remove every instance where Storyboard.TargetName is set.  Literally, remove the entire attribute. Now, we can apply this storyboard to any UIElement and not just images.  In this case, we call the Begin method from the storyboard itself, passing the element we want the storyboard to be applied to.

Storyboard s = (Storyboard)this.FindResource("FadeIn2");
s.Begin(textBlock);

The thing to watch out for with this technique is to make sure you call the storyboard on an element that in fact has all the properties referenced in the storyboard.  Otherwise, you'll get a runtime exception that says something like:

Additional information: '[Unknown]' property does not point to a DependencyObject in path '(0).(1).[0].(2)'.

Which is saying that the animation could find the property that it was told to animate.  A place where this can get you is if you are doing any Transform animations, such as Scale, Translate, Rotate or Skew.  By default, when you add an element to Blend, it does not create a TransformGroup for it. For example, go to Blend, add a Rectangle to the stage and see what it creates in XAML. It won't have a RenderTransform.  Now, go change its scale to 2 and then change it back to 1.  Now look at its XAML: a RenderTransform has been permanently added to it as a child which doesn't do anything! Blend counts on that TransformGroup for doing its animations, in that exact order (Scale, Skew, Rotate, Translate).  So, if you've created an animation that does a transform and you want to apply it to some other element, be sure that the element has a TransformGroup with the four transforms.

3. How to tweak an animation created in Blend on the fly in code

Let's say there's an animation created in Blend that you want to use, but you want to actually modify it with some dynamic values at runtime, maybe adding more animation.  First, you grab the storyboard and clone it so you have a new instance to party on. Then, you create your animation in code -- that's where you could insert dynamic variables.  Finally, you have to create a property path to the value you want animated.  The syntax is a little goofy, but once you crack its code as far as a path (good doc here) you'll be off and running.  Here's the code I used to add a scale animation on the fly:

Storyboard s = ((Storyboard)this.FindResource("FadeIn2")).Clone();
DoubleAnimation da = new DoubleAnimation(0, 1, TimeSpan.FromSeconds(1), FillBehavior.HoldEnd);
Storyboard.SetTargetProperty(da, new PropertyPath("(0).(1).[0].(2)", UIElement.RenderTransformProperty,
TransformGroup.ChildrenProperty,
ScaleTransform.ScaleXProperty));
s.Children.Add(da);
s.Begin(rectangle);

You could use a similar technique to crack into the storyboard, grab an animation that was created in XAML and tweak it.  So for example, we could grab the animation from the storyboard and change its begin time like this:

DoubleAnimationUsingKeyFrames d = (DoubleAnimationUsingKeyFrames)s.Children[0];
d.BeginTime = TimeSpan.FromSeconds(.5);

4. How to crack into an animation that is part of a DataTemplate

Doh! You can't!  I tried every workaround I could, but once a ContentTemplate gets loaded, it is in the WPF terminology "Sealed" and I've never seen a way to make it unsealed, even before it is added to the visual tree.  Bummer.

**********************************

So where are we?  We've learned some techniques such that a design technologist or interactive designer or diviner (or whatever they are called) can work in Blend, creating subtle and great animations and then, if there are scenarios where the developer or integrator or diviner (or whatever they are called) needs to start that animation, reuse that animation or tweak that animation on the fly, they can. Go WPF!

Download the code

It was two weeks ago that Microsoft released the Microsoft Facebook Toolkit.  The response has been great and an wiki popped up that people in the community were using to make enhancements to the toolkit and make fixes.  As a result, Clarity Consulting (who developed the original toolkit for Microsoft) has posted the toolkit to Codeplex.  This now formalizes a way for the toolkit to continue to evolve and, even better, for all developers to get the latest and greatest toolkit without having to go manually make the fixes based on the wiki.

I've been meaning to document how I wrapped the Twitter API ... in 4.5 seconds.   There is a very powerful feature in .NET is a tool in the sdk called xsd.exe.  Darren David actually has a fabulous post on exactly the power of this tool: never touch a DOM or XPATH again!   His post explains what is happening under the hood with xsd.exe quite nicely. I'd definitely recommend reading his post.  I figured it might be interesting for folks to see the exact steps I took to wrap the Twitter API:

1. Grab an instance of the public timeline from Twitter and pass that to xsd.exe to infer a schema as follows: xsd http://twitter.com/statuses/public_timeline.xml which creates public_timeline.xsd

3. Use the inferred schema to generate classes: xsd public_timeline.xsd

4. Walla!  We now have a class to party on called public_timeline.cs

5. To instantiate the class with live data, it is as simple as the following:

System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(statuses));

statuses s = serializer.Deserialize(new System.Xml.XmlTextReader("http://twitter.com/statuses/public_timeline.xml")) as statuses;

And there you have it.  No DOM, no XPATH, no RegEx.  Now, if we want to take this wrapper to the next level, there are a few things we can do.  First, you will notice that Twitter returns the data as a string.  That's kind of a bummer; it would be nice to have it as a strongly typed DateTime.  Here's the line of code to do that:

DateTime date = DateTime.ParseExact(s.created_at, "ddd MMM dd HH:mm:ss zzzzz yyyy", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);

Another thing that you'll need to do is authenticate when you contact Twitter if you want data other than the public timeline.  Here's how to do that:

using (WebClient client = new WebClient())
{
client.Credentials = new NetworkCredential(TWITTER_USERNAME, TWITTER_PASSWORD);
statuses s = serializer.Deserialize(client.OpenRead(TWITTER_URL)) as statuses;
}

Of course, the TWITTER variables need to be set with the username, password and particular URL to the Twitter feed you are looking for. 

Another thing to think about doing is making the calls to Twitter on a different thread.  My recommendation for doing that is to implement Dan Crevier's Data-View-View Model.  This frees the UI thread from any calls to Twitter and provides a really nice model for marshalling data between the threads.  In fact, I did just this in my Flitter and Flitterbook implementations, which you can check out in the source code.

The final thing to think about, which I just recently implemented in some code I was working on, was to make the naming conventions look prettier.  Darren David alluded to this in his post but he's been so busy with the totally amazing HP Multi Touch kiosk he built (which you have to check out the videos for if you haven't yet) that he hasn't posted his part II.  But I imagine he's going to talk about using partial classes so as to make the class look prettier without touching the generated code.  This came in real handy with the Twitter API which generated some code with ugly array structures that I wasn't so keen on. I also had a need to use a kind of cool feature of WPF databinding where I wanted to reuse a datatemplate between two different objects (Twitter status and Facebook status) by just having them share names, such as AvatarURL, rather than create two templates that were fundamentally identitcal except for the data object. As such, I created a partial class with a bunch of getters as follows:

public partial class statusesStatus
{
public DateTime Date
{
get
{
return DateTime.ParseExact((string)this.created_at, "ddd MMM dd HH:mm:ss zzzzz yyyy", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
}
}

public string AvatarUrl
{
get
{
return this.user[0].profile_image_url;
}
}

public string Text
{
get
{
return this.text;
}
}

public string UserName
{
get
{
return this.user[0].screen_name;
}
}

public string Location
{
get
{
return this.user[0].location;
}
}

}

Now I have a much prettier class without touching the generated code from xsd.exe.  Sorry for stealing Part II Darren. I couldn't help myself, as I have been meaning to write this post for about 2 months!

A new version of the WPF Performance Profiling tools has been posted, x86 and x64, as an .msi. These tools were previously only available in the beta .NET Framework 3.5 SDK, but that is a rather hefty dowload at over 1 gig.  Now, you can get at these invaluable tools as a simple download which is less than 1mg.  If you are a WPF developer and aren't using these tools, download immediately!  If you are using the existing wpfperf.exe tools, the recommendation is to move to the new version of the tools. Happy profiling -- and watch out for those bitmap effects!

 

This post has nothing to do with WPF, Expression, Silverlight, Vista or pixels. Rather, it has to do with web service discovery and with my former role at Microsoft in working with UDDI. I had a bunch of resources up on GotDotNet which I have had to migrate with the phase-out of GotDotNet.  These resources include a couple of interesting white papers I wrote on using UDDI to catalog RSS, how to register RSS in the Windows Server implementation of UDDI and a WinForms sample using the UDDI SDK to read and publish blogs to UDDI.  (I'm still proud of these!) Also included in these resources is my UDDI blog, which has some nice nuggets including "The Strange and Curious World of tModels".  Lastly, there is a UDDI resources page.

My UDDI blog is also evidence that I was blogging as a Microsoft employee back in 2002, using Don Box's spoutlet codebase, which was a super simple and elegant RSS engine that uses XML and XSL to provide both HTML and RSS compliant XML, 1.0 of course given the time this was written.  I also find it amusing that I posted an entry where John Udell complains about the lack of Microsoft bloggers. He now is on a sister team with me at Microsoft.  Funny.

I'm here at the Facebook Developer's event down here in San Francisco.  Dan'l Lewin from Microsoft was on stage as a parter:

Lots of good stuff announced as far as Facebook/Microsoft partnership: Microsoft just released a great wrapper to the Facebook API written by the guys at Clarity Consulting.  They've got some nice sample applications, including a cool WPF app that is a rolodex of your Facebook contacts.


Also, Popfly also added support for the Facebook API to their mashup builder.  Speaking of Silverlight, there's support for Silverlight in FBML via the FB:Silverlight tag, although it is undocumented right now and not quite there.  However, you can host Silverlight in an iframe using FBML.  More on that to come.

I implemented in an updated version of Flitterbook, which you can download here.  This version of Flitterbook now has support for the Facebook API and pulls all images from your friends along with Twitter feeds and Flickr data.  Again, this is still alpha code: no promises!

One thing I implemented in Flitterbook is support for infinite sessions with Facebook.  There aren't any code samples for this in the samples that ship with the Facebook  Developer Toolkit so I thought it might be useful for other folks. I save the Facebook infinite session data in a user config file using Visual Studio. The crux is that you have to pass your own secret if you don't have a secret that gets returned from Facebook to support an infinite session.  Here's the code:

//set infinite session parameters on to facebook data adapter
if (Settings.Default.IsFacebookInfiniteSession)
{
  facebookConnect.UserId = Settings.Default.FACEBOOK_USERID;
  facebookConnect.SessionKey = Settings.Default.FACEBOOK_SESSIONKEY;
  //note here that we pass the secret that we saved
  facebookConnect.Secret = Settings.Default.FACEBOOK_SECRET;
}
else
{
  //if we don't have an infinite session, we use my application's secret
  facebookConnect.Secret = secret;
  //we invoke the UI dialog
  facebookConnect.ConnectToFacebook();
  //if the user let us save their session, throw it in config
  if (!facebookConnect.SessionExpires)
  {
    Settings.Default.FACEBOOK_SESSIONKEY = facebookConnect.SessionKey;
    Settings.Default.FACEBOOK_USERID = facebookConnect.UserId;
    Settings.Default.FACEBOOK_SECRET = facebookConnect.Secret;
    Settings.Default.IsFacebookInfiniteSession = true;
    Settings.Default.Save();
  }
}

I just posted three new hands-on labs for Expression Blend that were created for MIX but haven't been posted for the world yet. There's lots of little nuggets in there worth checking out, things like creating a user controls, databinding, triggers, styling controls, using web services, paging, data input and more.  The more I use Blend, the more I love it, but it has its own learning curve, above and beyond WPF.

The first lab is a UI for Windows Live Search, including Image Search.

The second lab is a color swatch lab.

The third lab is a recipe viewer application.

I'm very interested in the phenomenon of Twitter.  In this piece, I want to write about a particular aspect of Twitter and the one that I'm most familiar with, the usage of Twitter at conferences.  In fact, I was first turned on to Twitter at South by Southwest Interactive. They had monitors scattered about the conference with a visualization of everyone who was using Twitter at the conference.  Thought balloons would float by with the person's icon, realtime.  In fact, here is a screenshot of my ego-twitter:

What I liked about this visualization while I was at the conference was the the realtime commentary that the visualization provided: about sessions (good and bad), about parties (especially unannounced ones), about any ancillary things happening.   The other nifty thing about the visualization was the social networking aspect, in that if you saw a twitter that interested you, it was easy to subscribe to that person's feed right from your cellphone and start getting that person's twitter feed pushed to you.  In fact, the crux of twitter at a conference is the SMS aspect.  The ability to interact immediately with the "cloud" right from your cellphone, both to comment and to receive comments, is the power of Twitter at a conference.  Not only can the conference organizers push information to attendees, but attendees can create their own web of connections.

I was inspired by the visualization at SxSW and decided to write my own.  You can see the first cut here which I called Twitterpated (run it or download source here).  Note that you'll need the .NET Framework 3.0 to run it if you are on XP.

 

There's lots of goofy code in there, so please beware!  Classic case of having to write an app the first time and fail in order to write it correctly.  I went about the animations in the wrong way, trying to animate from off the screen using an itemscontrol. Also, I only fetch the Twitter data once and never implemented a real data model.  But I figured I'd post it in case there was something useful for someone. 

All of this happened pre-MIX.  It was the logical next step to do something similar for MIX.  In talking with Beth Goza, I realized there were other social networking aspects being promoted for MIX, including Flickr and Facebook.  As such, I wanted my visualization to pull not only Twitter, but these other feeds.  It turned out my architecture made this trivial, using WPF (more on the technical details of this in a future post.) I also wanted to bring in a designer to help with the visuals, thus Tim Aidlin's work on the project. Not only has this immensely improved the look and feel of the app, but also has given me more experience with designer/developer workflow using Expression (more on that in a later post as well.)

The result was Flitterbook.  It ended up at two places at MIX.  The first place was before the keynotes on the big screen:

 

It was great to see it up on the big screen and really funny to see people figure out that they could ego twitter realtime.  Many people commented on the band, both favorably and unfavorably, which was hilarious ("too much accordion for this early in the morning"). 

The other place it was at MIX was as a screensaver on all machines available to attendees for Internet access, similar to SxSW:

One technical note if you are interested in using this code for your conference.  For all of this to work, you need to make sure that you create a Twitter account for your conference and then have attendees FOLLOW that account.  So, for MIX, we had an account called MIX07.  Then, the visualizer pulled a feed of all the followers.  To pull this feed, the application had to authenticate to Twitter with the MIX07 credentials.  You'd need to do something similar if you wanted to do this for another conference.

Check out Lutz Roeder's Monotone -- very, very cool. 

Pay close attention to how tightly synched the animation is with the visuals. I've been digging into the source code and there are several techniques he uses that are worth calling out.  First, it is interesting to note how the entire logic of the experience is controled in code.  There is nothing in Page.xaml.  It is in the constructor of his Page class that he wires up his Loaded event and it is in the Loaded event where he uses the Downloader object to insure that the mp3 he wants to play is in fact downloaded.  He then starts the .mp3 playing on the Downloader_DownloadProgressChanged. If you watching carefully, you'll notice that he throws up a progress bar while the Downloader is running and he includes the code for the ProgressBar class, worth grabbing that source.  So why does he go to all this work instead of just assigning the mp3 to a MediaElement directly? Well, by handling the downloading of the mp3 himself, it ensures that he knows exactly when the music starts, so that his animations are exactly in synch, which if you notice, the timing is perfect as the squares animate in.

 He adds the first visual by dynamically loading his XAML file into the canvas with this code:

using (StreamReader reader = new StreamReader(this.GetType().Assembly.GetManifestResourceStream("Monotone.Grid.xaml")))
{
 this.Children.Add((Canvas) XamlReader.Load(reader.ReadToEnd()));
}

I include this because it isn't exactly intuitive code to write!  Sure, XmlReader.Load is not rocket science, but getting at the xaml file requires some arm twisting, as you can see.  Once the Grid.xaml file is loaded, its animations kick off based on an EventTrigger.  I'm sure he used Blend to create these animations.  In fact, if you open up the project in Blend, you'll see that you can run all the animations from within Blend.  However, here's one tricky part.  You can see there are two Storyboards nested within the Canvas.Loaded EventTrigger.  But the second storyboard's BeginTime happens to fall exactly at 6.85 seconds, which is timed for when the first storyboard ends.  Unfortunately, there isn't a way to set this value in Blend.  He probably just manually added it to the XAML.

The next part of the piece is a spiral math art animation.  But before how does he know to unload the grid.xaml and fire off the spiral animation?  He actually uses a timer!  You'll notice that he starts off an HtmlTimer right after he calls play on on the mp3.  The timer's interval is set here:

this.timer.Interval = (int)((60f / 140f) * 4 * 4 * 2 * 1000f);

Not sure why he couldn't just use the TimeSpan object and cast to (int), but Lutz will have to address that! Anyway, this is what he uses to then unload his Grid and load his custom Spiral class.  The Spiral class, which subclasses Canvas, does not use the Silverlight animation engine but rather wires up a timer for behavior similar to WPF's CompositionTarget.Render or Flash's OnEnterFrame.  Now, I must admit this code threw me for a loop:

double interval = ((60f / 140f) * 50f);
if (HtmlPage.BrowserInformation.Name != "Microsoft Internet Explorer")
{
 interval = interval * 1.461f;
}

Why did he have to special case IE when creating his timer?

For the spiral effect, he's using some trigonometry to create a new ellipse on each tick in such a way that a spiral is formed. Similarly, on each tick, he rotates the spiral.  At a certain point, he zooms and fades it.  And, when his other timer hits what is around 6.85 seconds, he yanks it from the VisualTree and inserts Stroposcope, which also is a timer based animation and also subclasses Canvas.  Within Strotoscope, he adds three instances of Ring, which is another canvas that is a  series of Ellipse objects that he then manipulates, again using trigonometry.  There is someother interesting code in there for getting the background to white out at certain points in the animation as far as watching where he is in the timer.

All in all, a great piece. The music is so tightly synched with the visuals.  Watch and listen closely and you'll see what I mean. Which raises the question: which came first?  The animation or the music? 

Technorati tags:

I just posted a high resolution copy of the WPF Momentum video shown during Ray Ozzie's MIX07 keynote for downloading.  If you don't want to take the 32mb download hit, you can always watch it streamed via Silverlight.

Kevin Moore very quietly released a new bag o' tricks that has two of the coolest controls for WPF that I've seen in awhile: transition and reveal. 

Transition is gnarly: it provides the infrastructure to create a visual transition between any two visuals in WPF.  These visuals could be controls, vector graphics, images, 3D or, really,  anything.  What is nice is that the architecture of the control is extensible, such that you can define a new transition quite easily.  There are a bunch of built in transitions, both 2D and 3D. Many of the 2D transitions are modeled after the stock transitions available in Windows Movie Maker.  (Some, like Rotate Wipe, remind me of the transitions in Star Wars, A New Hope.)  The 3D ones are quite nice and include cloth, page, doors and explode.

Reveal is also quite powerful.  Rather than a transition, it provides animation to reveal something -- anything -- in WPF.  This isn't just an opacity fade but rather a directional unveiling. For example, when clicking a treeview item, imagine the item animating in view instead of just appearing. 

Both of these controls are the kind of control that allows for people to write "better" UI, in the sense of UI that doesn't just slap the user around, but gracefully moves the user from state to state. Reminds me of the tagline that has been used in association with WPF: "build the UI of your dreams."

With the importance of using custom controls to create beautiful UI in mind, I implemented these controls in a new version of the Avalon Feature Fest, which is the 2nd most downloaded application up on http://wpf.netfx3.com/files/default.aspx.  You can run it here (beware it is a 16mb download because of the video.) It is downloaded that frequently for a reason: it is a great overview of WPF when giving a presentation and trying to explain what, in fact, WPF is.  As such, I added a new section called Custom Controls, where I show off Transition, Reveal and Zap Scroller.  The point being: WPF allows you to build incredibly powerful control above and beyond the controls "in the box".  The other point: other people are starting to build these controls and the ecosystem will start to thrive with great controls.  In fact, at MIX, there were a number of companies announcing just that.  And, knowing Kevin, expect more goodies to continue to end up in his bag o' tricks.

Here's some screenshots from the transition control of good old limecat in the middle of a 3D cloth transition:

Technorati tags: ,

Tim recently posted a list of all the Silverlight screencasts that are being hosted up on silverlight.net.  I authored five of them, all of which are focused on using Blend, which I fall more in love with each passing day. 

The first three, which you can find here and here and here, are pretty darned simple, showing different vector drawing tools in Blend and animation techinques in the service of making a vector chicken cluck.

The fourth, inspired by the recent studies that have reported the protein links between chickens and T. rex fossils, is not far from a lot of the work up at You're The Man Now Dog.    I was hoping to post it up at ytmnd.com, but they only allow you to post animated gifs and mp3s.  You can see it here.  (I wish I could embed it in this blog post, but I can't.  Bummer.)

For the last one, I needed some video content -- what better than footage I took myself ... of chickens. I used the new Silverlight streaming service to host the video.  It is a little confusing at first to use the service, as I didn't realize that they were hosting not only the video asset but javascript and xaml as well.  Thus, you have to .zip up all the files and include a manifest. Also, if you use Expression Media Encoder, you have to choose a template for your media. If you don't, you won't get all the nifty generated .js files that you need to create a video skin.  But once I figured that out, it was pretty simple.  You can see the results here.

(Updated 6/21) -- Please go check out http://flotzam.com which is the released incarnation of this software!

I just posted the screen saver source to Flitter here.

 

It is now entirely configurable, both for Flickr and Twitter. To install, right click on the .scr file and click Install.  Click the settings button from within the screen saver user interface to configure it. This runs ONLY on Windows XP, Windows Server 2003 and Windows Vista.  If you are on XP or Server, you'll need to download the .NET Framework: http://www.microsoft.com/downloads/details.aspx?familyid=10cc340b-f857-4a14-83f5-25634c3bf043&displaylang=en

This is definitely v.0.0.0.1.  Please provide feedback, issues, bugs and any thing else that comes to mind.

Note that I had to pull the Facebook integration (for now) because I am using a .NET wrapper to Facebook that hasn't been released just yet, but it is coming soon...

I'm using all kinds of other people's code in this:

In future posts, I'll go into a little more about how Tim Aidlin, the designer behind this, and I built it.

More Posts Next page »
 
Page view tracker