Create a new file called LoginPresenter.cs
, add it to the Presenter
folder in the Chat.Common
project, and implement the following:
public class LoginPresenter : BasePresenter { #region Private Properties private ILoginView _view; #endregion #region IClientsListView public interface ILoginView : IView { event EventHandler<Tuple<string, string>> Login; event EventHandler<Tuple<string, string>> Register; } #endregion #region Constructors public LoginPresenter(ApplicationState state, INavigationService navigationService) { _navigationService = navigationService; _state = state; _webApiAccess = new WebApiAccess(); } #endregion #region Public Methods public void SetView(ILoginView view) { _view = view; _view.Login -= HandleLogin; _view.Login += HandleLogin; _view.Register -= HandleRegister; _view.Register += HandleRegister; } #endregion }
Our LoginPresenter
contains a new ILoginView
interface with two new event handlers for the two buttons that will appear on the login screen. We also include a new WebApiAccess
object as we will need to perform logins and registrations on the Web API. We also need another function called SetView
, this will take the user interface object and register any EventHandlers
specified by the ILoginView
interface. Let's now add the function for handling logins:
#region Private Methods private async void HandleLogin(object sender, Tuple<string, string> user) { if (!_view.IsInProgress) { _state.Username = user.Item1; _view.IsInProgress = true; if (user.Item2.Length >= 6) { var loggedIn = await _webApiAccess.LoginAsync(user.Item1, user.Item2, CancellationToken.None); if (loggedIn) { var tokenContract = await _webApiAccess.GetTokenAsync(user.Item1, user.Item2, CancellationToken.None); if (!string.IsNullOrEmpty(tokenContract.AccessToken)) { var presenter = new ClientsListPresenter(_state, _navigationService, tokenContract.AccessToken); _navigationService.PushPresenter(presenter); } else { _view.SetErrorMessage("Failed to register user."); } } else { _view.SetErrorMessage("Invalid username or password."); } } else { _view.SetErrorMessage("Password must be at least 6 characters."); } _view.IsInProgress = false; } }
The HandleLogin
function will check first if the screen is currently progressing from another login; we want to make sure that only one login or registration can occur at any one time. Firstly, we call the LoginAsync
and check that the user exists in the UserManager
, then we call the GetTokenAsync
function to retrieve the access token which will be used in our HubConnection
. If both are successful, we push on the ClientsListViewController
using the NavigationService
. If either fails, we use the SetErrorMessage
function for displaying an error.
Now let's add the function for handling registrations:
private async void HandleRegister(object sender, Tuple<string, string> user) { // make sure only once can we be registering at any one time if (!_view.IsInProgress) { _state.Username = user.Item1; _view.IsInProgress = true; if (user.Item2.Length >= 6) { var registerSuccess = await _webApiAccess.RegisterAsync(user.Item1, user.Item2, CancellationToken.None); if (registerSuccess) { _view.SetErrorMessage("User successfully registered."); } } else { _view.SetErrorMessage("Password must be at least 6 characters."); } _view.IsInProgress = false; } } #endregion
Very much the same as the LoginAsync
, but we call the RegisterAsync
and simply wait for the call to finish and check we have the HTTP status code of 200 (OK)
.
18.222.37.169