mirror of
https://github.com/WowUp/WowUp.git
synced 2026-04-23 15:27:03 -04:00
v1.14.2
Add in global addon channel selection
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -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))
|
||||
|
||||
22
WowUp.WPF/Extensions/EnumExtensions.cs
Normal file
22
WowUp.WPF/Extensions/EnumExtensions.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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" />
|
||||
|
||||
Reference in New Issue
Block a user