1
- using BardMusicPlayer . Pigeonhole ;
1
+ using BardMusicPlayer . Coffer ;
2
+ using BardMusicPlayer . Functions ;
3
+ using BardMusicPlayer . Pigeonhole ;
2
4
using BardMusicPlayer . Resources ;
3
5
using HtmlAgilityPack ;
6
+ using System . Diagnostics ;
4
7
using System . IO ;
5
8
using System . Net . Http ;
6
9
using System . Reflection ;
@@ -21,7 +24,10 @@ public partial class MidiRepository : UserControl
21
24
private const string commentNodeXpath = ".//span[contains(@class, 'r4')]" ;
22
25
private readonly HttpClient httpClient ;
23
26
private readonly string midiRepoUrl = "https://songs.bardmusicplayer.com" ;
24
- private List < Song > listSong = new List < Song > ( ) ;
27
+ private List < Song > fullListSong = new List < Song > ( ) ;
28
+ private List < Song > previewListSong = new List < Song > ( ) ;
29
+ private Song ? selectedSong ;
30
+ private bool isDownloading ;
25
31
public MidiRepository ( )
26
32
{
27
33
InitializeComponent ( ) ;
@@ -31,6 +37,7 @@ public MidiRepository()
31
37
DownloadPath . Text = BmpPigeonhole . Instance . MidiDownloadPath ;
32
38
DownloadProgressLabel . Visibility = Visibility . Hidden ;
33
39
DownloadProgressBar . Visibility = Visibility . Hidden ;
40
+ RefreshPlaylistSelector ( ) ;
34
41
}
35
42
private class Song
36
43
{
@@ -56,7 +63,8 @@ private async Task<string> FetchSongData()
56
63
/// <param name="html"></param>
57
64
private void RefreshSongList ( string html )
58
65
{
59
- listSong . Clear ( ) ;
66
+ fullListSong . Clear ( ) ;
67
+ previewListSong . Clear ( ) ;
60
68
HtmlDocument htmlDoc = new HtmlDocument ( ) ;
61
69
htmlDoc . LoadHtml ( html ) ;
62
70
@@ -70,7 +78,7 @@ private void RefreshSongList(string html)
70
78
71
79
if ( titleNode != null && authorNode != null && commentNode != null )
72
80
{
73
- listSong . Add ( new Song
81
+ fullListSong . Add ( new Song
74
82
{
75
83
Title = titleNode . GetAttributeValue ( "title" , "" ) ,
76
84
Author = authorNode . InnerText ,
@@ -94,11 +102,14 @@ private async void Button_Click(object sender, RoutedEventArgs e)
94
102
var songData = await FetchSongData ( ) ;
95
103
96
104
RefreshSongList ( songData ) ;
97
- MidiRepoContainer . ItemsSource = listSong . Select ( song => song . Title ) . ToList ( ) ;
105
+ previewListSong = fullListSong ;
106
+ MidiRepoContainer . ItemsSource = previewListSong . Select ( song => song . Title ) . ToList ( ) ;
107
+ RefreshCountTextBox ( ) ;
98
108
99
109
BtnGetSongList . IsEnabled = true ;
100
110
BtnGetSongList . Content = "Refresh" ;
101
111
LoadingProgressBar . Visibility = Visibility . Hidden ;
112
+ SongSearchTextBox . Text = "" ;
102
113
}
103
114
104
115
/// <summary>
@@ -108,10 +119,13 @@ private async void Button_Click(object sender, RoutedEventArgs e)
108
119
/// <param name="e"></param>
109
120
private void MidiRepoContainer_SelectionChanged ( object sender , SelectionChangedEventArgs e )
110
121
{
122
+ if ( MidiRepoContainer . SelectedIndex == - 1 )
123
+ return ;
124
+
111
125
DownloadPanel . Visibility = Visibility . Visible ;
112
- Song song = listSong [ MidiRepoContainer . SelectedIndex ] ;
113
- SongTitle . Text = $ "({ song . Author } ) { song . Title } ";
114
- SongComment . Text = song . Comment ;
126
+ selectedSong = previewListSong [ MidiRepoContainer . SelectedIndex ] ;
127
+ SongTitle . Text = $ "({ selectedSong . Author } ) { selectedSong . Title } ";
128
+ SongComment . Text = selectedSong . Comment ;
115
129
}
116
130
117
131
/// <summary>
@@ -145,6 +159,7 @@ private void SelectPath_Button_Click(object sender, RoutedEventArgs e)
145
159
/// <param name="fileName"></param>
146
160
private async void DownloadFile ( string url , string fileName )
147
161
{
162
+ isDownloading = true ;
148
163
HttpClient client = new HttpClient ( ) ;
149
164
HttpResponseMessage response = await client . GetAsync ( url , HttpCompletionOption . ResponseHeadersRead ) ;
150
165
long ? contentLength = response . Content . Headers . ContentLength ;
@@ -170,8 +185,18 @@ private async void DownloadFile(string url, string fileName)
170
185
string finalFilePath = $ "{ downloadsPath } /{ fileName } .mid";
171
186
172
187
File . Move ( tempFilePath , finalFilePath , true ) ;
173
- DownloadButton . IsEnabled = true ;
188
+ DownloadPanel . IsEnabled = true ;
174
189
DownloadProgressLabel . Visibility = Visibility . Visible ;
190
+ isDownloading = false ;
191
+
192
+ // Add to selected playlist
193
+ bool addToPlaylist = AddToPlaylistCheckBox . IsChecked ?? false ;
194
+
195
+ if ( addToPlaylist && PlaylistDropdown . SelectedIndex != - 1 )
196
+ {
197
+ var playlist = BmpCoffer . Instance . GetPlaylist ( PlaylistDropdown . SelectedItem as string ) ;
198
+ PlaylistFunctions . AddFileToPlaylist ( finalFilePath , playlist ) ;
199
+ }
175
200
}
176
201
177
202
/// <summary>
@@ -191,6 +216,7 @@ private void DownloadButtonClick(object sender, RoutedEventArgs e)
191
216
/// <param name="e"></param>
192
217
private void MidiRepoContainer_MouseDoubleClick ( object sender , MouseButtonEventArgs e )
193
218
{
219
+ selectedSong = previewListSong [ MidiRepoContainer . SelectedIndex ] ;
194
220
DownloadSelectedMidi ( ) ;
195
221
}
196
222
@@ -199,15 +225,114 @@ private void MidiRepoContainer_MouseDoubleClick(object sender, MouseButtonEventA
199
225
/// </summary>
200
226
private void DownloadSelectedMidi ( )
201
227
{
228
+ if ( isDownloading )
229
+ return ;
230
+
202
231
if ( ! Directory . Exists ( BmpPigeonhole . Instance . MidiDownloadPath ) )
203
232
{
204
233
MessageBox . Show ( "The downloads directory is not valid." , "Error" , MessageBoxButton . OK , MessageBoxImage . Error ) ;
205
234
return ;
206
235
}
207
- Song selectedSong = listSong [ MidiRepoContainer . SelectedIndex ] ;
208
- DownloadButton . IsEnabled = false ;
236
+
237
+ if ( selectedSong == null )
238
+ return ;
239
+
240
+ DownloadPanel . IsEnabled = false ;
209
241
DownloadProgressBar . Visibility = Visibility . Visible ;
210
242
DownloadProgressBar . Value = 0 ;
211
243
DownloadFile ( $ "{ midiRepoUrl } /{ selectedSong . Url } ", $ "({ selectedSong . Author } ) { selectedSong . Title } ") ;
212
244
}
245
+
246
+ /// <summary>
247
+ /// Refresh result count textblock
248
+ /// </summary>
249
+ private void RefreshCountTextBox ( )
250
+ {
251
+ ResultsCountTextBox . Text = $ "{ previewListSong . Count } Results";
252
+ }
253
+
254
+ #region Search Functions
255
+ /// <summary>
256
+ /// Filter the midi listview based on SongSearchTextBox
257
+ /// </summary>
258
+ private void SearchSong ( )
259
+ {
260
+ if ( fullListSong . Count == 0 )
261
+ return ;
262
+
263
+ var filteredList = new List < string > ( ) ;
264
+ if ( SongSearchTextBox . Text != "" )
265
+ {
266
+ previewListSong = fullListSong . FindAll ( s => s . Title . ToLower ( ) . Contains ( SongSearchTextBox . Text . ToLower ( ) ) ) ;
267
+ filteredList = previewListSong . Select ( s => s . Title ) . ToList ( ) ;
268
+ }
269
+ else
270
+ {
271
+ previewListSong = fullListSong ;
272
+ filteredList = previewListSong . Select ( s => s . Title ) . ToList ( ) ;
273
+ }
274
+
275
+ MidiRepoContainer . ItemsSource = filteredList ;
276
+ RefreshCountTextBox ( ) ;
277
+ }
278
+ /// <summary>
279
+ /// Filter song when textbox value changed
280
+ /// </summary>
281
+ /// <param name="sender"></param>
282
+ /// <param name="e"></param>
283
+ private void SongSearchTextBox_TextChanged ( object sender , TextChangedEventArgs e )
284
+ {
285
+ SearchSong ( ) ;
286
+ }
287
+ #endregion
288
+
289
+ #region Import To Playlist Functions
290
+ /// <summary>
291
+ /// Refresh playlist dropdown when click 'refresh' button
292
+ /// </summary>
293
+ /// <param name="sender"></param>
294
+ /// <param name="e"></param>
295
+ private void RefreshPlaylist_Click ( object sender , RoutedEventArgs e )
296
+ {
297
+ RefreshPlaylistSelector ( ) ;
298
+ }
299
+
300
+ /// <summary>
301
+ /// Refresh playlist dropdown
302
+ /// </summary>
303
+ private void RefreshPlaylistSelector ( )
304
+ {
305
+ PlaylistDropdown . DataContext = BmpCoffer . Instance . GetPlaylistNames ( ) ;
306
+ }
307
+
308
+ /// <summary>
309
+ /// Disable 'add to playlist' feature if checkbox is unchecked
310
+ /// </summary>
311
+ /// <param name="sender"></param>
312
+ /// <param name="e"></param>
313
+ private void AddToPlaylistCheckBox_Unchecked ( object sender , RoutedEventArgs e )
314
+ {
315
+ RefreshAddToPlaylistMode ( ) ;
316
+ }
317
+
318
+ /// <summary>
319
+ /// Enable 'add to playlist' feature if checkbox is checked
320
+ /// </summary>
321
+ /// <param name="sender"></param>
322
+ /// <param name="e"></param>
323
+ private void AddToPlaylistCheckBox_Checked ( object sender , RoutedEventArgs e )
324
+ {
325
+ RefreshAddToPlaylistMode ( ) ;
326
+ }
327
+
328
+ /// <summary>
329
+ /// Hide and show playlist selector while check/uncheck 'add to playlist' checkbox
330
+ /// </summary>
331
+ private void RefreshAddToPlaylistMode ( )
332
+ {
333
+ bool isChecked = AddToPlaylistCheckBox . IsChecked ?? false ;
334
+ PlaylistDropdown . Visibility = isChecked ? Visibility . Visible : Visibility . Hidden ;
335
+ RefreshPlaylistButton . Visibility = isChecked ? Visibility . Visible : Visibility . Hidden ;
336
+ }
337
+ #endregion
213
338
}
0 commit comments