@@ -17,17 +17,22 @@ public partial class MainViewModel : ObservableRecipient
17
17
18
18
private AppSettings _appSettings ;
19
19
private MainService _mainService ;
20
+ private YouTubeDataService _youtubeDataService ;
20
21
private List < VideoInfo > _videoInfoList ;
21
22
22
23
public MainViewModel ( string dbFilePath )
23
24
{
24
25
_appSettings = new AppSettings ( ) ;
25
26
_mainService = new MainService ( dbFilePath ) ;
27
+ // Note: if this key doesn't work (e.g. expired), get your key at:
28
+ // https://console.cloud.google.com/apis/api/youtube.googleapis.com/overview
29
+ string youtubeDataApiKey = "AIzaSyCUV6j6vCUTD9W2aiTOV-6XkV0Yl8tjFiA" ;
30
+ _youtubeDataService = new YouTubeDataService ( youtubeDataApiKey ) ;
26
31
_videoInfoList = new List < VideoInfo > ( ) ;
27
32
InitializeWebView2 ( ) ;
28
33
29
34
Version ver = Environment . Version ;
30
- AppTitle = $ "{ App . AppName } - by Peter Sun (.NET { ver . Major } .{ ver . Minor } .{ ver . Build } Runtime , WPF WebView2, CommunityToolkit.Mvvm, " +
35
+ AppTitle = $ "{ App . AppName } - by Peter Sun (.NET { ver . Major } .{ ver . Minor } .{ ver . Build } runtime , WPF WebView2, CommunityToolkit.Mvvm, " +
31
36
"EntityFrameworkCore.Sqlite, ModernWpfUI, RestoreWindowPlace)" ;
32
37
#if DEBUG
33
38
AppTitle += " - Debug" ;
@@ -39,7 +44,7 @@ public MainViewModel(string dbFilePath)
39
44
public WebView2 ? WebView2Control { get ; private set ; }
40
45
// Video address in the textbox (whenever navigated to)
41
46
[ ObservableProperty ]
42
- string _currentVideoUri = string . Empty ;
47
+ string _currentVideoUrl = string . Empty ;
43
48
[ ObservableProperty ]
44
49
ObservableCollection < string > _videoGroupList = new ObservableCollection < string > ( ) ;
45
50
[ ObservableProperty ]
@@ -167,18 +172,18 @@ partial void OnSelectedVideoInfoChanged(VideoInfo? value)
167
172
{
168
173
// Link is like https://www.youtube.com/watch?v=d_l-st8Q1S0,
169
174
// https://www.youtube.com/results?search_query=....."
170
- _currentVideoUri = value . Link ;
175
+ _currentVideoUrl = value . Link ;
171
176
}
172
177
else
173
- {
174
- _currentVideoUri = VideoInfo . YouTubeHomeUri ;
178
+ {
179
+ _currentVideoUrl = VideoInfo . YouTubeHomeUri ;
175
180
}
176
181
177
182
// YouTube tab (go to the last navigated video uri)
178
- BindWebView2Control ( _currentVideoUri ) ;
179
- OnPropertyChanged ( nameof ( CurrentVideoUri ) ) ;
183
+ BindWebView2Control ( _currentVideoUrl ) ;
184
+ OnPropertyChanged ( nameof ( CurrentVideoUrl ) ) ;
180
185
181
- _mainService . UpdateAppSetting ( AppSettings . SelectedVideoLinkName , _currentVideoUri ) ;
186
+ _mainService . UpdateAppSetting ( AppSettings . SelectedVideoLinkName , _currentVideoUrl ) ;
182
187
183
188
if ( value . Description . IsNotBlank ( ) )
184
189
{
@@ -200,7 +205,7 @@ private void GoToVideoUrl()
200
205
{
201
206
try
202
207
{
203
- BindWebView2Control ( CurrentVideoUri ) ;
208
+ BindWebView2Control ( CurrentVideoUrl ) ;
204
209
}
205
210
catch ( Exception ex )
206
211
{
@@ -209,32 +214,24 @@ private void GoToVideoUrl()
209
214
}
210
215
211
216
[ RelayCommand ]
212
- private void ImportCurrentVideo ( )
217
+ private async void ImportCurrentVideo ( )
213
218
{
214
- if ( ! GeneralHelper . IsValidUri ( _currentVideoUri ) )
219
+ if ( ! GeneralHelper . IsValidUri ( _currentVideoUrl ) )
215
220
{
216
221
StatusMessage = "A video needs to be navigated to for 'Import'" ;
217
222
return ;
218
223
}
219
224
220
- if ( ! GeneralHelper . IsYouTubeVideoUri ( _currentVideoUri ) )
225
+ if ( ! GeneralHelper . IsYouTubeVideoUri ( _currentVideoUrl ) )
221
226
{
222
227
StatusMessage = "Must be a YouTube video to be imported" ;
223
228
return ;
224
229
}
225
230
226
231
try
227
232
{
228
- GeneralHelper . CleanYouTubeUri ( ref _currentVideoUri ) ;
229
- var videoInfo = new VideoInfo
230
- {
231
- // With YouTubeVideoUri, from https://www.youtube.com/watch?v=d_l-st8Q1S0,
232
- // make https://img.youtube.com/vi/d_l-st8Q1S0/0.jpg
233
- CoverUrl = _currentVideoUri . Replace ( "www.youtube" , "img.youtube" )
234
- . Replace ( "watch?v=" , "vi/" ) + "/0.jpg" ,
235
- Link = _currentVideoUri ,
236
- } ;
237
-
233
+ GeneralHelper . CleanYouTubeUri ( ref _currentVideoUrl ) ;
234
+ VideoInfo videoInfo = await _youtubeDataService . CreateYouTubeVideoMatch ( _currentVideoUrl ) ;
238
235
_mainService . ImportVideo ( _videoInfoList , _selectedVideoGroup , ref videoInfo ,
239
236
out bool isNewVideo , out string statusMessage ) ;
240
237
if ( isNewVideo )
@@ -262,9 +259,9 @@ private async void OpenAtYouTubeWebSite()
262
259
{
263
260
try
264
261
{
265
- if ( _currentVideoUri . IsNotBlank ( ) && GeneralHelper . IsValidUri ( _currentVideoUri ) )
262
+ if ( _currentVideoUrl . IsNotBlank ( ) && GeneralHelper . IsValidUri ( _currentVideoUrl ) )
266
263
{
267
- await GeneralHelper . ExecuteOpenUrlCommandAsync ( _currentVideoUri ) ;
264
+ await GeneralHelper . ExecuteOpenUrlCommandAsync ( _currentVideoUrl ) ;
268
265
}
269
266
else
270
267
{
@@ -289,15 +286,15 @@ private void InitializeWebView2()
289
286
{
290
287
// Always update the textbox (so can copy to clipboard)
291
288
// not the same as YouTube behavior (only update at the top)
292
- CurrentVideoUri = WebView2Control . Source . AbsoluteUri ;
289
+ CurrentVideoUrl = WebView2Control . Source . AbsoluteUri ;
293
290
} ;
294
291
OnPropertyChanged ( nameof ( WebView2Control ) ) ;
295
292
}
296
293
297
294
// Ensure to avoid empty YouTube control
298
295
private VideoInfo EnsureInitialVideoInfo ( List < VideoInfo > videoInfoList , string selectedVideoLink )
299
296
{
300
- VideoInfo ? initialVideoInfo = null ;
297
+ VideoInfo ? initialVideoInfo = null ;
301
298
if ( selectedVideoLink . IsNotBlank ( ) )
302
299
{
303
300
initialVideoInfo = videoInfoList . FirstOrDefault ( x => x . Link == selectedVideoLink ) ;
@@ -311,20 +308,20 @@ private VideoInfo EnsureInitialVideoInfo(List<VideoInfo> videoInfoList, string s
311
308
else
312
309
{
313
310
// Create defaults on empty. Videos imported by a user (from UI) will be from YouTube.
314
- _currentVideoUri = "https://github.com/psun247/ShazamDesk" ;
311
+ _currentVideoUrl = "https://github.com/psun247/ShazamDesk" ;
315
312
initialVideoInfo = new VideoInfo
316
313
{
317
314
Description = "WPF ChatGPT + Shazam by Peter Sun" ,
318
315
CoverUrl = "/CSharpWpfYouTube;component/Resources/Info.png" ,
319
- Link = _currentVideoUri ,
316
+ Link = _currentVideoUrl ,
320
317
} ;
321
318
_mainService . ImportVideo ( _videoInfoList , VideoInfo . HomeVideoGroup , ref initialVideoInfo ,
322
319
out bool _ , out string _ ) ;
323
320
var videoInfo = new VideoInfo
324
321
{
325
- Description = "French Open Novak Djokovic vs Carlos Alcaraz " ,
326
- CoverUrl = "https://img.youtube.com/vi/K6VuFCwUMnQ /0.jpg" ,
327
- Link = "https://www.youtube.com/watch?v=K6VuFCwUMnQ " ,
322
+ Description = "Jannik Sinner v Daniil Medvedev Extended Highlights | Australian Open 2024 Final " ,
323
+ CoverUrl = "https://img.youtube.com/vi/b90INDbXX7Y /0.jpg" ,
324
+ Link = "https://www.youtube.com/watch?v=b90INDbXX7Y " ,
328
325
} ;
329
326
_mainService . ImportVideo ( _videoInfoList , VideoInfo . HomeVideoGroup , ref videoInfo ,
330
327
out bool _ , out string _ ) ;
0 commit comments