Add in global addon channel selection
This commit is contained in:
jliddev
2020-08-05 12:57:45 -05:00
parent 9e142879f5
commit 60ea0145fd
9 changed files with 179 additions and 93 deletions

View File

@@ -18,7 +18,10 @@ namespace WowUp.Common.Services.Contracts
Task<ChangeLogFile> GetChangeLogFile();
Task UpdateApplication(Action<ApplicationUpdateState, decimal> updateAction);
bool GetCollapseToTray();
void SetCollapseToTray(bool enabled);
AddonChannelType GetDefaultAddonChannel();
void SetDefaultAddonChannel(AddonChannelType type);
}
}

View File

@@ -1,5 +1,9 @@
{
"ChangeLogs": [
{
"Version": "1.14.2",
"Description": "Add the ability to set a global addon channel."
},
{
"Version": "1.14.1",
"Description": "Fix issue with update button being shown over progress bar during auto update."

View File

@@ -7,6 +7,23 @@ namespace WowUp.WPF.Extensions
{
public static class AddonExtensions
{
public static Addon Assign(this Addon addon1, Addon addon2)
{
addon1.Name = addon2.Name;
addon1.FolderName = addon2.FolderName;
addon1.DownloadUrl = addon2.DownloadUrl;
addon1.LatestVersion = addon2.LatestVersion;
addon1.ExternalId = addon2.ExternalId;
addon1.ProviderName = addon2.ProviderName;
addon1.ExternalUrl = addon2.ExternalUrl;
addon1.ThumbnailUrl = addon2.ThumbnailUrl;
addon1.GameVersion = addon2.GameVersion;
addon1.ClientType = addon2.ClientType;
addon1.ChannelType = addon2.ChannelType;
return addon1;
}
public static IList<string> GetInstalledDirectories(this Addon addon)
{
if (string.IsNullOrEmpty(addon.InstalledFolders))

View File

@@ -0,0 +1,22 @@
using System;
using WowUp.Common.Enums;
namespace WowUp.WPF.Extensions
{
public static class EnumExtensions
{
public static AddonChannelType ToAddonChannelType(this string str)
{
if (AddonChannelType.Alpha.ToString().Equals(str, StringComparison.OrdinalIgnoreCase))
{
return AddonChannelType.Alpha;
}
else if (AddonChannelType.Beta.ToString().Equals(str, StringComparison.OrdinalIgnoreCase))
{
return AddonChannelType.Beta;
}
return AddonChannelType.Stable;
}
}
}

View File

@@ -33,9 +33,11 @@ namespace WowUp.WPF.Services
protected readonly IEnumerable<IAddonProvider> _providers = new List<IAddonProvider>();
protected readonly IAddonRepository _addonRepository;
protected readonly IAnalyticsService _analyticsService;
protected readonly IDownloadService _downloadService;
protected readonly IWarcraftService _warcraftService;
protected readonly IWowUpService _wowUpService;
public event AddonEventHandler AddonUninstalled;
public event AddonEventHandler AddonInstalled;
@@ -48,12 +50,15 @@ namespace WowUp.WPF.Services
IAddonRepository addonRepository,
IAnalyticsService analyticsService,
IDownloadService downloadSevice,
IWarcraftService warcraftService)
IWarcraftService warcraftService,
IWowUpService wowUpService)
{
_addonRepository = addonRepository;
_analyticsService = analyticsService;
_downloadService = downloadSevice;
_warcraftService = warcraftService;
_wowUpService = wowUpService;
_providers = new List<IAddonProvider>
{
@@ -177,29 +182,6 @@ namespace WowUp.WPF.Services
.FirstOrDefault();
}
public async Task InstallAddon(
PotentialAddon potentialAddon,
WowClientType clientType,
Action<AddonInstallState, decimal> onUpdate = null)
{
var provider = _providers.First(p => p.Name == potentialAddon.ProviderName);
var searchResult = await provider.GetById(potentialAddon.ExternalId, clientType);
var latestFile = GetLatestFile(searchResult, AddonChannelType.Stable);
var existingAddon = _addonRepository.GetByExternalId(searchResult.ExternalId, clientType);
if (existingAddon != null)
{
throw new AddonAlreadyInstalledException();
}
var addon = CreateAddon(latestFile.Folders.FirstOrDefault(), searchResult, latestFile, clientType);
_addonRepository.SaveItem(addon);
await InstallAddon(addon.Id, onUpdate);
}
public async Task<PotentialAddon> GetAddonByUri(
Uri addonUri,
WowClientType clientType,
@@ -208,25 +190,6 @@ namespace WowUp.WPF.Services
var provider = GetAddonProvider(addonUri);
return await provider.Search(addonUri, clientType);
//var latestFile = GetLatestFile(searchResult, AddonChannelType.Stable);
//if (latestFile == null)
//{
// throw new AddonNotFoundException();
//}
//var existingAddon = _addonRepository.GetByExternalId(searchResult.ExternalId, clientType);
//if(existingAddon != null)
//{
// throw new AddonAlreadyInstalledException();
//}
//var addon = CreateAddon(latestFile.Folders.FirstOrDefault(), searchResult, latestFile, clientType);
//_addonRepository.SaveItem(addon);
//await InstallAddon(addon.Id, onUpdate);
}
public async Task UninstallAddon(Addon addon)
@@ -245,6 +208,41 @@ namespace WowUp.WPF.Services
AddonUninstalled?.Invoke(this, new AddonEventArgs(addon, AddonChangeType.Uninstalled));
}
public async Task<Addon> GetAddon(
string externalId,
string providerName,
WowClientType clientType)
{
var provider = GetProvider(providerName);
var searchResult = await provider.GetById(externalId, clientType);
var latestFile = GetLatestFile(searchResult, _wowUpService.GetDefaultAddonChannel());
return CreateAddon(latestFile.Folders.FirstOrDefault(), searchResult, latestFile, clientType);
}
private IAddonProvider GetProvider(string providerName)
{
return _providers.First(p => p.Name == providerName);
}
public async Task InstallAddon(
PotentialAddon potentialAddon,
WowClientType clientType,
Action<AddonInstallState, decimal> onUpdate = null)
{
var existingAddon = _addonRepository.GetByExternalId(potentialAddon.ExternalId, clientType);
if (existingAddon != null)
{
throw new AddonAlreadyInstalledException();
}
var addon = await GetAddon(potentialAddon.ExternalId, potentialAddon.ProviderName, clientType);
_addonRepository.SaveItem(addon);
await InstallAddon(addon.Id, onUpdate);
}
public async Task InstallAddon(int addonId, Action<AddonInstallState, decimal> updateAction)
{
var addon = GetAddon(addonId);
@@ -253,6 +251,12 @@ namespace WowUp.WPF.Services
throw new Exception("Addon not found or invalid");
}
if(addon.ChannelType != _wowUpService.GetDefaultAddonChannel())
{
var newAddon = await GetAddon(addon.ExternalId, addon.ProviderName, addon.ClientType);
addon.Assign(newAddon);
}
updateAction?.Invoke(AddonInstallState.Downloading, 25m);
string downloadedFilePath = string.Empty;
@@ -380,40 +384,6 @@ namespace WowUp.WPF.Services
return await MapAll(addonFolders, clientType);
}
//public async Task<List<Addon>> MapAll(IEnumerable<Addon> addons, WowClientType clientType)
//{
// if (addons == null)
// {
// Log.Warning("Addon list was null");
// return new List<Addon>();
// }
// foreach (var addon in addons)
// {
// Log.Debug($"Addon {addon.FolderName}");
// try
// {
// var searchResults = await Search(addon.Name, addon.FolderName, clientType);
// var firstResult = searchResults.FirstOrDefault();
// if (firstResult == null)
// {
// continue;
// }
// addon.LatestVersion = firstResult.Version;
// addon.GameVersion = firstResult.GameVersion;
// addon.Author = firstResult.Author;
// }
// catch (Exception ex)
// {
// Log.Error(ex, "Failed to map addon");
// }
// }
// return addons.ToList();
//}
public async Task<List<Addon>> MapAll(IEnumerable<AddonFolder> addonFolders, WowClientType clientType)
{
var results = new Dictionary<string, Addon>();
@@ -427,7 +397,7 @@ namespace WowUp.WPF.Services
{
var provider = _providers.First(p => p is CurseAddonProvider) as CurseAddonProvider;
var searchResult = await provider.GetById(addonFolder.Toc.CurseProjectId, clientType);
var latestFile = GetLatestFile(searchResult, AddonChannelType.Stable);
var latestFile = GetLatestFile(searchResult, _wowUpService.GetDefaultAddonChannel());
addon = CreateAddon(addonFolder.Name, searchResult, latestFile, clientType);
}
else
@@ -522,7 +492,7 @@ namespace WowUp.WPF.Services
DownloadUrl = latestFile.DownloadUrl,
ExternalUrl = searchResult.ExternalUrl,
ProviderName = searchResult.ProviderName,
ChannelType = latestFile.ChannelType
ChannelType = _wowUpService.GetDefaultAddonChannel()
};
}
}

View File

@@ -21,22 +21,20 @@ namespace WowUp.WPF.Services
private const string LatestVersionUrlFormat = "https://wowup-builds.s3.us-east-2.amazonaws.com/v{0}/WowUp.zip";
private const string ChangeLogFileCacheKey = "change_log_file";
private const string CollapseToTrayKey = "collapse_to_tray";
private const string DefaultAddonChannelKey = "default_addon_channel";
public const string WebsiteUrl = "https://wowup.io";
private readonly IMemoryCache _cache;
private readonly IDownloadService _downloadSevice;
private readonly IServiceProvider _serviceProvider;
private readonly IPreferenceRepository _preferenceRepository;
public WowUpService(
IMemoryCache memoryCache,
IPreferenceRepository preferenceRepository,
IServiceProvider serviceProvider,
IDownloadService downloadService)
IServiceProvider serviceProvider)
{
_cache = memoryCache;
_downloadSevice = downloadService;
_serviceProvider = serviceProvider;
_preferenceRepository = preferenceRepository;
@@ -56,13 +54,34 @@ namespace WowUp.WPF.Services
public void SetCollapseToTray(bool enabled)
{
var pref = _preferenceRepository.FindByKey(CollapseToTrayKey);
if (pref == null)
SetPreference(CollapseToTrayKey, enabled.ToString());
}
public AddonChannelType GetDefaultAddonChannel()
{
var pref = _preferenceRepository.FindByKey(DefaultAddonChannelKey);
if(pref == null)
{
pref = new Preference { Key = CollapseToTrayKey };
throw new Exception("Default addon channel preference not found");
}
pref.Value = enabled.ToString();
return pref.Value.ToAddonChannelType();
}
public void SetDefaultAddonChannel(AddonChannelType type)
{
SetPreference(DefaultAddonChannelKey, type.ToString());
}
public void SetPreference(string key, string value)
{
var pref = _preferenceRepository.FindByKey(key);
if (pref == null)
{
pref = new Preference { Key = key };
}
pref.Value = value;
_preferenceRepository.SaveItem(pref);
}
@@ -90,7 +109,7 @@ namespace WowUp.WPF.Services
public async Task<string> GetLatestVersion()
{
var changeLogFile = await GetChangeLogFile();
if(changeLogFile == null)
if (changeLogFile == null)
{
return string.Empty;
}
@@ -153,8 +172,14 @@ namespace WowUp.WPF.Services
{
SetCollapseToTray(true);
}
pref = _preferenceRepository.FindByKey(DefaultAddonChannelKey);
if (pref == null)
{
SetDefaultAddonChannel(AddonChannelType.Stable);
}
}
}
}

View File

@@ -1,4 +1,6 @@
using WowUp.Common.Enums;
using System.Collections.ObjectModel;
using System.Windows.Controls;
using WowUp.Common.Enums;
using WowUp.Common.Services.Contracts;
using WowUp.WPF.Services.Contracts;
using WowUp.WPF.Utilities;
@@ -60,6 +62,13 @@ namespace WowUp.WPF.ViewModels
set { SetProperty(ref _collapseToTrayEnabled, value); }
}
private AddonChannelType _selectedAddonChannelType;
public AddonChannelType SelectedAddonChannelType
{
get => _selectedAddonChannelType;
set { SetProperty(ref _selectedAddonChannelType, value); }
}
public Command ShowLogsCommand { get; set; }
public Command TelemetryCheckCommand { get; set; }
public Command CollapseToTrayCheckCommand { get; set; }
@@ -68,7 +77,10 @@ namespace WowUp.WPF.ViewModels
public Command SetClassicLocationCommand { get; set; }
public Command SetClassicPtrLocationCommand { get; set; }
public Command RescanFoldersCommand { get; set; }
public Command AddonChannelChangeCommand { get; set; }
public ObservableCollection<AddonChannelType> AddonChannelNames { get; set; }
public OptionsViewModel(
IAnalyticsService analyticsService,
IWarcraftService warcraftService,
@@ -86,6 +98,14 @@ namespace WowUp.WPF.ViewModels
SetClassicLocationCommand = new Command(() => OnSetLocation(WowClientType.Classic));
SetClassicPtrLocationCommand = new Command(() => OnSetLocation(WowClientType.ClassicPtr));
RescanFoldersCommand = new Command(() => OnRescanFolders());
AddonChannelChangeCommand = new Command(() => OnAddonChannelChange(SelectedAddonChannelType));
AddonChannelNames = new ObservableCollection<AddonChannelType>
{
AddonChannelType.Stable,
AddonChannelType.Beta,
AddonChannelType.Alpha
};
LoadOptions();
}
@@ -94,6 +114,7 @@ namespace WowUp.WPF.ViewModels
{
IsTelemetryEnabled = _analyticsService.IsTelemetryEnabled();
CollapseToTrayEnabled = _wowUpService.GetCollapseToTray();
SelectedAddonChannelType = _wowUpService.GetDefaultAddonChannel();
WowRetailLocation = _warcraftService.GetClientLocation(WowClientType.Retail);
WowRetailPtrLocation = _warcraftService.GetClientLocation(WowClientType.RetailPtr);
@@ -139,5 +160,10 @@ namespace WowUp.WPF.ViewModels
_warcraftService.ScanProducts();
LoadOptions();
}
private void OnAddonChannelChange(AddonChannelType addonChannelType)
{
_wowUpService.SetDefaultAddonChannel(addonChannelType);
}
}
}

View File

@@ -3,6 +3,7 @@
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:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:WowUp.WPF.Views"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
@@ -108,6 +109,7 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
@@ -133,7 +135,23 @@
</CheckBox>
<Label VerticalAlignment="Top">When closing the WowUp window, minimize to the system tray.</Label>
</StackPanel>
<Label FontWeight="Bold" Grid.Row="3" Grid.Column="0" >Default Addon Channel</Label>
<StackPanel Grid.Row="3" Grid.Column="1" Margin="0 5" Orientation="Horizontal">
<ComboBox x:Name="AddonChannelComboBox" SelectedItem="{Binding SelectedAddonChannelType}"
HorizontalAlignment="Left"
Style="{StaticResource ComboBoxFlatStyle}"
ItemsSource="{Binding AddonChannelNames}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding AddonChannelChangeCommand}"
CommandParameter="{Binding ElementName=AddonChannelComboBox, Path=SelectedValue}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
<TextBlock Padding="0" Margin="5 0 0 0" VerticalAlignment="Center">
Newly installed addons will assume this release channel.
</TextBlock>
</StackPanel>
</Grid>
</Border>
</StackPanel>

View File

@@ -10,7 +10,7 @@
<PackageId>WowUp</PackageId>
<Authors>Jliddev</Authors>
<Product>WowUp</Product>
<Version>1.14.1</Version>
<Version>1.14.2</Version>
<ApplicationIcon>wowup_logo_512np_RRT_icon.ico</ApplicationIcon>
<Copyright>jliddev</Copyright>
<PackageProjectUrl>https://wowup.io</PackageProjectUrl>
@@ -46,6 +46,7 @@
<PackageReference Include="Flurl.Http" Version="2.4.2" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="3.1.6" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="3.1.6" />
<PackageReference Include="Microsoft.Xaml.Behaviors.Wpf" Version="1.1.19" />
<PackageReference Include="protobuf-net" Version="3.0.29" />
<PackageReference Include="Serilog" Version="2.9.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.1" />