Skip to content

Commit 0cf1dbd

Browse files
committed
feat: add progress dialog functionality
- Implement `MessageBoxHelper` for error and progress dialogs - Create `ProgressViewModel` for managing progress state - Add `ProgressWindow` view for displaying progress - Update `IDialogService` and `DialogService` to support progress dialog
1 parent 20f8f2e commit 0cf1dbd

7 files changed

Lines changed: 148 additions & 3 deletions

File tree

SubRenamer/Helper/IssueReporter.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,15 @@ public static void CheckCrashAndShowDialog()
2525
var crashLog = await File.ReadAllTextAsync(App.CrashLogFile);
2626
var title = crashLog.Split('\n').FirstOrDefault() ?? "";
2727

28-
var reportBtnName = Application.Current.GetResource<string>("App.Strings.IssueReporterReport");
28+
var reportBtnName = Application.Current.GetResource<string>("App.Strings.IssueReporterReport") ?? "Report";
2929
var box = MessageBoxManager.GetMessageBoxCustom(new MessageBoxCustomParams
3030
{
3131
ButtonDefinitions = new List<ButtonDefinition>
3232
{
3333
new ButtonDefinition { Name = reportBtnName, IsDefault = true },
34-
new ButtonDefinition { Name = Application.Current.GetResource<string>("App.Strings.IssueReporterIgnore"), IsCancel = true }
34+
new ButtonDefinition { Name = Application.Current.GetResource<string>("App.Strings.IssueReporterIgnore") ?? "Ignore", IsCancel = true }
3535
},
36-
ContentTitle = Application.Current.GetResource<string>("App.Strings.IssueReporterCapital"),
36+
ContentTitle = Application.Current.GetResource<string>("App.Strings.IssueReporterCapital") ?? "Issue Reporter",
3737
ContentMessage = $"{title}\n\n{Application.Current.GetResource<string>("App.Strings.IssueReporterMessage")}",
3838
Icon = MsBox.Avalonia.Enums.Icon.Warning,
3939
WindowStartupLocation = WindowStartupLocation.CenterScreen,
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
using System;
2+
using System.Threading.Tasks;
3+
using Avalonia.Controls;
4+
using Avalonia.Threading;
5+
using MsBox.Avalonia;
6+
using MsBox.Avalonia.Dto;
7+
using MsBox.Avalonia.Enums;
8+
using SubRenamer.ViewModels;
9+
using SubRenamer.Views;
10+
11+
namespace SubRenamer.Helper;
12+
13+
public static class MessageBoxHelper
14+
{
15+
public static void ShowError(string text)
16+
{
17+
Dispatcher.UIThread.Post(() =>
18+
{
19+
var box = MessageBoxManager.GetMessageBoxStandard(new MessageBoxStandardParams
20+
{
21+
ButtonDefinitions = ButtonEnum.Ok,
22+
ContentTitle = "Error",
23+
ContentMessage = text,
24+
Icon = Icon.Error,
25+
MaxWidth = 500,
26+
MaxHeight = 800,
27+
Topmost = true,
28+
WindowStartupLocation = WindowStartupLocation.CenterScreen
29+
});
30+
box.ShowAsync();
31+
});
32+
}
33+
34+
public static ProgressViewModel ShowProgress(Window target, string title, string desc, Action? onAbort = null)
35+
{
36+
var store = new ProgressViewModel(title, desc);
37+
if (onAbort != null) store.OnAbort += onAbort;
38+
var dialog = new ProgressWindow()
39+
{
40+
DataContext = store
41+
};
42+
dialog.Show(target);
43+
return store;
44+
}
45+
}

SubRenamer/Model/IDialogService.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
using System;
12
using System.Collections.Generic;
23
using System.Collections.ObjectModel;
34
using System.Threading.Tasks;
5+
using SubRenamer.ViewModels;
46

57
namespace SubRenamer.Model;
68

@@ -12,4 +14,5 @@ public interface IDialogService
1214
public Task OpenManualModeSetting();
1315
public Task OpenItemEdit(MatchItem item, ObservableCollection<MatchItem> collection);
1416
public Task<string?> OpenConflict(List<string> options);
17+
public Task<ProgressViewModel> OpenProgressDialog(string title, string progressText, Action onAbort);
1518
}

SubRenamer/Services/DialogService.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,4 +87,9 @@ public async Task OpenManualModeSetting()
8787
};
8888
await dialog.ShowDialog(_target);
8989
}
90+
91+
public Task<ProgressViewModel> OpenProgressDialog(string title, string desc, Action onAbort)
92+
{
93+
return Task.FromResult(MessageBoxHelper.ShowProgress(_target, title, desc, onAbort));
94+
}
9095
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using Avalonia.Controls;
3+
using CommunityToolkit.Mvvm.ComponentModel;
4+
using CommunityToolkit.Mvvm.Input;
5+
6+
namespace SubRenamer.ViewModels;
7+
8+
public partial class ProgressViewModel(string title, string desc) : ViewModelBase
9+
{
10+
[ObservableProperty] private string _title = title;
11+
[ObservableProperty] private string _desc = desc;
12+
[ObservableProperty] private int _progress;
13+
[ObservableProperty] private bool _isDone;
14+
[ObservableProperty] private string _progressText = "0%";
15+
16+
partial void OnProgressChanged(int value)
17+
=> ProgressText = $"{value}%";
18+
19+
public event Action? OnAbort;
20+
21+
public void Update(int value, bool isDone)
22+
{
23+
Progress = value;
24+
IsDone = isDone;
25+
}
26+
27+
[RelayCommand]
28+
public void Abort(Window? window)
29+
{
30+
OnAbort?.Invoke();
31+
window?.Close();
32+
}
33+
34+
[RelayCommand]
35+
public void Done(Window? window)
36+
{
37+
window?.Close();
38+
}
39+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<Window xmlns="https://github.com/avaloniaui"
2+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
3+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
4+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
5+
xmlns:vm="using:SubRenamer.ViewModels"
6+
mc:Ignorable="d"
7+
WindowStartupLocation="CenterOwner"
8+
Width="430"
9+
Height="140"
10+
CanResize="False"
11+
x:Class="SubRenamer.Views.ProgressWindow"
12+
x:Name="ProgressWindowRef"
13+
x:DataType="vm:ProgressViewModel"
14+
Title="{Binding Title}">
15+
16+
<Design.DataContext>
17+
<vm:ProgressViewModel/>
18+
</Design.DataContext>
19+
20+
<StackPanel Margin="20">
21+
<TextBlock Text="{Binding Desc}" />
22+
<Border Height="10" />
23+
<ProgressBar Margin="0 10" Height="10" Minimum="0" Maximum="100" Value="{Binding Progress}" />
24+
<Border Height="10" />
25+
<Grid ColumnDefinitions="Auto,*,Auto">
26+
<TextBlock Grid.Column="0" Text="{Binding ProgressText}" />
27+
<Button Grid.Column="2" IsVisible="{Binding !IsDone}" Content="{DynamicResource App.Strings.ProgressDialogCancel}" Command="{Binding AbortCommand}" CommandParameter="{Binding ElementName=ProgressWindowRef}" />
28+
<Button Grid.Column="2" IsVisible="{Binding IsDone}" Content="{DynamicResource App.Strings.ProgressDialogDone}" Command="{Binding DoneCommand}" CommandParameter="{Binding ElementName=ProgressWindowRef}" />
29+
</Grid>
30+
</StackPanel>
31+
</Window>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using Avalonia;
2+
using Avalonia.Controls;
3+
using Avalonia.Interactivity;
4+
using Avalonia.Markup.Xaml;
5+
6+
namespace SubRenamer.Views;
7+
8+
public partial class ProgressWindow : Window
9+
{
10+
public ProgressWindow()
11+
{
12+
InitializeComponent();
13+
14+
Closed += (sender, args) =>
15+
{
16+
if (DataContext is not ViewModels.ProgressViewModel vm) return;
17+
18+
if (vm.IsDone) vm.Done(this);
19+
else vm.Abort(this);
20+
};
21+
}
22+
}

0 commit comments

Comments
 (0)