Skip to content

Commit 4792969

Browse files
committed
Final (I think) fixes to the theme downloader
- Added a cancel button and associated logic when downloading themes - Made the text colour be the opposite of the progress bar below it - Added a try catch around extracting a theme, just in case - Moved the dialog handling to a task, which I was hoping would allow the progress bar to update but sadly still no - The download dialog is only created once and then reused, so it doesn't pop up twice when downloading the heroes mod loader theme
1 parent 47754cc commit 4792969

4 files changed

Lines changed: 92 additions & 32 deletions

File tree

source/Reloaded.Mod.Launcher/Pages/Dialogs/ThemeDownloadDialog.xaml

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,23 @@
1616

1717
<Grid Height="50" Background="{DynamicResource BackgroundBrush}">
1818
<Grid Margin="6">
19-
<Grid Width="485" HorizontalAlignment="Center">
20-
<ProgressBar x:Name="ThemeProgressBar"/>
19+
<Grid Width="400" HorizontalAlignment="Left">
20+
<ProgressBar x:Name="ThemeProgressBar" />
2121
<TextBlock
2222
x:Name="ThemeTextBlock"
2323
HorizontalAlignment="Center"
24-
VerticalAlignment="Center"
25-
Foreground="White"/>
24+
VerticalAlignment="Center">
25+
<TextBlock.Foreground>
26+
<LinearGradientBrush>
27+
<GradientStop Offset="0.0" Color="Black" />
28+
<GradientStop Offset="0.0" Color="White" />
29+
</LinearGradientBrush>
30+
</TextBlock.Foreground>
31+
</TextBlock>
32+
</Grid>
33+
34+
<Grid Width="90" HorizontalAlignment="Right">
35+
<Button Name="CancelButton" PreviewMouseDown="CancelButton_PreviewMouseDown">Cancel</Button>
2636
</Grid>
2737
</Grid>
2838
</Grid>

source/Reloaded.Mod.Launcher/Pages/Dialogs/ThemeDownloadDialog.xaml.cs

Lines changed: 45 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,61 +5,91 @@
55

66
namespace Reloaded.Mod.Launcher.Pages.Dialogs;
77

8+
public enum ThemeDownloadDialogResult
9+
{
10+
Ok,
11+
Cancelled,
12+
Failed
13+
}
14+
15+
816
/// <summary>
917
/// Interaction logic for ThemeDownloadDialog.xaml
1018
/// </summary>
1119
public partial class ThemeDownloadDialog : ReloadedWindow
1220
{
13-
private readonly CancellationTokenSource CancellationToken;
14-
private readonly Task DownloadTask;
21+
private CancellationTokenSource CancellationToken;
1522

16-
public ThemeDownloadDialog(GameBananaModFile file)
23+
public ThemeDownloadDialog()
1724
{
1825
InitializeComponent();
1926

2027
CancellationToken = new CancellationTokenSource();
28+
}
29+
30+
// progress is measured from 0-1
31+
private void UpdateProgressBar(double progress)
32+
{
33+
for (int i = 0; i < 2; i++)
34+
((System.Windows.Media.LinearGradientBrush)ThemeTextBlock.Foreground).GradientStops[i].Offset = progress;
2135

22-
DownloadTask = DownloadAndExtractZip(file);
23-
ShowDialog();
24-
DownloadTask.Wait();
36+
ThemeProgressBar.Value = progress * 100;
2537
}
2638

27-
public async Task DownloadAndExtractZip(GameBananaModFile file)
39+
public async Task<ThemeDownloadDialogResult> DownloadAndExtractZip(GameBananaModFile file)
2840
{
41+
CancellationToken = new CancellationTokenSource();
42+
43+
var result = ThemeDownloadDialogResult.Ok;
44+
45+
UpdateProgressBar(0);
2946
ThemeTextBlock.Text = $"Downloading {file.FileName}...";
3047

3148
var handler = new HttpClientHandler() { AllowAutoRedirect = true };
3249
var progressHandler = new ProgressMessageHandler(handler);
3350

34-
// This is supposed to update the progress bar as it's downloading, emphasis on supposed to
35-
progressHandler.HttpReceiveProgress += (obj, args) => { ThemeProgressBar.Value = (args.BytesTransferred / (double)args.TotalBytes!) * 100.0; };
51+
progressHandler.HttpReceiveProgress += (obj, args) => { UpdateProgressBar(args.BytesTransferred / (double)args.TotalBytes!); };
3652

3753
int attempts = 0;
3854
Stream zipStream;
3955
Retry:
4056
try
4157
{
42-
zipStream = await new HttpClient(progressHandler).GetStreamAsync(file.DownloadUrl);
58+
zipStream = await new HttpClient(progressHandler).GetStreamAsync(file.DownloadUrl, CancellationToken.Token);
4359
}
44-
catch (Exception e)
60+
catch
4561
{
4662
if (attempts++ < 10)
4763
goto Retry;
4864

49-
var messageBox = new MessageBox("Theme Download Error", "Failed to download the mod! Check your internet connection, and if that's good, it might just be GameBanana's servers acting up, try again later");
65+
var messageBox = new MessageBox("Theme Download Error", "Failed to download the theme! Check your internet connection, and if that's good, it might just be GameBanana's servers acting up, try again later");
5066
messageBox.ShowDialog();
5167

68+
result = ThemeDownloadDialogResult.Failed;
5269
// I know, I know, gotos are bad, but in this case it saves a few lines of code -zw
5370
goto Exit;
5471
}
5572

56-
ThemeTextBlock.Text = $"Extracting {file.FileName}...";
57-
ZipFile.ExtractToDirectory(zipStream, ThemeDownloader.TempFolder);
73+
if (CancellationToken.IsCancellationRequested)
74+
result = ThemeDownloadDialogResult.Cancelled;
75+
else
76+
{
77+
ThemeTextBlock.Text = $"Extracting {file.FileName}...";
78+
try
79+
{
80+
ZipFile.ExtractToDirectory(zipStream, ThemeDownloader.TempFolder);
81+
}
82+
catch
83+
{
84+
result = ThemeDownloadDialogResult.Failed;
85+
goto Exit;
86+
}
87+
}
5888

5989
zipStream.Close();
6090

6191
Exit:
62-
Close();
92+
return result;
6393
}
6494

6595
private void CancelButton_PreviewMouseDown(object sender, MouseButtonEventArgs e)

source/Reloaded.Mod.Launcher/Utility/ThemeDownloader.cs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ private static bool ThemeNeedsToBeCreated(out List<bool> existingXAMLs)
238238
return createTheme;
239239
}
240240

241-
private static void DownloadTheme(GameBananaMod theme)
241+
private static async Task DownloadTheme(GameBananaMod theme, ThemeDownloadDialog dialog)
242242
{
243243
// There needs to be a standard for how to upload themes
244244
// I'll support all of the current ones but there's likely to be an edge case that causes it to break in the future -zw
@@ -254,7 +254,8 @@ private static void DownloadTheme(GameBananaMod theme)
254254

255255
if (theme.Files.Count == 1 && theme.Files[0].FileName.EndsWith(".zip"))
256256
{
257-
new ThemeDownloadDialog(theme.Files[0]);
257+
if (await dialog.DownloadAndExtractZip(theme.Files[0]) != ThemeDownloadDialogResult.Ok)
258+
goto Exit;
258259

259260
if (ThemeNeedsToBeCreated(out var existingXAMLs))
260261
{
@@ -283,12 +284,13 @@ private static void DownloadTheme(GameBananaMod theme)
283284
// Checking for the heroes mod loader theme
284285
else if (theme.Files.Count == 2 && theme.Files[0].FileName == "default_5073e.zip")
285286
{
286-
new ThemeDownloadDialog(theme.Files[0]);
287+
288+
if (await dialog.DownloadAndExtractZip(theme.Files[0]) != ThemeDownloadDialogResult.Ok) goto Exit;
287289

288290
Directory.Move($"{TempFolder}/Default", themeFolder);
289291
Directory.Delete(TempFolder);
290292

291-
new ThemeDownloadDialog(theme.Files[1]);
293+
if (await dialog.DownloadAndExtractZip(theme.Files[1]) != ThemeDownloadDialogResult.Ok) goto Exit;
292294

293295
string imagesFolder = $"{themeFolder}/Images";
294296
Directory.Move(TempFolder, imagesFolder);
@@ -301,20 +303,22 @@ private static void DownloadTheme(GameBananaMod theme)
301303
CopyFromHalogen($"{ThemeFolder}/Halogen.xaml", themeFolder + ".xaml", themeName);
302304
}
303305

306+
Exit:
307+
dialog.Close();
304308
DeleteTempFiles();
305309
}
306310

307311
/// <summary>
308312
/// Finds the theme from the given .xaml, and then downloads and installs it
309313
/// </summary>
310314
/// <param name="name">The .xaml to load from the theme selector</param>
311-
public static void DownloadThemeByName(string name)
315+
public static async Task DownloadThemeByName(string name, ThemeDownloadDialog dialog)
312316
{
313317
foreach ((var subtheme, var index) in ThemesDictionary)
314318
{
315319
if (subtheme == name)
316320
{
317-
DownloadTheme(AvailableThemes[index]);
321+
await DownloadTheme(AvailableThemes[index], dialog);
318322
break;
319323
}
320324
}

source/Reloaded.Mod.Launcher/Utility/XamlThemeSelector.cs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,27 @@ private void PopulateAndFetch(string selectedTheme, bool fetch=true)
2828
}
2929
}
3030

31+
private async Task DownloadTheme()
32+
{
33+
string selectedTheme = File!;
34+
35+
var dialog = new ThemeDownloadDialog();
36+
var task = ThemeDownloader.DownloadThemeByName(File, dialog);
37+
dialog.ShowDialog();
38+
await task;
39+
40+
bool exists = System.IO.File.Exists(selectedTheme);
41+
42+
PopulateAndFetch(exists ? selectedTheme : ThemeDownloader.GetFullPath("Default.xaml"), false);
43+
44+
if (exists)
45+
{
46+
// Probably the bodgey-est bodge I've ever done -zw
47+
File = Files.FirstOrDefault();
48+
File = selectedTheme;
49+
}
50+
}
51+
3152
protected override void UpdateSource()
3253
{
3354
if (File == null)
@@ -45,13 +66,8 @@ protected override void UpdateSource()
4566
}
4667
catch
4768
{
48-
var selectedTheme = File;
49-
ThemeDownloader.DownloadThemeByName(File);
50-
PopulateAndFetch(selectedTheme, false);
51-
52-
// Probably the bodgey-est bodge I've ever done -zw
53-
File = Files.FirstOrDefault();
54-
File = selectedTheme;
69+
DownloadTheme();
70+
return;
5571
}
5672

5773
/*

0 commit comments

Comments
 (0)