public MainViewModel()
{
CurrentScreen = ScreenType.ApiKey;
//Observable.Start(() =>
//{
// try
// {
// //I'm considering doing an http request to smashboards to find if a new version is released. I think smashboard's anti-DDOS protection is preventing it from working
// WebRequest request = WebRequest.Create(ThreadUrl);
// request.Credentials = CredentialCache.DefaultCredentials;
// WebResponse response = request.GetResponse();
// if (((HttpWebResponse)response).StatusDescription == "OK")
// {
// Stream dataStream = response.GetResponseStream();
// StreamReader reader = new StreamReader(dataStream);
// string responseFromServer = reader.ReadToEnd();
// reader.Close();
// }
// response.Close();
// }
// catch { /* ignore */ }
//});
//Modify ViewModel state when an action is initiated
Action startAction = () =>
{
ErrorMessage = null;
IsBusy = true;
};
//Modify ViewModel state when an action is completed
Action endAction = () =>
{
IsBusy = false;
};
//Modify ViewModel state when an action comes back with an exception
Action<Exception> errorHandler = ex =>
{
if (ex.InnerException is ChallongeApiException)
{
var cApiEx = (ChallongeApiException)ex.InnerException;
if (cApiEx.Errors != null) ErrorMessage = cApiEx.Errors.Aggregate((one, two) => one + "\r\n" + two);
else ErrorMessage = string.Format("Error with ResponseStatus \"{0}\" and StatusCode \"{1}\". {2}", cApiEx.RestResponse.ResponseStatus,
cApiEx.RestResponse.StatusCode, cApiEx.RestResponse.ErrorMessage);
}
else
{
ErrorMessage = ex.NewLineDelimitedMessages();
}
IsBusy = false;
};
var dispatcher = System.Threading.SynchronizationContext.Current;
//Handle next button press
NextCommand = Command.CreateAsync(() => true, () =>
{
switch (CurrentScreen)
{
case ScreenType.ApiKey:
var subdomain = string.IsNullOrWhiteSpace(Subdomain) ? null : Subdomain;
Portal = new ChallongePortal(ApiKey, subdomain);
//Load list of tournaments that match apikey/subdomain
TournamentCollection = Portal.GetTournaments().OrderByDescending(t => t.CreatedAt).ToArray();
try
{
//This is a silly method for checking whether a new application version exists without me having my own website.
//I manage the most recent version number in the description of a tournament hosted on challonge. This code fetches that number
var versionCheckPortal = new ChallongePortal(ApiKey, "fizzitestorg");
MostRecentVersion = versionCheckPortal.GetTournaments().Where(t => t.Name == "CMDVersionTest").Select(t =>
{
//Modifying the description seems to put some html formatting into the result. This filters the description for
//just the version number by itself
var versionResult = string.Concat(t.Description.Where(c => char.IsDigit(c) || c == '.'));
return versionResult;
}).First();
//Check both version numbers to determine if current version is older than recent version
var versionCompareResult = Version.Split('.').Zip(MostRecentVersion.Split('.'), (v, mrv) =>
{
return int.Parse(v).CompareTo(int.Parse(mrv));
}).FirstOrDefault(i => i != 0);
//If app version is older than most recent version, show message
IsVersionOutdatedVisible = versionCompareResult < 0;
}
catch (Exception)
{
//If version check fails simply ignore the problem and move on
System.Diagnostics.Debug.WriteLine("Version check failed.");
}
break;
case ScreenType.TournamentSelection:
if (Context != null) Context.Dispose();
if (matchesChangedHandler != null) Context.Tournament.PropertyChanged -= matchesChangedHandler;
//Create tournament context from selected tournament
Context = new TournamentContext(Portal, SelectedTournament.Id);
Context.StartSynchronization(TimeSpan.FromMilliseconds(500), 6);
//Create TO View Model
OrgViewModel = new OrganizerViewModel(this, dispatcher);
//Load up matches into display matches. This is done to allow ordering of assigned matches over unassigned matches without having to refresh the view
DisplayMatches = Context.Tournament.Matches.Select(kvp => new DisplayMatch(OrgViewModel, kvp.Value, DisplayMatch.DisplayType.Assigned))
.Concat(Context.Tournament.Matches.Select(kvp => new DisplayMatch(OrgViewModel, kvp.Value, DisplayMatch.DisplayType.Unassigned))).ToList();
//This handler is used to keep matches display matches in sync with tournament context matches. If the matches in the context change, re-generate the display matches
matchesChangedHandler = new PropertyChangedEventHandler((sender, e) =>
{
if (e.PropertyName == "Matches")
{
if (Context.Tournament.Matches == null) DisplayMatches = null;
else
{
DisplayMatches = Context.Tournament.Matches.Select(kvp => new DisplayMatch(OrgViewModel, kvp.Value, DisplayMatch.DisplayType.Assigned))
.Concat(Context.Tournament.Matches.Select(kvp => new DisplayMatch(OrgViewModel, kvp.Value, DisplayMatch.DisplayType.Unassigned))).ToList();
}
}
});
Context.Tournament.PropertyChanged += matchesChangedHandler;
break;
}
CurrentScreen = (ScreenType)((int)CurrentScreen + 1);
}, startAction, endAction, errorHandler);
Back = Command.CreateAsync(() => true, () =>
{
switch (CurrentScreen)
{
case ScreenType.TournamentSelection:
ApiKey = null;
break;
case ScreenType.PendingMatchView:
if (OrgViewModel != null)
{
OrgViewModel.Dispose();
OrgViewModel = null;
}
break;
}
CurrentScreen = (ScreenType)((int)CurrentScreen - 1);
}, startAction, endAction, errorHandler);
IgnoreVersionNotification = Command.Create(() => true, () => IsVersionOutdatedVisible = false);
}