Skip to content

Commit

Permalink
Implement OAuth for token claiming
Browse files Browse the repository at this point in the history
  • Loading branch information
azeier committed Mar 20, 2018
1 parent bef3578 commit c6a8023
Show file tree
Hide file tree
Showing 24 changed files with 705 additions and 274 deletions.
12 changes: 12 additions & 0 deletions Hearthstone Deck Tracker/Controls/StatusIndicator.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<UserControl x:Class="Hearthstone_Deck_Tracker.Controls.StatusIndicator"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
d:DesignHeight="300" d:DesignWidth="300">
<TextBlock TextAlignment="Center" FontWeight="SemiBold">
<Run Foreground="{Binding Color, Mode=OneWay}" Text="{Binding Icon, Mode=OneWay}"/>
</TextBlock>
</UserControl>
47 changes: 47 additions & 0 deletions Hearthstone Deck Tracker/Controls/StatusIndicator.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Media;
using Hearthstone_Deck_Tracker.Annotations;

namespace Hearthstone_Deck_Tracker.Controls
{
public partial class StatusIndicator : INotifyPropertyChanged
{
public static readonly DependencyProperty SuccessProperty = DependencyProperty.Register(
"Success", typeof(bool), typeof(StatusIndicator), new FrameworkPropertyMetadata(OnSuccessChanged));

public StatusIndicator()
{
InitializeComponent();
}

public bool Success
{
get => (bool) GetValue(SuccessProperty);
set => SetValue(SuccessProperty, value);
}

public SolidColorBrush Color => new SolidColorBrush(Success ? Colors.Green : Colors.Red);
public string Icon => Success ? "✔" : "✖";

public event PropertyChangedEventHandler PropertyChanged;

private static void OnSuccessChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if(d is StatusIndicator s) s.Update();
}

private void Update()
{
OnPropertyChanged(nameof(Color));
OnPropertyChanged(nameof(Icon));
}

[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
4 changes: 3 additions & 1 deletion Hearthstone Deck Tracker/Core.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,13 +151,15 @@ public static async void Initialize()
if(Helper.HearthstoneDirExists && Config.Instance.StartHearthstoneWithHDT && !Game.IsRunning)
Helper.StartHearthstoneAsync().Forget();

ApiWrapper.UpdateAccountStatus().Forget();
if(HSReplayNetOAuth.IsAuthenticated)
HSReplayNetHelper.UpdateAccount().Forget();

Initialized = true;

Influx.OnAppStart(
Helper.GetCurrentVersion(),
newUser,
HSReplayNetOAuth.IsAuthenticated,
(int)(DateTime.UtcNow - _startUpTime).TotalSeconds,
PluginManager.Instance.Plugins.Count
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<UserControl x:Class="Hearthstone_Deck_Tracker.FlyoutControls.Options.HSReplay.HSReplayAccount"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:controls="clr-namespace:Hearthstone_Deck_Tracker.Controls"
xmlns:converters="clr-namespace:Hearthstone_Deck_Tracker.Utility.Converters"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
d:DesignHeight="500" d:DesignWidth="300">
<StackPanel Margin="20">
<StackPanel Visibility="{Binding LoginButtonVisibility}">
<TextBlock TextWrapping="Wrap" TextAlignment="Center"
FontSize="16" FontWeight="SemiBold"
Text="Login to claim your replays and enable all HSReplay.net features."
Visibility="{Binding LoginInfoVisibility}"/>
<TextBlock TextWrapping="Wrap" FontWeight="SemiBold"
TextAlignment="Center" FontSize="16"
Visibility="{Binding ReplaysClaimedVisibility}">
<Run Text="Login to enable all HSReplay.net features."/>
<LineBreak/>
<Run FontSize="15" FontWeight="Normal" Text="Replays are uploaded to"/>
<Hyperlink Command="{Binding AccountSettingsCommand}">
<Run Text="{Binding BattleTag, Mode=OneWay}"/>
</Hyperlink>.
</TextBlock>
<Button Style="{DynamicResource AccentedSquareButtonStyle}" Margin="25"
Width="200" Command="{Binding LoginCommand}"
IsEnabled="{Binding LoginButtonEnabled}">
<TextBlock Text="Login"/>
</Button>
</StackPanel>
<StackPanel Visibility="{Binding AccountStatusVisibility}">
<Grid HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontWeight" Value="SemiBold"/>
</Style>
<Style TargetType="controls:StatusIndicator">
<Setter Property="Margin" Value="5"/>
</Style>
<Style TargetType="StackPanel">
<Setter Property="Margin" Value="5"/>
</Style>
<converters:BoolToVisibilityConverter x:Key="BoolToVisibility"/>
<converters:InverseBoolToVisibilityConverter x:Key="InverseBoolToVisibility"/>
</Grid.Resources>
<controls:StatusIndicator Grid.Row="0" Grid.Column="0" Success="True"/>
<TextBlock Grid.Row="0" Grid.Column="1" Margin="5">
<Run Text="Logged in as"/>
<Run Text="{Binding BattleTag, Mode=OneWay}"/>
</TextBlock>
<controls:StatusIndicator Grid.Row="2" Grid.Column="0"
Success="{Binding ReplayUploadingEnabled, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
<StackPanel Grid.Row="2" Grid.Column="1" Margin="5">
<TextBlock Text="Replay uploading"/>
<TextBlock FontSize="12" Visibility="{Binding ReplayUploadingEnabled, Converter={StaticResource InverseBoolToVisibility}}">
<Hyperlink Command="{Binding EnableReplayUploadingCommand}">
<Run Text="Enable now" FontSize="12"/>
</Hyperlink>
</TextBlock>
</StackPanel>
<controls:StatusIndicator Grid.Row="3" Grid.Column="0"
Visibility="{Binding UploadTokenClaimed, Converter={StaticResource InverseBoolToVisibility}, RelativeSource={RelativeSource AncestorType=UserControl}}"
Success="{Binding UploadTokenClaimed, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
<StackPanel Grid.Row="3" Grid.Column="1" Margin="5" Visibility="{Binding UploadTokenClaimed, Converter={StaticResource InverseBoolToVisibility}}">
<TextBlock Text="Replays claimed"/>
<TextBlock FontSize="12" IsEnabled="{Binding ClaimTokenButtonEnabled}">
<Hyperlink Command="{Binding ClaimUploadTokenCommand}">
<Run Text="Claim now" FontSize="12"/>
</Hyperlink>
</TextBlock>
</StackPanel>
<controls:StatusIndicator Grid.Row="4" Grid.Column="0"
Success="{Binding IsPremiumUser, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
<StackPanel Grid.Row="4" Grid.Column="1">
<TextBlock Text="Subscribed to Premium"/>
<TextBlock Text="Thank you for supporting us!" FontSize="12" Foreground="#FFB00D"
Visibility="{Binding IsPremiumUser, Converter={StaticResource BoolToVisibility}}"/>
<TextBlock FontSize="12" Visibility="{Binding IsPremiumUser, Converter={StaticResource InverseBoolToVisibility}}">
<Hyperlink Command="{Binding PremiumInfoCommand}">
<Run Text="Find out more"/>
</Hyperlink>
</TextBlock>
</StackPanel>
</Grid>
<Button HorizontalAlignment="Center" Width="200" Content="Account Settings" Margin="0,15,0,0"
Command="{Binding AccountSettingsCommand}"/>
<TextBlock TextWrapping="Wrap" TextAlignment="Center" Margin="0,20,0,0"
Visibility="{Binding LogoutWarningVisibility}">
<Run FontWeight="SemiBold" FontSize="14" Text="Are you sure you want to logout?"/>
<LineBreak/>
<Run Text="New replays will no longer be attached to your account."/>
<LineBreak/>
<Run Text="Logging back in will claim all new replays retroactively."></Run>
</TextBlock>
<Button HorizontalAlignment="Center" Width="200" Content="Logout" Margin="0,10,0,0"
IsEnabled="{Binding LogoutButtonEnabled}"
Command="{Binding LogoutCommand}">
<Button.Background>
<SolidColorBrush Color="Red" Opacity="0.5"/>
</Button.Background>
</Button>
</StackPanel>
</StackPanel>
</UserControl>
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using Hearthstone_Deck_Tracker.Annotations;
using Hearthstone_Deck_Tracker.HsReplay;
using Hearthstone_Deck_Tracker.Utility;
using Hearthstone_Deck_Tracker.Utility.Extensions;
using static System.Windows.Visibility;
using static Hearthstone_Deck_Tracker.HsReplay.Enums.AccountStatus;

namespace Hearthstone_Deck_Tracker.FlyoutControls.Options.HSReplay
{
public partial class HSReplayAccount : INotifyPropertyChanged
{
private bool _loginButtonEnabled = true;
private bool _logoutButtonEnabled = true;
private bool _logoutTriggered;
private bool _claimTokenButtonEnabled;

public HSReplayAccount()
{
InitializeComponent();
HSReplayNetOAuth.AccountDataUpdated += () =>
{
Update();
LogoutTriggered = false;
};
HSReplayNetOAuth.LoggedOut += () =>
{
Update();
LogoutTriggered = false;
};
HSReplayNetOAuth.UploadTokenClaimed += () => OnPropertyChanged(nameof(UploadTokenClaimed));
Account.Instance.TokenClaimedChanged += () => OnPropertyChanged(nameof(UploadTokenClaimed));
ConfigWrapper.ReplayAutoUploadChanged += () => OnPropertyChanged(nameof(ReplayUploadingEnabled));
HSReplayNetHelper.Authenticating += EnableLoginButton;
}

private void EnableLoginButton(bool authenticating)
{
if(authenticating)
{
LoginButtonEnabled = false;
Task.Run(async () =>
{
await Task.Delay(5000);
LoginButtonEnabled = true;
}).Forget();
}
else
LoginButtonEnabled = true;
}

public Visibility LoginButtonVisibility =>
HSReplayNetOAuth.IsAuthenticated ? Collapsed : Visible;

public Visibility AccountStatusVisibility =>
HSReplayNetOAuth.IsAuthenticated ? Visible : Collapsed;

public Visibility ReplaysClaimedVisibility =>
Account.Instance.Status == Anonymous || HSReplayNetOAuth.IsAuthenticated ? Collapsed : Visible;

public Visibility LoginInfoVisibility =>
Account.Instance.Status == Anonymous || HSReplayNetOAuth.IsAuthenticated ? Visible : Collapsed;

public bool IsPremiumUser =>
HSReplayNetOAuth.AccountData?.IsPremium?.Equals("true", StringComparison.InvariantCultureIgnoreCase) ?? false;

public Visibility LogoutWarningVisibility => LogoutTriggered ? Visible : Collapsed;

public bool LogoutTriggered
{
get => _logoutTriggered;
set
{
_logoutTriggered = value;
OnPropertyChanged();
OnPropertyChanged(nameof(LogoutWarningVisibility));
}
}

public bool LoginButtonEnabled
{
get => _loginButtonEnabled;
set
{
_loginButtonEnabled = value;
OnPropertyChanged();
}
}

public bool LogoutButtonEnabled
{
get => _logoutButtonEnabled;
set
{
_logoutButtonEnabled = value;
OnPropertyChanged();
}
}

public string BattleTag => HSReplayNetOAuth.AccountData?.BattleTag ?? Account.Instance.Username ?? string.Empty;

public ICommand LoginCommand => new Command(async () => await HSReplayNetHelper.TryAuthenticate());

public ICommand LogoutCommand => new Command(async () =>
{
if(LogoutTriggered)
{
LogoutButtonEnabled = false;
await HSReplayNetOAuth.Logout();
LogoutButtonEnabled = true;
}
else
LogoutTriggered = true;
});

public bool ClaimTokenButtonEnabled
{
get => _claimTokenButtonEnabled;
set
{
_claimTokenButtonEnabled = value;
OnPropertyChanged();
}
}

public ICommand EnableReplayUploadingCommand => new Command(() => ConfigWrapper.HsReplayAutoUpload = true);

public ICommand PremiumInfoCommand => new Command(() =>
{
var url = Helper.BuildHsReplayNetUrl("premium", "options_account_premium_info");
Helper.TryOpenUrl(url);
});

public ICommand AccountSettingsCommand => new Command(() =>
{
var url = Helper.BuildHsReplayNetUrl("account", "options_account_settings");
Helper.TryOpenUrl(url);
});

public bool ReplayUploadingEnabled => ConfigWrapper.HsReplayAutoUpload;

public bool UploadTokenClaimed => Account.Instance.TokenClaimed ?? false;

public void Update()
{
OnPropertyChanged(nameof(BattleTag));
OnPropertyChanged(nameof(AccountStatusVisibility));
OnPropertyChanged(nameof(ReplaysClaimedVisibility));
OnPropertyChanged(nameof(LoginButtonVisibility));
OnPropertyChanged(nameof(LoginButtonEnabled));
OnPropertyChanged(nameof(IsPremiumUser));
}

public event PropertyChangedEventHandler PropertyChanged;

[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<UserControl x:Class="Hearthstone_Deck_Tracker.FlyoutControls.Options.HSReplay.HSReplayReplays"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:lex="http://wpflocalizeextension.codeplex.com"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<StackPanel Margin="5">
<CheckBox Name="CheckBoxAutoUpload" Content="{lex:Loc Options_Tracker_Replays_CheckBox_Upload}" IsChecked="{Binding HsReplayAutoUpload, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
<CheckBox Content="{lex:Loc Options_Tracker_Replays_CheckBox_Ranked}" Margin="20,5,0,0" IsChecked="{Binding HsReplayUploadRanked, Source={StaticResource ConfigWrapper}}" IsEnabled="{Binding IsChecked, ElementName=CheckBoxAutoUpload}"/>
<CheckBox Content="{lex:Loc Options_Tracker_Replays_CheckBox_Casual}" Margin="20,5,0,0" IsChecked="{Binding HsReplayUploadCasual, Source={StaticResource ConfigWrapper}}" IsEnabled="{Binding IsChecked, ElementName=CheckBoxAutoUpload}"/>
<CheckBox Content="{lex:Loc Options_Tracker_Replays_CheckBox_Arena}" Margin="20,5,0,0" IsChecked="{Binding HsReplayUploadArena, Source={StaticResource ConfigWrapper}}" IsEnabled="{Binding IsChecked, ElementName=CheckBoxAutoUpload}"/>
<CheckBox Content="{lex:Loc Options_Tracker_Replays_CheckBox_Brawl}" Margin="20,5,0,0" IsChecked="{Binding HsReplayUploadBrawl, Source={StaticResource ConfigWrapper}}" IsEnabled="{Binding IsChecked, ElementName=CheckBoxAutoUpload}"/>
<CheckBox Content="{lex:Loc Options_Tracker_Replays_CheckBox_Friendly}" Margin="20,5,0,0" IsChecked="{Binding HsReplayUploadFriendly, Source={StaticResource ConfigWrapper}}" IsEnabled="{Binding IsChecked, ElementName=CheckBoxAutoUpload}"/>
<CheckBox Content="{lex:Loc Options_Tracker_Replays_CheckBox_AdventurePractice}" Margin="20,5,0,0" IsChecked="{Binding HsReplayUploadPractice, Source={StaticResource ConfigWrapper}}" IsEnabled="{Binding IsChecked, ElementName=CheckBoxAutoUpload}"/>
<CheckBox Content="{lex:Loc Options_Tracker_Replays_CheckBox_Spectator}" Margin="20,5,0,0" IsChecked="{Binding HsReplayUploadSpectator, Source={StaticResource ConfigWrapper}}" IsEnabled="{Binding IsChecked, ElementName=CheckBoxAutoUpload}"/>
<CheckBox Name="CheckBoxShowToast" Content="{lex:Loc Options_Tracker_Replays_CheckBox_ShareNotification}" Margin="0,5,0,0" IsChecked="{Binding HsReplayShareToast, Source={StaticResource ConfigWrapper}}"/>
</StackPanel>
</UserControl>
Loading

0 comments on commit c6a8023

Please sign in to comment.