Skip to content

Commit 05e81d7

Browse files
authored
Feature: Display release notes after updating app (#10976)
1 parent 2005be9 commit 05e81d7

File tree

6 files changed

+161
-29
lines changed

6 files changed

+161
-29
lines changed

src/Files.App/App.xaml.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ await Task.WhenAll(
208208
var updateService = Ioc.Default.GetRequiredService<IUpdateService>();
209209
await updateService.CheckForUpdates();
210210
await updateService.DownloadMandatoryUpdates();
211+
await updateService.CheckLatestReleaseNotesAsync();
211212

212213
static async Task OptionalTask(Task task, bool condition)
213214
{

src/Files.App/ServicesImplementation/SideloadUpdateService.cs

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using System.Diagnostics;
99
using System.IO;
1010
using System.Net.Http;
11+
using System.Threading;
1112
using System.Threading.Tasks;
1213
using System.Xml.Serialization;
1314
using Windows.ApplicationModel;
@@ -55,13 +56,17 @@ public bool IsUpdating
5556
private set => SetProperty(ref _isUpdating, value);
5657
}
5758

58-
private bool _isAppUpdated;
5959
public bool IsAppUpdated
6060
{
61-
get => _isAppUpdated;
62-
private set => SetProperty(ref _isAppUpdated, value);
61+
get => SystemInformation.Instance.IsAppUpdated;
6362
}
6463

64+
private bool _isReleaseNotesAvailable;
65+
public bool IsReleaseNotesAvailable
66+
{
67+
get => _isReleaseNotesAvailable;
68+
private set => SetProperty(ref _isReleaseNotesAvailable, value);
69+
}
6570
public async Task DownloadUpdates()
6671
{
6772
await ApplyPackageUpdate();
@@ -72,9 +77,33 @@ public Task DownloadMandatoryUpdates()
7277
return Task.CompletedTask;
7378
}
7479

75-
public SideloadUpdateService()
80+
public async Task<string?> GetLatestReleaseNotesAsync(CancellationToken cancellationToken = default)
81+
{
82+
var applicationVersion = $"{SystemInformation.Instance.ApplicationVersion.Major}.{SystemInformation.Instance.ApplicationVersion.Minor}.{SystemInformation.Instance.ApplicationVersion.Build}";
83+
var releaseNotesLocation = string.Concat("https://raw.githubusercontent.com/files-community/Release-Notes/main/", applicationVersion, ".md");
84+
85+
using (var client = new HttpClient())
86+
{
87+
try
88+
{
89+
var result = await client.GetStringAsync(releaseNotesLocation, cancellationToken);
90+
return result == string.Empty ? null : result;
91+
}
92+
catch
93+
{
94+
return null;
95+
}
96+
}
97+
}
98+
99+
public async Task CheckLatestReleaseNotesAsync(CancellationToken cancellationToken = default)
76100
{
77-
IsAppUpdated = SystemInformation.Instance.IsAppUpdated;
101+
if (!IsAppUpdated)
102+
return;
103+
104+
var result = await GetLatestReleaseNotesAsync();
105+
if (result is not null)
106+
IsReleaseNotesAvailable = true;
78107
}
79108

80109
public async Task CheckForUpdates()

src/Files.App/ServicesImplementation/UpdateService.cs

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
using System.Collections.Generic;
88
using System.IO;
99
using System.Linq;
10+
using System.Net.Http;
11+
using System.Threading;
1012
using System.Threading.Tasks;
1113
using Windows.Services.Store;
1214
using WinRT.Interop;
@@ -34,18 +36,21 @@ public bool IsUpdating
3436
private set => SetProperty(ref _isUpdating, value);
3537
}
3638

37-
private bool _isAppUpdated;
39+
private bool _isReleaseNotesAvailable;
40+
public bool IsReleaseNotesAvailable
41+
{
42+
get => _isReleaseNotesAvailable;
43+
private set => SetProperty(ref _isReleaseNotesAvailable, value);
44+
}
45+
3846
public bool IsAppUpdated
3947
{
40-
get => _isAppUpdated;
41-
private set => SetProperty(ref _isAppUpdated, value);
48+
get => SystemInformation.Instance.IsAppUpdated;
4249
}
4350

4451
public UpdateService()
4552
{
4653
_updatePackages = new List<StorePackageUpdate>();
47-
48-
IsAppUpdated = SystemInformation.Instance.IsAppUpdated;
4954
}
5055

5156
public async Task DownloadUpdates()
@@ -143,6 +148,36 @@ private static async Task<bool> ShowDialogAsync()
143148
return result == ContentDialogResult.Primary;
144149
}
145150

151+
public async Task CheckLatestReleaseNotesAsync(CancellationToken cancellationToken = default)
152+
{
153+
if (!IsAppUpdated)
154+
return;
155+
156+
var result = await GetLatestReleaseNotesAsync();
157+
158+
if (result is not null)
159+
IsReleaseNotesAvailable = true;
160+
}
161+
162+
public async Task<string?> GetLatestReleaseNotesAsync(CancellationToken cancellationToken = default)
163+
{
164+
var applicationVersion = $"{SystemInformation.Instance.ApplicationVersion.Major}.{SystemInformation.Instance.ApplicationVersion.Minor}.{SystemInformation.Instance.ApplicationVersion.Build}";
165+
var releaseNotesLocation = string.Concat("https://raw.githubusercontent.com/files-community/Release-Notes/main/", applicationVersion, ".md");
166+
167+
using (var client = new HttpClient())
168+
{
169+
try
170+
{
171+
var result = await client.GetStringAsync(releaseNotesLocation, cancellationToken);
172+
return result == string.Empty ? null : result;
173+
}
174+
catch
175+
{
176+
return null;
177+
}
178+
}
179+
}
180+
146181
// WINUI3
147182
private static ContentDialog SetContentDialogRoot(ContentDialog contentDialog)
148183
{

src/Files.App/UserControls/AddressToolbar.xaml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -265,18 +265,18 @@
265265
x:Name="UpdateButton"
266266
HorizontalContentAlignment="Stretch"
267267
VerticalContentAlignment="Stretch"
268-
x:Load="{x:Bind ViewModel.UpdateService.IsUpdateAvailable, Mode=OneWay}"
268+
x:Load="{x:Bind ViewModel.IsUpdateAvailable, Mode=OneWay}"
269269
AccessKey="1"
270270
AutomationProperties.Name="{helpers:ResourceString Name=UpdateFiles}"
271271
Command="{x:Bind ViewModel.UpdateCommand, Mode=OneWay}"
272-
IsEnabled="{x:Bind ViewModel.UpdateService.IsUpdating, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}"
272+
IsEnabled="{x:Bind ViewModel.IsUpdating, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}"
273273
Style="{StaticResource AddressToolbarButtonStyle}"
274274
ToolTipService.ToolTip="{helpers:ResourceString Name=UpdateFiles}">
275275
<Grid>
276276
<!-- Icon -->
277277
<FontIcon
278278
x:Name="UpdateIcon"
279-
x:Load="{x:Bind ViewModel.UpdateService.IsUpdating, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}"
279+
x:Load="{x:Bind ViewModel.IsUpdating, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}"
280280
FontSize="14"
281281
Foreground="{ThemeResource SystemAccentColor}"
282282
Glyph="&#xE896;" />
@@ -286,7 +286,7 @@
286286
x:Name="UpdateProgressRing"
287287
Width="20"
288288
Height="20"
289-
x:Load="{x:Bind ViewModel.UpdateService.IsUpdating, Mode=OneWay}"
289+
x:Load="{x:Bind ViewModel.IsUpdating, Mode=OneWay}"
290290
IsIndeterminate="True" />
291291
</Grid>
292292
</Button>
@@ -296,7 +296,7 @@
296296
x:Name="ViewReleaseNotesButton"
297297
HorizontalContentAlignment="Stretch"
298298
VerticalContentAlignment="Stretch"
299-
x:Load="{x:Bind ViewModel.UpdateService.IsAppUpdated, Mode=OneWay}"
299+
x:Load="{x:Bind ViewModel.IsReleaseNotesVisible, Mode=OneWay}"
300300
AccessKey="2"
301301
AutomationProperties.Name="{helpers:ResourceString Name=ReleaseNotes}"
302302
Command="{x:Bind ViewModel.ViewReleaseNotesCommand, Mode=OneWay}"
@@ -338,7 +338,6 @@
338338
<!-- Release Notes Teaching Tip -->
339339
<TeachingTip
340340
x:Name="ReleaseNotesTeachingTip"
341-
Title="{helpers:ResourceString Name=ReleaseNotes}"
342341
IsLightDismissEnabled="True"
343342
IsOpen="{x:Bind ViewModel.IsReleaseNotesOpen, Mode=TwoWay}"
344343
Target="{x:Bind ViewReleaseNotesButton}">
@@ -361,13 +360,14 @@
361360
<!-- Markdown Content -->
362361
<TeachingTip.Content>
363362
<ScrollViewer
363+
Width="260"
364364
Height="240"
365-
HorizontalScrollMode="Disabled"
366-
VerticalScrollMode="Enabled">
365+
HorizontalScrollMode="Auto"
366+
VerticalScrollMode="Auto">
367367
<controls:MarkdownTextBlock
368-
Padding="0,12"
369368
Background="Transparent"
370-
Text="Coming Soon 👀" />
369+
ListGutterWidth="16"
370+
Text="{x:Bind ViewModel.ReleaseNotes, Mode=OneWay}" />
371371
</ScrollViewer>
372372
</TeachingTip.Content>
373373
</TeachingTip>

src/Files.App/ViewModels/ToolbarViewModel.cs

Lines changed: 60 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Files.App.Filesystem;
88
using Files.App.Filesystem.StorageItems;
99
using Files.App.Helpers;
10+
using Files.App.ServicesImplementation;
1011
using Files.App.Shell;
1112
using Files.App.UserControls;
1213
using Files.App.Views;
@@ -23,10 +24,13 @@
2324
using System;
2425
using System.Collections.Generic;
2526
using System.Collections.ObjectModel;
27+
using System.ComponentModel;
2628
using System.IO;
2729
using System.Linq;
30+
using System.Net.Http;
2831
using System.Threading.Tasks;
2932
using System.Windows.Input;
33+
using Vanara.PInvoke;
3034
using Windows.ApplicationModel.DataTransfer;
3135
using Windows.Storage;
3236
using Windows.UI.Text;
@@ -40,7 +44,6 @@ namespace Files.App.ViewModels
4044
public class ToolbarViewModel : ObservableObject, IAddressToolbar, IDisposable
4145
{
4246
private IUserSettingsService UserSettingsService { get; } = Ioc.Default.GetRequiredService<IUserSettingsService>();
43-
4447
public IUpdateService UpdateService { get; } = Ioc.Default.GetService<IUpdateService>()!;
4548

4649
public delegate void ToolbarPathItemInvokedEventHandler(object sender, PathNavigationEventArgs e);
@@ -252,6 +255,41 @@ public bool IsLayoutAdaptive
252255
public bool IsAdaptiveLayoutEnabled
253256
=> UserSettingsService.FoldersSettingsService.EnableOverridingFolderPreferences;
254257

258+
private bool isUpdating;
259+
public bool IsUpdating
260+
{
261+
get => isUpdating;
262+
set => SetProperty(ref isUpdating, value);
263+
}
264+
265+
private bool isUpdateAvailable;
266+
public bool IsUpdateAvailable
267+
{
268+
get => isUpdateAvailable;
269+
set => SetProperty(ref isUpdateAvailable, value);
270+
}
271+
272+
private string? releaseNotes;
273+
public string? ReleaseNotes
274+
{
275+
get => releaseNotes;
276+
set => SetProperty(ref releaseNotes, value);
277+
}
278+
279+
private bool isReleaseNotesVisible;
280+
public bool IsReleaseNotesVisible
281+
{
282+
get => isReleaseNotesVisible;
283+
set => SetProperty(ref isReleaseNotesVisible, value);
284+
}
285+
286+
private bool isReleaseNotesOpen;
287+
public bool IsReleaseNotesOpen
288+
{
289+
get => isReleaseNotesOpen;
290+
set => SetProperty(ref isReleaseNotesOpen, value);
291+
}
292+
255293
private bool canCopyPathInPage;
256294
public bool CanCopyPathInPage
257295
{
@@ -312,13 +350,6 @@ public bool IsSearchBoxVisible
312350
}
313351
}
314352

315-
private bool isReleaseNotesOpen;
316-
public bool IsReleaseNotesOpen
317-
{
318-
get => isReleaseNotesOpen;
319-
set => SetProperty(ref isReleaseNotesOpen, value);
320-
}
321-
322353
private string? pathText;
323354
public string? PathText
324355
{
@@ -379,12 +410,33 @@ public ToolbarViewModel()
379410

380411
SearchBox.Escaped += SearchRegion_Escaped;
381412
UserSettingsService.OnSettingChangedEvent += UserSettingsService_OnSettingChangedEvent;
413+
UpdateService.PropertyChanged += UpdateService_OnPropertyChanged;
414+
}
415+
416+
private async void UpdateService_OnPropertyChanged(object? sender, PropertyChangedEventArgs e)
417+
{
418+
IsUpdateAvailable = UpdateService.IsUpdateAvailable;
419+
IsUpdating = UpdateService.IsUpdating;
420+
421+
// Bad code, result is called twice when checking for release notes
422+
if (UpdateService.IsReleaseNotesAvailable)
423+
await CheckForReleaseNotesAsync();
382424
}
383425

384426
private void DoViewReleaseNotes()
385427
{
386428
IsReleaseNotesOpen = true;
387429
}
430+
431+
public async Task CheckForReleaseNotesAsync()
432+
{
433+
var result = await UpdateService.GetLatestReleaseNotesAsync();
434+
if (result is null)
435+
return;
436+
437+
ReleaseNotes = result;
438+
IsReleaseNotesVisible = true;
439+
}
388440

389441
private void UserSettingsService_OnSettingChangedEvent(object? sender, SettingChangedEventArgs e)
390442
{

src/Files.Backend/Services/IUpdateService.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
using System.ComponentModel;
1+
using System;
2+
using System.Collections.Generic;
3+
using System.ComponentModel;
4+
using System.Threading;
25
using System.Threading.Tasks;
36

47
namespace Files.Backend.Services
@@ -20,10 +23,22 @@ public interface IUpdateService : INotifyPropertyChanged
2023
/// </summary>
2124
bool IsAppUpdated { get; }
2225

26+
/// <summary>
27+
/// Gets a value indicating if release notes are available.
28+
/// </summary>
29+
bool IsReleaseNotesAvailable { get; }
30+
2331
Task DownloadUpdates();
2432

2533
Task DownloadMandatoryUpdates();
2634

2735
Task CheckForUpdates();
36+
37+
Task CheckLatestReleaseNotesAsync(CancellationToken cancellationToken = default);
38+
39+
/// <summary>
40+
/// Gets release notes for the latest release
41+
/// </summary>
42+
Task<string?> GetLatestReleaseNotesAsync(CancellationToken cancellationToken = default);
2843
}
2944
}

0 commit comments

Comments
 (0)