Skip to content

Commit

Permalink
Logout button & Password edit control in settings
Browse files Browse the repository at this point in the history
  • Loading branch information
angelsix committed Jul 22, 2017
1 parent 9bd7c30 commit b29ccf9
Show file tree
Hide file tree
Showing 15 changed files with 594 additions and 14 deletions.
2 changes: 2 additions & 0 deletions Source/Fasetto.Word.Core/Fasetto.Word.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,9 @@
<Compile Include="ViewModel\Dialogs\Design\MessageBoxDialogDesignModel.cs" />
<Compile Include="ViewModel\Dialogs\MessageBoxDialogViewModel.cs" />
<Compile Include="ViewModel\Application\LoginViewModel.cs" />
<Compile Include="ViewModel\Input\Design\PasswordEntryDesignModel.cs" />
<Compile Include="ViewModel\Input\Design\TextEntryDesignModel.cs" />
<Compile Include="ViewModel\Input\PasswordEntryViewModel.cs" />
<Compile Include="ViewModel\Input\TextEntryViewModel.cs" />
<Compile Include="ViewModel\Menu\Design\MenuDesignModel.cs" />
<Compile Include="ViewModel\Menu\Design\MenuItemDesignModel.cs" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ public class ApplicationViewModel : BaseViewModel
/// <param name="page">The page to go to</param>
public void GoToPage(ApplicationPage page)
{
// Always hide settings page if we are changing pages
SettingsMenuVisible = false;

// Set the current page
CurrentPage = page;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public SettingsDesignModel()
{
Name = new TextEntryViewModel { Label = "Name", OriginalText = "Luke Malpass" };
Username = new TextEntryViewModel { Label = "Username", OriginalText = "luke" };
Password = new TextEntryViewModel { Label = "Password", OriginalText = "********" };
Password = new PasswordEntryViewModel { Label = "Password", FakePassword = "********" };
Email = new TextEntryViewModel { Label = "Email", OriginalText = "contact@angelsix.com" };
}

Expand Down
10 changes: 10 additions & 0 deletions Source/Fasetto.Word.Core/ViewModel/Application/LoginViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,18 @@ public async Task LoginAsync(object parameter)
{
await RunCommandAsync(() => LoginIsRunning, async () =>
{
// TODO: Fake a login...
await Task.Delay(1000);
// OK successfully logged in... now get users data
// TODO: Ask server for users info
// TODO: Remove this with real information pulled from our database in future
IoC.Settings.Name = new TextEntryViewModel { Label = "Name", OriginalText = $"Luke Malpass {DateTime.Now.ToLocalTime()}" };
IoC.Settings.Username = new TextEntryViewModel { Label = "Username", OriginalText = "luke" };
IoC.Settings.Password = new PasswordEntryViewModel { Label = "Password", FakePassword = "********" };
IoC.Settings.Email = new TextEntryViewModel { Label = "Email", OriginalText = "contact@angelsix.com" };
// Go to chat page
IoC.Application.GoToPage(ApplicationPage.Chat);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,18 @@ public class SettingsViewModel : BaseViewModel
/// <summary>
/// The current users password
/// </summary>
public TextEntryViewModel Password { get; set; }
public PasswordEntryViewModel Password { get; set; }

/// <summary>
/// The current users email
/// </summary>
public TextEntryViewModel Email { get; set; }

/// <summary>
/// The text for the logout button
/// </summary>
public string LogoutButtonText { get; set; }

#endregion

#region Public Commands
Expand All @@ -48,6 +53,16 @@ public class SettingsViewModel : BaseViewModel
/// </summary>
public ICommand CloseCommand { get; set; }

/// <summary>
/// The command to logout of the application
/// </summary>
public ICommand LogoutCommand { get; set; }

/// <summary>
/// The command to clear the users data from the view model
/// </summary>
public ICommand ClearUserDataCommand { get; set; }

#endregion

#region Constructor
Expand All @@ -60,12 +75,17 @@ public SettingsViewModel()
// Create commands
OpenCommand = new RelayCommand(Open);
CloseCommand = new RelayCommand(Close);
LogoutCommand = new RelayCommand(Logout);
ClearUserDataCommand = new RelayCommand(ClearUserData);

// TODO: Remove this with real information pulled from our database in future
Name = new TextEntryViewModel { Label = "Name", OriginalText = "Luke Malpass" };
// TODO: Remove this once th real back-end is ready
Name = new TextEntryViewModel { Label = "Name", OriginalText = $"Luke Malpass" };
Username = new TextEntryViewModel { Label = "Username", OriginalText = "luke" };
Password = new TextEntryViewModel { Label = "Password", OriginalText = "********" };
Password = new PasswordEntryViewModel { Label = "Password", FakePassword = "********" };
Email = new TextEntryViewModel { Label = "Email", OriginalText = "contact@angelsix.com" };

// TODO: Get from localization
LogoutButtonText = "Logout";
}

#endregion
Expand All @@ -88,5 +108,33 @@ public void Close()
IoC.Application.SettingsMenuVisible = false;
}

/// <summary>
/// Logs the user out
/// </summary>
public void Logout()
{
// TODO: Confirm the user wants to logout

// TODO: Clear any user data/cache

// Clean all application level view models that contain
// any information about the current user
ClearUserData();

// Go to login page
IoC.Application.GoToPage(ApplicationPage.Login);
}

/// <summary>
/// Clears any data specific to the current user
/// </summary>
public void ClearUserData()
{
// Clear all view models containing the users info
Name = null;
Username = null;
Password = null;
Email = null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ public class MessageBoxDialogViewModel : BaseDialogViewModel
/// <summary>
/// The text to use for the OK button
/// </summary>
public string OkText { get; set; }
public string OkText { get; set; } = "OK";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
namespace Fasetto.Word.Core
{
/// <summary>
/// The design-time data for a <see cref="PasswordEntryViewModel"/>
/// </summary>
public class PasswordEntryDesignModel : PasswordEntryViewModel
{
#region Singleton

/// <summary>
/// A single instance of the design model
/// </summary>
public static PasswordEntryDesignModel Instance => new PasswordEntryDesignModel();

#endregion

#region Constructor

/// <summary>
/// Default Constructor
/// </summary>
public PasswordEntryDesignModel()
{
Label = "Name";
FakePassword = "********";
}

#endregion
}
}
184 changes: 184 additions & 0 deletions Source/Fasetto.Word.Core/ViewModel/Input/PasswordEntryViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
using System.Security;
using System.Windows.Input;

namespace Fasetto.Word.Core
{
/// <summary>
/// The view model for a password entry to edit a password
/// <summary>
public class PasswordEntryViewModel : BaseViewModel
{
#region Public Properties

/// <summary>
/// The label to identify what this value is for
/// </summary>
public string Label { get; set; }

/// <summary>
/// The fake password display string
/// </summary>
public string FakePassword { get; set; }

/// <summary>
/// The current password hint text
/// </summary>
public string CurrentPasswordHintText { get; set; }

/// <summary>
/// The new password hint text
/// </summary>
public string NewPasswordHintText { get; set; }

/// <summary>
/// The confirm password hint text
/// </summary>
public string ConfirmPasswordHintText { get; set; }

/// <summary>
/// The current saved password
/// </summary>
public SecureString CurrentPassword { get; set; }

/// <summary>
/// The current non-commit edited password
/// </summary>
public SecureString NewPassword { get; set; }

/// <summary>
/// The current non-commit edited confirmed password
/// </summary>
public SecureString ConfirmPassword { get; set; }

/// <summary>
/// Indicates if the current text is in edit mode
/// </summary>
public bool Editing { get; set; }

#endregion

#region Public Commands

/// <summary>
/// Puts the control into edit mode
/// </summary>
public ICommand EditCommand { get; set; }

/// <summary>
/// Cancels out of edit mode
/// </summary>
public ICommand CancelCommand { get; set; }

/// <summary>
/// Commits the edits and saves the value
/// as well as goes back to non-edit mode
/// </summary>
public ICommand SaveCommand { get; set; }

#endregion

#region Constructor

/// <summary>
/// Default constructor
/// </summary>
public PasswordEntryViewModel()
{
// Create commands
EditCommand = new RelayCommand(Edit);
CancelCommand = new RelayCommand(Cancel);
SaveCommand = new RelayCommand(Save);

// Set default hints
// TODO: Replace with localization text
CurrentPasswordHintText = "Current Password";
NewPasswordHintText = "New Password";
ConfirmPasswordHintText = "Confirm Password";
}

#endregion

#region Command Methods

/// <summary>
/// Puts the control into edit mode
/// </summary>
public void Edit()
{
// Clear all password
NewPassword = new SecureString();
ConfirmPassword = new SecureString();

// Go into edit mode
Editing = true;
}

/// <summary>
/// Cancels out of edit mode
/// </summary>
public void Cancel()
{
Editing = false;
}

/// <summary>
/// Commits the content and exits out of edit mode
/// </summary>
public void Save()
{
// Make sure current password is correct
// TODO: This will come from the real back-end store of this users password
// or via asking the web server to confirm it
var storedPassword = "Testing";

// Confirm current password is a match
// NOTE: Typically this isn't done here, it's done on the server
if (storedPassword != CurrentPassword.Unsecure())
{
// Let user know
IoC.UI.ShowMessage(new MessageBoxDialogViewModel
{
Title = "Wrong password",
Message = "The current password is invalid"
});

return;
}

// Now check that the new and confirm password match
if (NewPassword.Unsecure() != ConfirmPassword.Unsecure())
{
// Let user know
IoC.UI.ShowMessage(new MessageBoxDialogViewModel
{
Title = "Password mismatch",
Message = "The new and confirm password do not match"
});

return;
}

// Check we actually have a password
if (NewPassword.Unsecure().Length == 0)
{
// Let user know
IoC.UI.ShowMessage(new MessageBoxDialogViewModel
{
Title = "Password too short",
Message = "You must enter a password!"
});

return;
}

// Set the edited password to the current value
CurrentPassword = new SecureString();
foreach (var c in NewPassword.Unsecure().ToCharArray())
CurrentPassword.AppendChar(c);

Editing = false;
}

#endregion
}
}
25 changes: 18 additions & 7 deletions Source/Fasetto.Word/AttachedProperties/TextAttachedProperties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,27 @@ public class FocusAndSelectProperty : BaseAttachedProperty<FocusAndSelectPropert
public override void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
// If we don't have a control, return
if (!(sender is TextBoxBase control))
return;
if (sender is TextBoxBase control)
{
if ((bool)e.NewValue)
{
// Focus this control
control.Focus();

if ((bool)e.NewValue)
// Select all text
control.SelectAll();
}
}
if (sender is PasswordBox password)
{
// Focus this control
control.Focus();
if ((bool)e.NewValue)
{
// Focus this control
password.Focus();

// Select all text
control.SelectAll();
// Select all text
password.SelectAll();
}
}
}
}
Expand Down
Loading

0 comments on commit b29ccf9

Please sign in to comment.