diff --git a/WeatubeDL/MainWindow.xaml b/WeatubeDL/MainWindow.xaml
index 424dc70..161cc1c 100644
--- a/WeatubeDL/MainWindow.xaml
+++ b/WeatubeDL/MainWindow.xaml
@@ -7,28 +7,81 @@
mc:Ignorable="d"
Title="Weatube DL" Height="450" Width="810">
-
-
+
+
-
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
+
+
+
-
-
+
-
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WeatubeDL/MainWindow.xaml.cs b/WeatubeDL/MainWindow.xaml.cs
index 1d28785..a1a901e 100644
--- a/WeatubeDL/MainWindow.xaml.cs
+++ b/WeatubeDL/MainWindow.xaml.cs
@@ -19,12 +19,13 @@ using System.Windows.Media.Animation;
namespace WeatubeDL
{
public partial class MainWindow : Window
- {
- private YoutubeVideo[] videos;
+ {
+ private Dictionary AddedVids;
private YoutubeVideo current;
public MainWindow()
{
InitializeComponent();
+ AddedVids = new Dictionary();
}
private async void Link_TextChanged(object sender, TextChangedEventArgs e)
@@ -43,7 +44,7 @@ namespace WeatubeDL
return;
}
var text = (sender as TextBox).Text;
- if (current != null && current.id == YoutubeVideo.IdFromUrl(text))
+ if (current != null && current.Id == YoutubeVideo.IdFromUrl(text))
{
EnableSuggestion();
return;
@@ -52,28 +53,76 @@ namespace WeatubeDL
if (await vid.Exists())
{
current = vid;
- while (current.name == null) await Task.Delay(500);
+ while (current.Name == null) await Task.Delay(500);
EnableSuggestion();
}
else DisableSuggestion();
}
+ protected override void OnClosed(EventArgs e)
+ {
+ base.OnClosed(e);
+ Application.Current.Shutdown();
+ }
+
+ private void AddLink_Click(object sender, RoutedEventArgs e)
+ {
+ if (current == null) return;
+ DockPanel _s = new DockPanel
+ {
+ Tag = AddedVids.Count,
+ Style = (Style)FindResource("VideoPanel")
+ };
+ _s.Children.Add(new Image
+ {
+ Source = current.Image,
+ Style = (Style)FindResource("VideoImage")
+ });
+ _s.Children.Add(new TextBlock
+ {
+ Text = current.Name,
+ VerticalAlignment = VerticalAlignment.Center,
+ Style = (Style)FindResource("VideoText")
+ });
+ var button = new Button
+ {
+ Style = (Style)FindResource("VideoButtonClose")
+ };
+ button.Click += new RoutedEventHandler(CloseButtonClick);
+ _s.Children.Add(button);
+ VideosPanel.Children.Add(_s);
+ ShowPanel(_s);
+ AddedVids.Add(_s, current);
+ Link.Text = "";
+ current = null;
+ }
+
+ private async void CloseButtonClick(object sender, RoutedEventArgs e)
+ {
+ var p = (sender as Button).Parent;
+ HidePanel((DockPanel)p);
+ while ((p as DockPanel).Margin.Left != -((p as DockPanel).Width*2)) await Task.Delay(100);
+ AddedVids.Remove((DockPanel)p);
+ VideosPanel.Children.Remove((DockPanel)p);
+ }
+
+ #region WPF animations
public void EnableSuggestion()
{
AddLink.IsEnabled = true;
- if (SuggestedVideo.Margin.Top < 0)
+ if (SuggestedVideo.Margin.Top == 0)
{
Storyboard sb = Resources["ShowSuggested"] as Storyboard;
sb.Begin(SuggestedVideo);
}
- SuggestedItem.Text = current.name;
- SuggestedImage.Source = current.image;
+ SuggestedItem.Text = current.Name;
+ SuggestedImage.Source = current.Image;
}
public void DisableSuggestion()
{
AddLink.IsEnabled = false;
- if (SuggestedVideo.Margin.Top == 0)
+ if (SuggestedVideo.Margin.Top > 0)
{
Storyboard sb = Resources["HideSuggested"] as Storyboard;
sb.Begin(SuggestedVideo);
@@ -81,10 +130,18 @@ namespace WeatubeDL
SuggestedItem.Text = null;
SuggestedImage.Source = null;
}
- protected override void OnClosed(EventArgs e)
+
+ public void ShowPanel(DockPanel panel)
{
- base.OnClosed(e);
- Application.Current.Shutdown();
+ Storyboard sb = Resources["ShowPanel"] as Storyboard;
+ sb.Begin(panel);
}
+
+ public void HidePanel(DockPanel panel)
+ {
+ Storyboard sb = Resources["HidePanel"] as Storyboard;
+ sb.Begin(panel);
+ }
+ #endregion
}
}
diff --git a/WeatubeDL/Properties/YoutubeVideo.cs b/WeatubeDL/Properties/YoutubeVideo.cs
index 88e25d2..ae13248 100644
--- a/WeatubeDL/Properties/YoutubeVideo.cs
+++ b/WeatubeDL/Properties/YoutubeVideo.cs
@@ -14,73 +14,97 @@ namespace WeatubeDL
{
class YoutubeVideo
{
- public string src { get; private set; }
- public string id { get; private set; }
- public string[] types { get; private set; }
- public string imagePath { get; private set; }
- public BitmapImage image { get; private set; }
- public string name { get; private set; }
+ public string Src { get; private set; } // original link provided by user
+ public string Id { get; private set; } // YouTube video id
+ public string[] Types { get; private set; } // All download types available
+ public string ImagePath { get; private set; } // Path to image stored in user's temp folder
+ public BitmapImage Image { get; private set; } // YouTube video preview image
+ public string Name { get; private set; } // YouTube video name
private WebClient client;
+
+ ///
+ /// Creates YouTube video object
+ ///
public YoutubeVideo(string src)
{
- this.src = src;
- DownloadPreview();
+ this.Src = src;
+ DownloadPreview();
}
+
+ ///
+ /// Destroys YouTube video object
+ ///
~YoutubeVideo()
{
- if (File.Exists(imagePath)) File.Delete(imagePath);
+ if (File.Exists(ImagePath)) File.Delete(ImagePath);
if (client != null) client.Dispose();
}
+ ///
+ /// Takes video id from given url
+ ///
+ /// YouTube video Id string / null
public static string IdFromUrl(string src)
{
if (src.Contains("youtu.be/"))
return src.Replace("/youtu.be/", "").Split('/')[1].Split('&')[0];
else if (src.Contains("youtube.com/watch?v=") && src.Contains("&"))
return src.Split('=')[1].Split('&')[0];
- return " ";
+ return null;
}
+ ///
+ /// Downloads YouTube video preview image
+ ///
private void DownloadPreview()
{
- id = IdFromUrl(src);
- if (id == null || id == " ") return;
+ Id = IdFromUrl(Src);
+ if (Id == null) return;
client = new WebClient();
client.Headers.Add("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0)");
client.DownloadFileCompleted += new AsyncCompletedEventHandler(Completed);
- imagePath = Path.GetTempPath() + "WeatubeDL/" + id + ".png";
+ ImagePath = Path.GetTempPath() + "WeatubeDL/" + Id + ".png"; //path to /%LOCALAPPDATA%/Temp/WeatubeDL/image.png
Directory.CreateDirectory(Path.GetTempPath() + "WeatubeDL");
- client.DownloadFileAsync(new Uri("http://img.youtube.com/vi/" + id + "/mqdefault.jpg"), imagePath);
+ client.DownloadFileAsync(new Uri("http://img.youtube.com/vi/" + Id + "/mqdefault.jpg"), ImagePath);
}
+ ///
+ /// Disposes WebClient when download is complete
+ ///
static void Completed(object sender, AsyncCompletedEventArgs e)
{
(sender as WebClient).Dispose();
}
+
+ ///
+ /// Checks if given video exists on YouTube
+ ///
+ /// true = video exists ; false = video does not exist
public async Task Exists()
{
- if (id == null || client == null) return false;
- while(client.IsBusy)
- {
- await Task.Delay(100);
- }
- if (id.Length > 2 && File.Exists(imagePath) && new FileInfo(imagePath).Length > 0)
- {
- image = new BitmapImage();
-
- using (var stream = File.OpenRead(imagePath))
+ if (Id == null) return false;
+ if (client != null)
+ while(client.IsBusy) //wait until preview is downloaded
{
- image.BeginInit();
- image.CacheOption = BitmapCacheOption.OnLoad;
- image.StreamSource = stream;
- image.EndInit();
+ await Task.Delay(100);
+ }
+ if (File.Exists(ImagePath) && new FileInfo(ImagePath).Length > 0) //checks whether preview is downloaded or not
+ {
+ Image = new BitmapImage();
+
+ using (var stream = File.OpenRead(ImagePath)) //load image
+ {
+ Image.BeginInit();
+ Image.CacheOption = BitmapCacheOption.OnLoad;
+ Image.StreamSource = stream;
+ Image.EndInit();
}
- if (image.Width == 120)
+ if (Image.Width == 120) //if video not found, mqdefault.png would be 120px wide instead of default 320px
{
- File.Delete(imagePath);
+ File.Delete(ImagePath);
return false;
}
GetVideoName();
@@ -89,19 +113,24 @@ namespace WeatubeDL
return false;
}
- // TODO: После того как прога понимает, что видос существует, она должна подтягивать его форматы
+ ///
+ /// Downloads webpage from url given by user
+ ///
private void GetVideoName()
{
client = new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
- client.DownloadStringAsync(new Uri(src));
+ client.DownloadStringAsync(new Uri(Src));
}
+ ///
+ /// Gets YouTube video name from webpage title when page is loaded
+ ///
void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
- name = Regex.Match(e.Result, @"\]*\>\s*(?[\s\S]*?)\",
+ Name = Regex.Match(e.Result, @"\]*\>\s*(?[\s\S]*?)\",
RegexOptions.IgnoreCase).Groups["Title"].Value;
- name = name.Remove(name.Length - 10);
+ Name = Name.Remove(Name.Length - 10);
(sender as WebClient).Dispose();
}