Skip to content

Commit e37e681

Browse files
committed
🥁 Remember used output templates
While here, clean up and fix the logic for download path history.
1 parent a6adc48 commit e37e681

File tree

5 files changed

+84
-28
lines changed

5 files changed

+84
-28
lines changed

YoutubeDl.Wpf/Models/ObservableSettings.cs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,17 +84,23 @@ public class ObservableSettings : ReactiveObject
8484
[Reactive]
8585
public string CustomOutputTemplate { get; set; }
8686

87+
/// <summary>
88+
/// Gets the list of used output templates.
89+
/// New templates are appended to the list.
90+
/// </summary>
91+
public List<string> OutputTemplateHistory { get; }
92+
8793
[Reactive]
8894
public bool UseCustomPath { get; set; }
8995

9096
[Reactive]
9197
public string DownloadPath { get; set; }
9298

9399
/// <summary>
94-
/// Gets the list of download path history.
95-
/// New paths are always appended to the list.
100+
/// Gets the list of used download paths.
101+
/// New paths are appended to the list.
96102
/// </summary>
97-
public List<string> DownloadPathHistory { get; set; }
103+
public List<string> DownloadPathHistory { get; }
98104

99105
public ObservableSettings(Settings settings)
100106
{
@@ -120,6 +126,7 @@ public ObservableSettings(Settings settings)
120126
DownloadPlaylist = settings.DownloadPlaylist;
121127
UseCustomOutputTemplate = settings.UseCustomOutputTemplate;
122128
CustomOutputTemplate = settings.CustomOutputTemplate;
129+
OutputTemplateHistory = new(settings.OutputTemplateHistory);
123130
UseCustomPath = settings.UseCustomPath;
124131
DownloadPath = settings.DownloadPath;
125132
DownloadPathHistory = new(settings.DownloadPathHistory);
@@ -149,6 +156,7 @@ public void UpdateAppSettings()
149156
AppSettings.UseCustomOutputTemplate = UseCustomOutputTemplate;
150157
AppSettings.CustomOutputTemplate = CustomOutputTemplate;
151158
AppSettings.UseCustomPath = UseCustomPath;
159+
AppSettings.OutputTemplateHistory = OutputTemplateHistory.ToArray();
152160
AppSettings.DownloadPath = DownloadPath;
153161
AppSettings.DownloadPathHistory = DownloadPathHistory.ToArray();
154162
}

YoutubeDl.Wpf/Models/Settings.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,8 @@ public class Settings
7575

7676
public string CustomOutputTemplate { get; set; } = DefaultCustomFilenameTemplate;
7777

78+
public string[] OutputTemplateHistory { get; set; } = Array.Empty<string>();
79+
7880
public bool UseCustomPath { get; set; }
7981

8082
public string DownloadPath { get; set; } = "";

YoutubeDl.Wpf/ViewModels/HomeViewModel.cs

Lines changed: 51 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
using System.Linq;
1111
using System.Reactive;
1212
using System.Reactive.Linq;
13+
using System.Threading;
14+
using System.Threading.Tasks;
1315
using YoutubeDl.Wpf.Models;
1416
using YoutubeDl.Wpf.Utils;
1517

@@ -34,19 +36,26 @@ public class HomeViewModel : ReactiveValidationObject
3436

3537
public ObservableCollection<Preset> Presets { get; } = new();
3638

39+
/// <summary>
40+
/// Gets the output template history.
41+
/// This collection was first constructed from <see cref="ObservableSettings.OutputTemplateHistory"/> in reverse order.
42+
/// So the newest template is always the first element.
43+
/// </summary>
44+
public ObservableCollection<HistoryItemViewModel> OutputTemplateHistory { get; }
45+
3746
/// <summary>
3847
/// Gets the download path history.
3948
/// This collection was first constructed from <see cref="ObservableSettings.DownloadPathHistory"/> in reverse order.
4049
/// So the newest path is always the first element.
4150
/// </summary>
42-
public ObservableCollection<HistoryItemViewModel> DownloadPathHistory { get; } = new();
51+
public ObservableCollection<HistoryItemViewModel> DownloadPathHistory { get; }
4352

4453
/// <summary>
4554
/// Gets the collection of view models of the arguments area.
4655
/// A view model in this collection must be of either
4756
/// <see cref="ArgumentChipViewModel"/> or <see cref="AddArgumentViewModel"/> type.
4857
/// </summary>
49-
public ObservableCollection<object> DownloadArguments { get; } = new();
58+
public ObservableCollection<object> DownloadArguments { get; }
5059

5160
[Reactive]
5261
public string Link { get; set; } = "";
@@ -113,10 +122,12 @@ public HomeViewModel(ObservableSettings settings, BackendService backendService,
113122
Presets.AddRange(Preset.PredefinedPresets.Where(x => (x.SupportedBackends & SharedSettings.Backend) == SharedSettings.Backend));
114123
});
115124

116-
DownloadPathHistory.AddRange(SharedSettings.DownloadPathHistory.Select(x => new HistoryItemViewModel(x, DeleteDownloadPathItem)).Reverse());
117-
118-
DownloadArguments.AddRange(SharedSettings.BackendDownloadArguments.Select(x => new ArgumentChipViewModel(x, true, DeleteArgumentChip)));
119-
DownloadArguments.Add(new AddArgumentViewModel(AddArgument));
125+
OutputTemplateHistory = new(SharedSettings.OutputTemplateHistory.Select(x => new HistoryItemViewModel(x, DeleteOutputTemplateItem)).Reverse());
126+
DownloadPathHistory = new(SharedSettings.DownloadPathHistory.Select(x => new HistoryItemViewModel(x, DeleteDownloadPathItem)).Reverse());
127+
DownloadArguments = new(SharedSettings.BackendDownloadArguments.Select(x => new ArgumentChipViewModel(x, true, DeleteArgumentChip)))
128+
{
129+
new AddArgumentViewModel(AddArgument),
130+
};
120131

121132
var gdaA = this.WhenAnyValue(
122133
x => x.SharedSettings.Backend,
@@ -164,15 +175,18 @@ public HomeViewModel(ObservableSettings settings, BackendService backendService,
164175

165176
var canRun = this.WhenAnyValue(
166177
x => x.Link,
178+
x => x.BackendInstance.IsRunning,
179+
x => x.SharedSettings.UseCustomOutputTemplate,
167180
x => x.SharedSettings.UseCustomPath,
181+
x => x.SharedSettings.CustomOutputTemplate,
168182
x => x.SharedSettings.DownloadPath,
169183
x => x.SharedSettings.BackendPath,
170-
x => x.BackendInstance.IsRunning,
171-
(link, useCustomPath, downloadPath, dlBinaryPath, isRunning) =>
184+
(link, isRunning, useCustomOutputTemplate, useCustomPath, outputTemplate, downloadPath, backendPath) =>
172185
!string.IsNullOrEmpty(link) &&
186+
!isRunning &&
187+
(!useCustomOutputTemplate || !string.IsNullOrEmpty(outputTemplate)) &&
173188
(!useCustomPath || Directory.Exists(downloadPath)) &&
174-
!string.IsNullOrEmpty(dlBinaryPath) &&
175-
!isRunning);
189+
!string.IsNullOrEmpty(backendPath));
176190

177191
var canAbort = this.WhenAnyValue(x => x.BackendInstance.IsRunning);
178192

@@ -187,7 +201,7 @@ public HomeViewModel(ObservableSettings settings, BackendService backendService,
187201
ResetCustomFilenameTemplateCommand = ReactiveCommand.Create(ResetCustomFilenameTemplate, canResetCustomFilenameTemplate);
188202
BrowseDownloadFolderCommand = ReactiveCommand.Create(BrowseDownloadFolder, canBrowseDownloadFolder);
189203
OpenDownloadFolderCommand = ReactiveCommand.Create(OpenDownloadFolder, canOpenDownloadFolder);
190-
StartDownloadCommand = ReactiveCommand.CreateFromTask<string>(BackendInstance.StartDownloadAsync, canRun);
204+
StartDownloadCommand = ReactiveCommand.CreateFromTask<string>(StartDownloadAsync, canRun);
191205
ListFormatsCommand = ReactiveCommand.CreateFromTask<string>(BackendInstance.ListFormatsAsync, canRun);
192206
AbortCommand = ReactiveCommand.CreateFromTask(BackendInstance.AbortAsync, canAbort);
193207

@@ -237,17 +251,29 @@ private void DeleteCustomPreset()
237251
SharedSettings.SelectedPreset = Presets.First();
238252
}
239253

254+
private void DeleteOutputTemplateItem(HistoryItemViewModel item)
255+
{
256+
SharedSettings.OutputTemplateHistory.Remove(item.Text);
257+
OutputTemplateHistory.Remove(item);
258+
}
259+
240260
private void DeleteDownloadPathItem(HistoryItemViewModel item)
241261
{
242262
SharedSettings.DownloadPathHistory.Remove(item.Text);
243263
DownloadPathHistory.Remove(item);
244264
}
245265

266+
private void UpdateOutputTemplateHistory()
267+
{
268+
if (!SharedSettings.OutputTemplateHistory.Contains(SharedSettings.CustomOutputTemplate))
269+
{
270+
SharedSettings.OutputTemplateHistory.Add(SharedSettings.CustomOutputTemplate);
271+
OutputTemplateHistory.Insert(0, new(SharedSettings.CustomOutputTemplate, DeleteOutputTemplateItem));
272+
}
273+
}
274+
246275
private void UpdateDownloadPathHistory()
247276
{
248-
// No need to check if path is null or empty.
249-
// Because this code path can only be reached
250-
// when custom path is toggled and a valid path is supplied.
251277
if (!SharedSettings.DownloadPathHistory.Contains(SharedSettings.DownloadPath))
252278
{
253279
SharedSettings.DownloadPathHistory.Add(SharedSettings.DownloadPath);
@@ -337,11 +363,6 @@ private void GenerateDownloadArguments()
337363

338364
BackendInstance.GenerateDownloadArguments();
339365

340-
if (SharedSettings.UseCustomPath)
341-
{
342-
UpdateDownloadPathHistory();
343-
}
344-
345366
var pos = _globalArgCount;
346367

347368
foreach (var arg in BackendInstance.GeneratedDownloadArguments)
@@ -350,5 +371,16 @@ private void GenerateDownloadArguments()
350371
pos++;
351372
}
352373
}
374+
375+
private Task StartDownloadAsync(string link, CancellationToken cancellationToken = default)
376+
{
377+
if (SharedSettings.UseCustomOutputTemplate)
378+
UpdateOutputTemplateHistory();
379+
380+
if (SharedSettings.UseCustomPath)
381+
UpdateDownloadPathHistory();
382+
383+
return BackendInstance.StartDownloadAsync(link, cancellationToken);
384+
}
353385
}
354386
}

YoutubeDl.Wpf/Views/HomeView.xaml

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -155,10 +155,19 @@
155155
<ToggleButton x:Name="filenameTemplateToggle"
156156
Margin="4"/>
157157
<TextBlock VerticalAlignment="Center" Margin="4">Custom filename template</TextBlock>
158-
<TextBox x:Name="filenameTemplateTextBox"
159-
Margin="4"
160-
Width="200"
161-
VerticalAlignment="Center"/>
158+
<ComboBox x:Name="outputTemplateComboBox"
159+
IsEditable="True"
160+
IsReadOnly="False"
161+
StaysOpenOnEdit="True"
162+
Margin="4"
163+
Width="200"
164+
VerticalAlignment="Center">
165+
<ComboBox.ItemsPanel>
166+
<ItemsPanelTemplate>
167+
<VirtualizingStackPanel />
168+
</ItemsPanelTemplate>
169+
</ComboBox.ItemsPanel>
170+
</ComboBox>
162171
<Button x:Name="resetFilenameTemplateButton"
163172
Margin="4"
164173
Style="{StaticResource MaterialDesignFlatButton}"

YoutubeDl.Wpf/Views/HomeView.xaml.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,12 +123,17 @@ public HomeView()
123123

124124
this.OneWayBind(ViewModel,
125125
viewModel => viewModel.SharedSettings.UseCustomOutputTemplate,
126-
view => view.filenameTemplateTextBox.IsEnabled)
126+
view => view.outputTemplateComboBox.IsEnabled)
127+
.DisposeWith(disposables);
128+
129+
this.OneWayBind(ViewModel,
130+
viewModel => viewModel.OutputTemplateHistory,
131+
view => view.outputTemplateComboBox.ItemsSource)
127132
.DisposeWith(disposables);
128133

129134
this.Bind(ViewModel,
130135
viewModel => viewModel.SharedSettings.CustomOutputTemplate,
131-
view => view.filenameTemplateTextBox.Text)
136+
view => view.outputTemplateComboBox.Text)
132137
.DisposeWith(disposables);
133138

134139
// Options row 3

0 commit comments

Comments
 (0)