Skip to content

Added update button to the toolbar #8054

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Feb 2, 2022
Merged
5 changes: 4 additions & 1 deletion src/Files/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ private IServiceProvider ConfigureServices()
// Settings not related to IUserSettingsService:
.AddSingleton<IFileTagsSettingsService, FileTagsSettingsService>()
.AddSingleton<IBundlesSettingsService, BundlesSettingsService>()
.AddSingleton<IUpdateSettingsService, UpdateSettingsService>()

// TODO: Dialogs:

Expand Down Expand Up @@ -183,7 +184,9 @@ await Task.WhenAll(
});

// Check for required updates
new AppUpdater().CheckForUpdatesAsync();
var updateService = Ioc.Default.GetRequiredService<IUpdateSettingsService>();
await updateService.CheckForUpdates();
await updateService.DownloadMandatoryUpdates();
}

private void OnLeavingBackground(object sender, LeavingBackgroundEventArgs e)
Expand Down
2 changes: 2 additions & 0 deletions src/Files/Files.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,10 @@
<Compile Include="Services\IMultitaskingSettingsService.cs" />
<Compile Include="Services\IPreferencesSettingsService.cs" />
<Compile Include="Services\IPreviewPaneSettingsService.cs" />
<Compile Include="Services\IUpdateSettingsService.cs" />
<Compile Include="Services\IUserSettingsService.cs" />
<Compile Include="Services\IWidgetsSettingsService.cs" />
<Compile Include="Services\Implementation\UpdateSettingsService.cs" />
<Compile Include="UserControls\ColoredIcon.xaml.cs">
<DependentUpon>ColoredIcon.xaml</DependentUpon>
</Compile>
Expand Down
25 changes: 25 additions & 0 deletions src/Files/Services/IUpdateSettingsService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.ComponentModel;
using System.Threading.Tasks;

namespace Files.Services
{
public interface IUpdateSettingsService : IBaseSettingsService, INotifyPropertyChanged
{
/// <summary>
/// Gets a value indicating whether updates are available.
/// </summary>
bool IsUpdateAvailable { get; }

/// <summary>
/// Gets a value indicating if an update is in progress.
/// </summary>
bool IsUpdating { get; }

Task DownloadUpdates();

Task DownloadMandatoryUpdates();

Task CheckForUpdates();
}
}
161 changes: 161 additions & 0 deletions src/Files/Services/Implementation/UpdateSettingsService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Files.Models.JsonSettings;
using Microsoft.Toolkit.Uwp;
using Windows.Services.Store;
using Windows.UI.Xaml.Controls;

namespace Files.Services.Implementation
{
public class UpdateSettingsService : BaseObservableJsonSettingsModel, IUpdateSettingsService
{
private StoreContext _storeContext;
private IList<StorePackageUpdate> _updatePackages;

private bool IsMandatory => _updatePackages?.Where(e => e.Mandatory).ToList().Count >= 1;

private bool _isUpdateAvailable;

public bool IsUpdateAvailable
{
get => _isUpdateAvailable;
set
{
_isUpdateAvailable = value;
OnPropertyChanged(nameof(IsUpdateAvailable));
}
}

private bool _isUpdating;

public bool IsUpdating
{
get => _isUpdating;
private set
{
_isUpdating = value;
OnPropertyChanged(nameof(IsUpdating));
}
}

public UpdateSettingsService()
{
_updatePackages = new List<StorePackageUpdate>();
}

public void ReportToAppCenter() {}

public async Task DownloadUpdates()
{
OnUpdateInProgress();

if (!HasUpdates())
{
return;
}

// double check for Mandatory
if (IsMandatory)
{
// Show dialog
var dialog = await ShowDialogAsync();
if (!dialog)
{
// User rejected mandatory update.
OnUpdateCancelled();
return;
}
}

await DownloadAndInstall();
OnUpdateCompleted();
}

public async Task DownloadMandatoryUpdates()
{
// Prompt the user to download if the package list
// contains mandatory updates.
if (IsMandatory && HasUpdates())
{
if (await ShowDialogAsync())
{
OnUpdateInProgress();
await DownloadAndInstall();
OnUpdateCompleted();
}
}
}

public async Task CheckForUpdates()
{
await GetUpdatePackages();

if (_updatePackages is not null && _updatePackages.Count > 0)
{
IsUpdateAvailable = true;
}
}

private async Task DownloadAndInstall()
{
App.SaveSessionTabs();
var downloadOperation = _storeContext.RequestDownloadAndInstallStorePackageUpdatesAsync(_updatePackages);
await downloadOperation.AsTask();
}

private async Task GetUpdatePackages()
{
try
{
_storeContext ??= await Task.Run(StoreContext.GetDefault);
var updateList = await _storeContext.GetAppAndOptionalStorePackageUpdatesAsync();
_updatePackages = updateList?.ToList();
}
catch (FileNotFoundException)
{
// Suppress the FileNotFoundException.
// GetAppAndOptionalStorePackageUpdatesAsync throws for unknown reasons.
}
}

private static async Task<bool> ShowDialogAsync()
{
//TODO: Use IDialogService in future.
ContentDialog dialog = new()
{
Title = "ConsentDialogTitle".GetLocalized(),
Content = "ConsentDialogContent".GetLocalized(),
CloseButtonText = "Close".GetLocalized(),
PrimaryButtonText = "ConsentDialogPrimaryButtonText".GetLocalized()
};
ContentDialogResult result = await dialog.ShowAsync();

return result == ContentDialogResult.Primary;
}

private bool HasUpdates()
{
return _updatePackages is not null && _updatePackages.Count >= 1;
}

protected virtual void OnUpdateInProgress()
{
IsUpdating = true;
}

protected virtual void OnUpdateCompleted()
{
IsUpdating = false;
IsUpdateAvailable = false;
_updatePackages.Clear();
}

protected virtual void OnUpdateCancelled()
{
IsUpdating = false;
}
}
}
5 changes: 4 additions & 1 deletion src/Files/Strings/en-US/Resources.resw
Original file line number Diff line number Diff line change
Expand Up @@ -2744,4 +2744,7 @@ We use App Center to track which settings are being used, find bugs, and fix cra
<data name="CloseOthers" xml:space="preserve">
<value>Close others</value>
</data>
</root>
<data name="UpdateFiles" xml:space="preserve">
<value>Update Files</value>
</data>
</root>
16 changes: 16 additions & 0 deletions src/Files/UserControls/NavigationToolbar.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -562,6 +562,22 @@
Value="{x:Bind OngoingTasksViewModel.InfoBadgeValue, Mode=OneWay}" />
</Grid>

<Button
x:Name="UpdateButton"
x:Load="{x:Bind ViewModel.UpdateSettingsService.IsUpdateAvailable, Mode=OneWay}"
Width="36"
Height="32"
AccessKey="1"
AutomationProperties.Name="{helpers:ResourceString Name=UpdateFiles}"
Background="Transparent"
Command="{x:Bind ViewModel.UpdateCommand, Mode=OneWay}"
IsEnabled="{x:Bind ViewModel.UpdateSettingsService.IsUpdating, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}"
Style="{StaticResource ToolBarButtonStyle}"
ToolTipService.ToolTip="{helpers:ResourceString Name=UpdateFiles}"
HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<FontIcon FontSize="14" Glyph="&#xE896;" />
</Button>

<Button
x:Name="SettingsButton"
Width="36"
Expand Down
4 changes: 4 additions & 0 deletions src/Files/ViewModels/NavToolbarViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ public class NavToolbarViewModel : ObservableObject, INavigationToolbar, IDispos
{
private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService<IUserSettingsService>();

public IUpdateSettingsService UpdateSettingsService { get; } = Ioc.Default.GetService<IUpdateSettingsService>();

public delegate void ToolbarPathItemInvokedEventHandler(object sender, PathNavigationEventArgs e);

public delegate void ToolbarFlyoutOpenedEventHandler(object sender, ToolbarFlyoutOpenedEventArgs e);
Expand Down Expand Up @@ -816,6 +818,8 @@ public void SearchRegion_LostFocus(object sender, RoutedEventArgs e)

public ICommand InstallFontCommand { get; set; }

public ICommand UpdateCommand { get; set; }

public async Task SetPathBoxDropDownFlyoutAsync(MenuFlyout flyout, PathBoxItem pathItem, IShellPage shellPage)
{
var nextPathItemTitle = PathComponents[PathComponents.IndexOf(pathItem) + 1].Title;
Expand Down
3 changes: 3 additions & 0 deletions src/Files/Views/ColumnShellPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ public sealed partial class ColumnShellPage : Page, IShellPage, INotifyPropertyC

private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService<IUserSettingsService>();

private IUpdateSettingsService UpdateSettingsService { get; } = Ioc.Default.GetService<IUpdateSettingsService>();

public bool IsCurrentInstance
{
get
Expand Down Expand Up @@ -228,6 +230,7 @@ private void InitToolbarCommands()
NavToolbarViewModel.RotateImageLeftCommand = new RelayCommand(async () => SlimContentPage?.CommandsViewModel.RotateImageLeftCommand.Execute(null));
NavToolbarViewModel.RotateImageRightCommand = new RelayCommand(async () => SlimContentPage?.CommandsViewModel.RotateImageRightCommand.Execute(null));
NavToolbarViewModel.InstallFontCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.InstallFontCommand.Execute(null));
NavToolbarViewModel.UpdateCommand = new AsyncRelayCommand(async () => await UpdateSettingsService.DownloadUpdates());
}

private void FolderSettings_LayoutPreferencesUpdateRequired(object sender, LayoutPreferenceEventArgs e)
Expand Down
3 changes: 3 additions & 0 deletions src/Files/Views/ModernShellPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public sealed partial class ModernShellPage : Page, IShellPage, INotifyPropertyC

private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetService<IUserSettingsService>();

private IUpdateSettingsService UpdateSettingsService { get; } = Ioc.Default.GetService<IUpdateSettingsService>();

public bool IsCurrentInstance
{
get
Expand Down Expand Up @@ -213,6 +215,7 @@ private void InitToolbarCommands()
NavToolbarViewModel.RotateImageLeftCommand = new RelayCommand(async () => SlimContentPage?.CommandsViewModel.RotateImageLeftCommand.Execute(null));
NavToolbarViewModel.RotateImageRightCommand = new RelayCommand(async () => SlimContentPage?.CommandsViewModel.RotateImageRightCommand.Execute(null));
NavToolbarViewModel.InstallFontCommand = new RelayCommand(() => SlimContentPage?.CommandsViewModel.InstallFontCommand.Execute(null));
NavToolbarViewModel.UpdateCommand = new AsyncRelayCommand(async () => await UpdateSettingsService.DownloadUpdates());
}

private void ModernShellPage_RefreshWidgetsRequested(object sender, EventArgs e)
Expand Down