JabbrPhone: It’s like JabbR on your Phone

I like development, working with new technologies and Windows Phone and over the past few weeks I have been working on a project that combines all of these. I call it JabbrPhone, its a Windows Phone client for Jabbr (the signalR based developer chat site).

So why did I want to make a phone app for JabbR? Well simply, for fun and to try something new that I haven’t done before (in this instance its signalR).

For those who don’t know what signalR is:

Async signaling library for .NET to help build real-time, multi-user interactive web applications.

It really is an awesome library. The JabbR project is also based on this and open sourced on Github which was great for me to get started.

imageimageimageimage

The app isn’t too far off at the moment, still a bit to do before its officially released. Current functionality:

  • Login/Create user (/nick)
  • List rooms
  • Join a room
  • send messages to a room (and get responses)
  • List users in a room

Things left to do:

  • Lobby functions
  • User Actions
  • Handle links in messages better
  • support for private rooms

 

The source is available on github: https://github.com/dkarzon/JabbrPhone

Or download the xap from here: http://bit.ly/zTsCpu

abSee ‘ay be see’ – A/B Test library

I have often wondered “What if” when it comes design aspects of a website.

  • What if this button was green instead of blue?
  • What if I call it an upgrade instead of a purchase?
  • What if the background wasn’t as dark?
  • What if I make that notification flashing red instead of dark yellow?

You get the point…

So I’ve been working on an A/B testing library with the 1 goal of making it simple to insert tests into my web applications, thus abSee was born!

abSee is in NuGet so its pretty easy to install. (hurray!)

Its usage is simple enough also:

Firstly fire up an instance of the Tester, do so by calling the Start function. Or you could filter out certain users here to only show tests for them. (non-Admins etc.)

protected void Application_BeginRequest()
{
    ABTester.Start();
}

From there we can fire off tests to the User where ever we like by calling the Test function. Now to make a test we need to give it a name, this will be used to identify what we are testing in this specific instance. Then you give the function the different options and it will randomly select 1 for you as the output and save the result.

var output = ABTester.Test("MyTest1", "A", "B");

After running the test we then need to let the Tester know if it was successful or not so we can track conversions of the different options. We do this by calling the Convert function with the test name from the test we ran before. abSee will then store that result for us as converted.

ABTester.Convert("MyTest1");

So now we are running tests, how do I see the results?

You can get results for a given test using the GetResults function, this function returns a list of ABSeeResult which contains a few details about the test instance as well as the option that was selected and if it was converted or not.

var results = abSee.ABTester.GetResults("MyTest1");

 

More detailed documentation is coming soon with details on implementing custom storage and user identification.

Feel free to leave me some feedback about abSee or even fork it on Github.

BoxShot v2.0: Mango, Logo, Pictures hub and more

So I got a fair bit of feedback from the old BoxShot logo and how most of my users disliked it (some even called it offensive). Now that I’ve had my fun I decided to put together a serious update for the app, here is what this new update (that I am calling v2.0) includes:

Icon173

NEW LOGO!

As mentioned before I have changed the logo, this gives the app a more professional look and fits in much better with the Metro UI of Windows Phone. Hope you all like it.

 

 

Its now Mango…

This version is build for Mango so it takes advantage of fast app switching and general Mango goodness.

Picture Hub Integration

BoxShot now integrates into the Pictures Hub, so you can share your photos through BoxShot to your dropbox folder.

New Dropbox API

Dropbox have recently updated their API to be more secure. For a user this pretty much means the login process has changed, so now instead of giving the app the Email and Password you login to the dropbox mobile site and give permission to BoxShot.Tile - Copy

Background Live Tile

The Live Tiles are now generated on the phone itself with a background agent, this makes them much more stable.

EmulatorContentsWhite

Referrals

BoxShot now lets you send out referral links to email or social networks so you can get that extra free space!

Others?

  • Some UI fixes (better following the metro style guide)
  • Few bug fixes (to do with ads and the tile colour picker)
  • Picture view now rotates and can pinch to zoom

 

 

 

 

 

Download it now from the Windows Phone Marketplace!

Ad-Free Version:

Free Version:

 

Future Versions

I’m always open to feedback about what new features users would like to see but heres a list of whats on the roadmap.

  • Pin Folders to start screen (maybe files as well)
  • Thumbnails for pictures
  • Fix bug when uploading files with international characters

Update:

All of the above features have now been implemented in v2.2 (Thumbnails and international characters fixed in v2.1)

PurpleSmoke: Ecommerce for SkyPoint

So in my day job I work for a company called Ardent Leisure, and lately I have been working on a massive project to build an integrated ecommerce engine for SkyPoint, Dreamworld and WhiteWater World. I thought I might take some time to talk about the technologies used here, being a .NET developer I kept pretty close to the Microsoft Stack, with a few open source libraries in the mix.

framework Microsoft ASP.NET
language C# (.NET v4.0)
development environment Visual Studio 2010
web frameworks ASP.NET MVC3
client side framework JQuery (+ UI and tmpl)
Knockout
web service layer Windows Communication Framework
database SQL Server 2008 R2
data access layer LINQ to SQL
source control Team Foundation Server 2010

 

3rd Party Tools:

 

Winning Combinations:

For me their are a few winning combinations here:

1. RestSharp + Newtonsoft JSON.NET + WCF.

Now my love for RestSharp has been widely documented but I cant say it enough, this is an awesome library and using it with a WCF web service was great. However this combination is not without its flaws, mianly DateTimes in WCF. But I was able to get around this “Feature” by creating my own WCFDate Class which serialises to and from a formatted string. This was quite a hack but its working pretty well for us at the moment.

2. Knockout + Jquery + tmpl.

This was the first project that I have actually used Knockout for and it did take some time to get up to speed on how it all works together but now I couldn’t imagine doing this project without it. It gave us the flexibility we needed to display the data we needed where ever we wanted.

 

You can find PurpleSmoke lurking among the CMS Pages at www.skypoint.com.au

From TFS to Private NuGet

Let me start by saying this: I love NuGet, its straight up awesome!

This post is about how I created a TFS CI Build to create NuGet packages and push them to a private NuGet server hosted on site.

I have been playing around with the TFS Build server, mainly for a Continuous Integration (CI) build on some of our projects and I wanted a way for me to be able to update a core library and have it propagated to all of the projects that use that library without them all needing to be in the same solution.

The answer was a private NuGet server with a CI build that automatically packaged my library.

I started by setting up a private NuGet server, reading Phil Haack’s post about hosting a simple package feed. Once that was done I could start pumping out packages!

Now that I have my NuGet server I need to setup the build. I created an Ardent.CommonBuild.proj for my build config and tasks. I found its easier to manage as a separate file to the actual project file, this file has to be a .sln or .*proj file for the TFS Build server to be able to run it.

image

Now I also wanted to control the version numbers of the packages being pushed out (both manually and automatic). So I set a major and minor version property at the top.

<PropertyGroup>
    <VersionMajor>0</VersionMajor>
    <VersionMinor>1</VersionMinor>
</PropertyGroup>

I then wanted to include the TFS Changeset number as the 3rd part of the version. So I kicked off a TfsVersion task which outputs the changeset number of a specific path (Set this to the project root to get all changes).

<TfsVersion
  TfsLibraryLocation="C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\ReferenceAssemblies\v2.0"
  LocalPath="$(MSBuildProjectDirectory)">
  <Output TaskParameter="Changeset" PropertyName="ChangesetNumber"/>
</TfsVersion>

From there I build the Project, normally the TFS build outputs the dlls to a binaries folder in the build output folder, but I decided to skip the nuspec file step but pointing NuGet at the project file directly. However you could create a nuspec file and point that to the built dlls, your choice. I also set the version number here for the build.

<MSBuild Projects="$(MSBuildProjectDirectory)\Ardent.Common\Ardent.Common.csproj"
    Targets="Build"
    Properties="Configuration=Debug;
      OutDir=$(MSBuildProjectDirectory)\Ardent.Common\Bin\Debug\;
    ApplicationVersion=$(VersionMajor).$(VersionMinor).$(ChangesetNumber)" />

So now we have built our project and we have the version we want so lets create the package. Using the Exec function I then run the NuGet.exe pack command on my project file using the –Version flag to set the version of the package. I also cheated a bit here by setting the –OutputDirectory flag and pointing that to the packages folder on the NuGet server I created. This will populate the feed now with the new package.

<Exec Command="C:\NuGet\NuGet.exe pack $(MSBuildProjectDirectory)\Ardent.Common\Ardent.Common.csproj -Version $(VersionMajor).$(VersionMinor).$(ChangesetNumber) -OutputDirectory \\grp-dev02\f$\Websites\Ardent.NuGet\Packages"></Exec>

The only thing left to do is create a TFS build definition under that points to my Ardent.CommonBuild.proj file in source control set the definition to CI mode. Done!

image

Now for every check-in to that project in TFS I get a new package created with the updated code then NuGet handles the updates in all of my other projects.

image

Life is good…

BoxShot gets a live tile!

Following the recent release of my Windows Phone 7 app BoxShot, I have implemented a live tile displaying your dropbox.com quota info.

Boring old tile Fancy new tile Another fancy new tile
Default Blue Pink

 

Screen3Also, you can customise the colour of the tile from the settings screen.

Thats pretty much it for now, be sure to leave feedback for any new features you want!

BoxShot – Its like Dropbox on your phone…

BoxShotPanoramaPhone

BoxShot is a dropbox app for Windows Phone 7.

Screen1

Features:

  • Open files from your Dropbox using their default apps (Office files, PDFs, etc.)
  • View/Edit text files within BoxShot with the built in editor
  • View Image files within BoxShot and save them to your library
  • Copy/Move files or folders within your dropbox folder
  • Delete files or folder from your Dropbox folder
  • Rename files or folders in your Dropbox folder
  • Email a public file link
  • View Account usage information

 

 

 

 

Screen2BoxShot also lets you add your frequently used folder to a favourites list which are displayed on the main Panorama.

Premium Version:

Free Version:

DateTime + WCF: How I tamed the beast

I have been working a bit with WCF lately and like everyone else use Json with WCF I ran into some issues with DateTime formats. I kept trying to find a valid solution to this where it outputted a readable value.

Eventually I started outputting the DateTime as a formatted string and this worked, but it meant I have to create new string variables in all of my classes instead of the DateTimes that I already had and was using, but then I still needed the variable in its DateTime form.

So I came up with the WCFDate class, at its heart this class outputs a string in a set format, this allows it to be easily read by what ever needs to. I could then replace all of my DateTimes with WCFDate and all was good in the world.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;

/// <summary>
/// Class to help get around the craziness of WCF DateTime formats (Use this class instead of DateTime for WebService Models)
/// </summary>
public class WCFDate
{

    public static string DateTimeFormat = "yyyy-MM-dd hh:mm:ss zz";

    /// <summary>
    /// The Date as a formatted string
    /// </summary>
    public string Data { get; set; }

    /// <summary>
    /// Basic constructor (with no value)
    /// </summary>
    public WCFDate() { }
    /// <summary>
    /// String constructor setting a Formatted string for the DateTime
    /// </summary>
    /// <param name="data"></param>
    public WCFDate(string data)
    {
        Data = data;
    }
    /// <summary>
    /// DateTime constructor, sets the Data to the formatted String from the DateTime
    /// </summary>
    /// <param name="date"></param>
    public WCFDate(DateTime date)
    {
        Data = date.ToString(DateTimeFormat);
    }

    /// <summary>
    /// DateTime constructor, sets the Data to the formatted String from the DateTime
    /// </summary>
    /// <param name="date"></param>
    public WCFDate(DateTime? date)
    {
        if (date.HasValue)
        {
            Data = date.Value.ToString(DateTimeFormat);
        }
    }

    /// <summary>
    /// Check if the class is holding a Date or not
    /// </summary>
    public bool HasDate
    {
        get
        {
            return !string.IsNullOrWhiteSpace(Data);
        }
    }

    /// <summary>
    /// Gets the DateTime the class represents
    /// </summary>
    /// <returns></returns>
    public DateTime GetDate()
    {
        try
        {
            return DateTime.ParseExact(Data, DateTimeFormat, CultureInfo.CurrentCulture);
        }
        catch
        {
            return new DateTime();
        }
    }
}

Follow the Gist of this class or feel free to add to it.

AppEvents – Do stuff when things happen (WP7)

Ever wanted an easy way for apps to track certain events then run code based off what events the user has triggered? Well now you can with AppEvents!

So AppEvents is a Windows Phone 7 library to manage events for a user across multiple sessions. In this example I will use it with CodeTrack to prompt the user to rate the app after they have added 3 repos.

Lets get started, App.xaml.cs (this code can be put anywhere in the app but I felt this was better to be done at the start of the app)

public App()
{
    ...
    EventClient.New()
        .Add(RuleSet.When("rate-app",
            el => el.Any(e => e.Name == "addrepo" && e.Occurrrences.Count > 2))
            .Do(r => AskToRate())
        );
}

Now lets break that down, first we have the New() function being called, this creates the instance (and sets the Current singleton in the EventClient class). It also uses the default JsonEventStorageProvider to store the EventStore data, this can be overwritten with a type parameter on the new function:

EventClient.New<MyCustomEventStoreage>()

Now this is where the RuleSets are added to the client using RuleSet.When() The first parameter of this function is a name of the rule. This is mainly to keep track of the rule and make sure we don’t run it twice. The second parameter is a Func<UserEventList, bool> which means we can create lamba expressions to be run agains the UserEventList object, this expression tells the RuleSet when it should fire its Do Action.

    .Add(RuleSet.When("rate-app",
        el => el.Any(e => e.Name == "addrepo" && e.Occurrrences.Count > 2))
        .Do(r => AskToRate())
    );

So where do I get it?

The last part to this is firing off the events this part is very simple.

    EventClient.Current.Fire("addrepo");

And thats pretty much it, the library then does the rest

The library also allows for manual checking of events if for instance you fire an event on a page but want the RuleSet to be executed on a different page. To do this we simply add a false optional parameter to the Fire method to stop it running the RuleSets with the event. We can also manually run rules, either singly by the RuleSet name or all the rules in the list. We can also set the EventClient to not save the EventStore using the provider each time (and just have it saved later for performance).

EventClient.Current.Fire("addrepo", false);
EventClient.Current.Fire("addrepo", false, false);
EventClient.Current.RunRule("rate-app");
EventClient.Current.RunRules();
EventClient.Current.SaveEventStore();

So where do I get it?

The project if on GitHub for your forking, issues and discussions.AppEvents on Github.

Windows Mobile 6: Legacy

I have also made a Windows Mobile 6 version of this library but haven’t actively tested it too much, if you feel like giving it a go be sure to let me know how you go.

Dropbox on Windows Phone 7 with DropNet

So I have been working on an open source Dropbox client library for a while now called DropNet. I have recently put this project into NuGet so its super easy to add Dropbox support to your Windows Phone 7 apps.

Update: The source for this sample project is available here: http://bit.ly/dYjRnW

Update: The DropNet and DropNet-WP NuGet packages have been merged and allow for both Project Types.

I’ll start with a File -> New Project, creating a sample Windows Phone Application.

FileNew2

First thing to do is install the DropNet package, NuGet will automatically detect the type of project you are using and add the DropNet reference for that project type (eg. DropNet.WindowsPhone for Windows Phone 7 projects.)

DropNetNuGet

Ok, now we can start with the App, for starters I created a global variable for my DropNetClient instance.

GlobalClient = new DropNetClient("API KEY", "API SECRET");

Now from that we will need to let the user login so my main page has a basic login form, 2 textboxes for Email and Password and a button to make it work.

private void Login_Click(object sender, RoutedEventArgs e)
{
    //try login
    App.GlobalClient.LoginAsync(_model.Email, _model.Password,
        (response) =>
        {
            if (response.Data != null)
            {
                //DropNet automatically sets the result token inside the client
                NavigationService.Navigate(new Uri("/FilesPage.xaml", UriKind.Relative));
            }
        });
}

DropNets Login function automatically saves the user Token and Secret to its client instance so we dont have to set it. Then I just navigate to a new page where we will attempt to browse our Dropbox Folder.

This page has a basic view model with 1 property for the folders content.

private ObservableCollection<MetaData> _contents;
public ObservableCollection<MetaData> Contents
{
    get { return _contents; }
    set
    {
        _contents = value;
        NotifyPropertyChanged("Contents");
    }
}

Pretty easy, the page itself simply binds this collection to a listbox displaying the Name and an icon if its a folder.

Ok, now to actually get the data from Dropbox… We do this by calling our DropNetClient’s GetMetaDataAsync method. This method takes a path parameter so we can tell it which folder to get the metadata for.

App.GlobalClient.GetMetaDataAsync("/",
    (response) =>
    {
        foreach (var c in response.Data.Contents.OrderBy(f => f.Name).OrderByDescending(f => f.Is_Dir))
        {
            _model.Contents.Add(c);
        }
    });

Browse1

After getting the MetaData I then order it, folders first then alphabetically.

Wait, really? Thats it?

Yep! Thats my Dropbox folder.

Now to make it even better we can handle the listbox’s selection change event and if the selected item was a folder we can show its contents.

private void ListBox_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
    if (e.AddedItems.Count > 0)
    {
        var selected = (e.AddedItems[0] as MetaData);

        //if its a folder browse to it
        if (selected.Is_Dir)
        {
            _model.Contents = new ObservableCollection<MetaData>();
            App.GlobalClient.GetMetaDataAsync(selected.Path,
            (response) =>
            {
                foreach (var c in response.Data.Contents.OrderBy(f => f.Name).OrderByDescending(f => f.Is_Dir))
                {
                    _model.Contents.Add(c);
                }
            });
        }
    }
}

 

There we go, thats the basis for a Dropbox app using DropNet, lets see what we can come up with!

DropNet Implements most of the API’s functions, including :

  • Uploading files
  • Downloading files
  • Creating folders
  • Creating an account
  • Getting account info
  • Deleting files/folders
  • Data usage counter

I’m always updating the project over at GitHub, drop by and let me know what you think or if you have any feature requests/bugs. GitHub Project.

Or check out the NuGet Package here.

Browse3Browse2