PageRenderTime 36ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

/JMMClient/JMMClient/UserControls/ContinueWatchingTileControl.xaml.cs

https://bitbucket.org/gibwar/jmm-test
C# | 853 lines | 672 code | 166 blank | 15 comment | 93 complexity | 16ba217a76ac6d1ed964cb478cd7da0b MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Windows;
  6. using System.Windows.Controls;
  7. using System.Windows.Data;
  8. using System.Windows.Documents;
  9. using System.Windows.Input;
  10. using System.Windows.Media;
  11. using System.Windows.Media.Imaging;
  12. using System.Windows.Navigation;
  13. //using System.Windows.Shapes;
  14. using System.Collections.ObjectModel;
  15. using System.ComponentModel;
  16. using JMMClient.Forms;
  17. using JMMClient.ViewModel;
  18. using System.IO;
  19. using JMMClient.ImageDownload;
  20. using NLog;
  21. using System.Net;
  22. using System.Diagnostics;
  23. namespace JMMClient.UserControls
  24. {
  25. /// <summary>
  26. /// Interaction logic for ContinueWatchingTileControl.xaml
  27. /// </summary>
  28. public partial class ContinueWatchingTileControl : UserControl
  29. {
  30. private static Logger logger = LogManager.GetCurrentClassLogger();
  31. private BlockingList<object> imagesToDownload = new BlockingList<object>();
  32. private BackgroundWorker workerImages = new BackgroundWorker();
  33. public ObservableCollection<AnimeEpisodeVM> UnwatchedEpisodes { get; set; }
  34. public ICollectionView ViewUnwatchedEpisodes { get; set; }
  35. public ObservableCollection<RecommendationTile> Recommendations { get; set; }
  36. public ObservableCollection<object> Shouts { get; set; }
  37. BackgroundWorker episodesWorker = new BackgroundWorker();
  38. BackgroundWorker recsWorker = new BackgroundWorker();
  39. BackgroundWorker shoutsWorker = new BackgroundWorker();
  40. BackgroundWorker postShoutWorker = new BackgroundWorker();
  41. BackgroundWorker refreshShoutsRecsWorker = new BackgroundWorker();
  42. public static readonly DependencyProperty UnwatchedEpisodeCountProperty = DependencyProperty.Register("UnwatchedEpisodeCount",
  43. typeof(int), typeof(ContinueWatchingTileControl), new UIPropertyMetadata(0, null));
  44. public int UnwatchedEpisodeCount
  45. {
  46. get { return (int)GetValue(UnwatchedEpisodeCountProperty); }
  47. set { SetValue(UnwatchedEpisodeCountProperty, value); }
  48. }
  49. public static readonly DependencyProperty PosterWidthProperty = DependencyProperty.Register("PosterWidth",
  50. typeof(double), typeof(ContinueWatchingTileControl), new UIPropertyMetadata((double)180, null));
  51. public double PosterWidth
  52. {
  53. get { return (double)GetValue(PosterWidthProperty); }
  54. set { SetValue(PosterWidthProperty, value); }
  55. }
  56. public static readonly DependencyProperty IsLoadingShoutsProperty = DependencyProperty.Register("IsLoadingShouts",
  57. typeof(bool), typeof(ContinueWatchingTileControl), new UIPropertyMetadata(false, null));
  58. public bool IsLoadingShouts
  59. {
  60. get { return (bool)GetValue(IsLoadingShoutsProperty); }
  61. set
  62. {
  63. SetValue(IsLoadingShoutsProperty, value);
  64. IsNotLoadingShouts = !value;
  65. }
  66. }
  67. public static readonly DependencyProperty IsNotLoadingShoutsProperty = DependencyProperty.Register("IsNotLoadingShouts",
  68. typeof(bool), typeof(ContinueWatchingTileControl), new UIPropertyMetadata(false, null));
  69. public bool IsNotLoadingShouts
  70. {
  71. get { return (bool)GetValue(IsNotLoadingShoutsProperty); }
  72. set { SetValue(IsNotLoadingShoutsProperty, value); }
  73. }
  74. public ContinueWatchingTileControl()
  75. {
  76. InitializeComponent();
  77. UnwatchedEpisodes = new ObservableCollection<AnimeEpisodeVM>();
  78. ViewUnwatchedEpisodes = CollectionViewSource.GetDefaultView(UnwatchedEpisodes);
  79. Recommendations = new ObservableCollection<RecommendationTile>();
  80. Shouts = new ObservableCollection<object>();
  81. this.DataContextChanged += new DependencyPropertyChangedEventHandler(ContinueWatchingTileControl_DataContextChanged);
  82. btnBack.Click += new RoutedEventHandler(btnBack_Click);
  83. btnPlayNextEp.Click += new RoutedEventHandler(btnPlayNextEp_Click);
  84. btnPlayAllEps.Click += new RoutedEventHandler(btnPlayAllEps_Click);
  85. episodesWorker.DoWork += new DoWorkEventHandler(episodesWorker_DoWork);
  86. episodesWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(episodesWorker_RunWorkerCompleted);
  87. recsWorker.DoWork += new DoWorkEventHandler(recsWorker_DoWork);
  88. recsWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(recsWorker_RunWorkerCompleted);
  89. shoutsWorker.DoWork += new DoWorkEventHandler(shoutsWorker_DoWork);
  90. shoutsWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(shoutsWorker_RunWorkerCompleted);
  91. refreshShoutsRecsWorker.DoWork += new DoWorkEventHandler(refreshShoutsRecsWorker_DoWork);
  92. refreshShoutsRecsWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(refreshShoutsRecsWorker_RunWorkerCompleted);
  93. MainWindow.videoHandler.VideoWatchedEvent += new Utilities.VideoHandler.VideoWatchedEventHandler(videoHandler_VideoWatchedEvent);
  94. workerImages.DoWork += new DoWorkEventHandler(workerImages_DoWork);
  95. workerImages.RunWorkerAsync();
  96. txtShoutNew.GotFocus += new RoutedEventHandler(txtShoutNew_GotFocus);
  97. txtShoutNew.LostFocus += new RoutedEventHandler(txtShoutNew_LostFocus);
  98. btnSubmitShout.Click += new RoutedEventHandler(btnSubmitShout_Click);
  99. btnRefreshShouts.Click += new RoutedEventHandler(btnRefreshShouts_Click);
  100. postShoutWorker.DoWork += new DoWorkEventHandler(postShoutWorker_DoWork);
  101. postShoutWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(postShoutWorker_RunWorkerCompleted);
  102. cRating.OnRatingValueChangedEvent += new RatingControl.RatingValueChangedHandler(cRating_OnRatingValueChangedEvent);
  103. grdMain.PreviewMouseWheel += new MouseWheelEventHandler(grdMain_PreviewMouseWheel);
  104. lbEpisodes.PreviewMouseWheel += new MouseWheelEventHandler(lbEpisodes_PreviewMouseWheel);
  105. lbShouts.PreviewMouseWheel += new MouseWheelEventHandler(lbShouts_PreviewMouseWheel);
  106. }
  107. void lbShouts_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
  108. {
  109. try
  110. {
  111. ScrollerCWatching.ScrollToVerticalOffset(ScrollerCWatching.VerticalOffset - e.Delta / 3);
  112. }
  113. catch { }
  114. }
  115. void lbEpisodes_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
  116. {
  117. try
  118. {
  119. ScrollerCWatching.ScrollToVerticalOffset(ScrollerCWatching.VerticalOffset - e.Delta / 3);
  120. }
  121. catch { }
  122. }
  123. void grdMain_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
  124. {
  125. try
  126. {
  127. ScrollerCWatching.ScrollToVerticalOffset(ScrollerCWatching.VerticalOffset - e.Delta / 3);
  128. }
  129. catch { }
  130. }
  131. void cRating_OnRatingValueChangedEvent(RatingValueEventArgs ev)
  132. {
  133. AnimeSeriesVM ser = this.DataContext as AnimeSeriesVM;
  134. if (ser == null) return;
  135. try
  136. {
  137. decimal rating = (decimal)ev.RatingValue;
  138. int voteType = 1;
  139. if (ser.AniDB_Anime.FinishedAiring) voteType = 2;
  140. JMMServerVM.Instance.VoteAnime(ser.AniDB_ID, rating, voteType);
  141. // refresh the data
  142. MainListHelperVM.Instance.UpdateHeirarchy(ser);
  143. }
  144. catch (Exception ex)
  145. {
  146. Utils.ShowErrorMessage(ex);
  147. }
  148. }
  149. void postShoutWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  150. {
  151. string msg = e.Result.ToString();
  152. this.Cursor = Cursors.Arrow;
  153. MessageBox.Show(msg, "Message", MessageBoxButton.OK, MessageBoxImage.Information);
  154. txtShoutNew.Text = "";
  155. AnimeSeriesVM ser = this.DataContext as AnimeSeriesVM;
  156. if (ser == null) return;
  157. shoutsWorker.RunWorkerAsync(ser);
  158. }
  159. void postShoutWorker_DoWork(object sender, DoWorkEventArgs e)
  160. {
  161. Trakt_ShoutPost shout = e.Argument as Trakt_ShoutPost;
  162. string msg = "";
  163. try
  164. {
  165. JMMServerVM.Instance.clientBinaryHTTP.PostShoutShow(shout.AnimeID, shout.ShoutText, shout.Spoiler, ref msg);
  166. }
  167. catch (Exception ex)
  168. {
  169. e.Result = ex.Message;
  170. return;
  171. }
  172. e.Result = msg;
  173. }
  174. void btnSubmitShout_Click(object sender, RoutedEventArgs e)
  175. {
  176. AnimeSeriesVM animeSeries = (AnimeSeriesVM)this.DataContext;
  177. if (animeSeries == null)
  178. {
  179. Utils.ShowErrorMessage("Anime series info not found");
  180. txtShoutNew.Focus();
  181. return;
  182. }
  183. string shoutText = txtShoutNew.Text.Trim();
  184. if (string.IsNullOrEmpty(shoutText))
  185. {
  186. Utils.ShowErrorMessage("Please enter text for your shout");
  187. txtShoutNew.Focus();
  188. return;
  189. }
  190. if (shoutText.Length > 2000)
  191. {
  192. Utils.ShowErrorMessage(string.Format("Shout text must be less than 2000 characters ({0})", shoutText.Length));
  193. txtShoutNew.Focus();
  194. return;
  195. }
  196. btnSubmitShout.IsEnabled = false;
  197. this.Cursor = Cursors.Wait;
  198. Trakt_ShoutPost shout = new Trakt_ShoutPost();
  199. shout.AnimeID = animeSeries.AniDB_ID;
  200. shout.ShoutText = shoutText;
  201. shout.Spoiler = chkSpoiler.IsChecked.Value;
  202. postShoutWorker.RunWorkerAsync(shout);
  203. }
  204. void btnRefreshShouts_Click(object sender, RoutedEventArgs e)
  205. {
  206. AnimeSeriesVM animeSeries = (AnimeSeriesVM)this.DataContext;
  207. if (animeSeries == null) return;
  208. IsLoadingShouts = true;
  209. refreshShoutsRecsWorker.RunWorkerAsync(animeSeries);
  210. }
  211. void refreshShoutsRecsWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  212. {
  213. AnimeSeriesVM animeSeries = (AnimeSeriesVM)this.DataContext;
  214. if (animeSeries == null) return;
  215. shoutsWorker.RunWorkerAsync(animeSeries);
  216. }
  217. void refreshShoutsRecsWorker_DoWork(object sender, DoWorkEventArgs e)
  218. {
  219. try
  220. {
  221. AnimeSeriesVM ser = e.Argument as AnimeSeriesVM;
  222. JMMServerVM.Instance.clientBinaryHTTP.UpdateAnimeData(ser.AniDB_ID);
  223. // refresh the data
  224. MainListHelperVM.Instance.UpdateHeirarchy(ser);
  225. }
  226. catch (Exception ex)
  227. {
  228. logger.ErrorException(ex.ToString(), ex);
  229. }
  230. finally
  231. {
  232. }
  233. }
  234. void txtShoutNew_LostFocus(object sender, RoutedEventArgs e)
  235. {
  236. txtShoutNew.Height = 30;
  237. txtShoutNew.Foreground = Brushes.DarkGray;
  238. if (txtShoutNew.Text.Trim().Length == 0)
  239. txtShoutNew.Text = "Have Your Say...";
  240. }
  241. void txtShoutNew_GotFocus(object sender, RoutedEventArgs e)
  242. {
  243. if (txtShoutNew.Text.Equals("Have Your Say...", StringComparison.InvariantCultureIgnoreCase))
  244. txtShoutNew.Text = "";
  245. txtShoutNew.Foreground = Brushes.Black;
  246. txtShoutNew.Height = 150;
  247. }
  248. void workerImages_DoWork(object sender, DoWorkEventArgs e)
  249. {
  250. ProcessImages();
  251. }
  252. private void ProcessImages()
  253. {
  254. foreach (object req in imagesToDownload)
  255. {
  256. try
  257. {
  258. if (req.GetType() == typeof(Trakt_ShoutUserVM))
  259. {
  260. Trakt_ShoutUserVM tile = req as Trakt_ShoutUserVM;
  261. //user
  262. Uri uriUser = new Uri(tile.UserOnlineImagePath);
  263. string filenameUser = Path.GetFileName(uriUser.LocalPath);
  264. string tempNameUser = Path.Combine(Path.GetTempPath(), filenameUser);
  265. using (WebClient client = new WebClient())
  266. {
  267. client.Headers.Add("user-agent", "JMM");
  268. if (!File.Exists(tempNameUser))
  269. {
  270. if (tile.UserOnlineImagePath.Length > 0)
  271. client.DownloadFile(tile.UserOnlineImagePath, tempNameUser);
  272. }
  273. if (File.Exists(tempNameUser)) tile.DelayedUserImage = tempNameUser;
  274. }
  275. }
  276. if (req.GetType() == typeof(AniDB_RecommendationVM))
  277. {
  278. AniDB_RecommendationVM tile = req as AniDB_RecommendationVM;
  279. // unfortunately AniDB doesn't have any user images yet
  280. // we will use a placeholder
  281. tile.DelayedUserImage = tile.UserImagePathForDisplay;
  282. }
  283. imagesToDownload.Remove(req);
  284. }
  285. catch (Exception ex)
  286. {
  287. imagesToDownload.Remove(req);
  288. logger.ErrorException(ex.ToString(), ex);
  289. }
  290. }
  291. }
  292. void videoHandler_VideoWatchedEvent(Utilities.VideoWatchedEventArgs ev)
  293. {
  294. try
  295. {
  296. MainWindow mainwdw = (MainWindow)Window.GetWindow(this);
  297. if (MainWindow.CurrentMainTabIndex == MainWindow.TAB_MAIN_Dashboard && mainwdw.tileContinueWatching.Visibility == System.Windows.Visibility.Visible)
  298. RefreshData();
  299. }
  300. catch { }
  301. }
  302. void btnPlayAllEps_Click(object sender, RoutedEventArgs e)
  303. {
  304. try
  305. {
  306. AnimeSeriesVM ser = this.DataContext as AnimeSeriesVM;
  307. if (ser == null) return;
  308. MainWindow.videoHandler.PlayAllUnwatchedEpisodes(ser.AnimeSeriesID.Value);
  309. }
  310. catch (Exception ex)
  311. {
  312. Utils.ShowErrorMessage(ex);
  313. }
  314. }
  315. void btnPlayNextEp_Click(object sender, RoutedEventArgs e)
  316. {
  317. if (UnwatchedEpisodes.Count == 0) return;
  318. try
  319. {
  320. AnimeEpisodeVM ep = UnwatchedEpisodes[0];
  321. if (ep.FilesForEpisode.Count == 1)
  322. MainWindow.videoHandler.PlayVideo(ep.FilesForEpisode[0]);
  323. else if (ep.FilesForEpisode.Count > 1)
  324. {
  325. if (AppSettings.AutoFileSingleEpisode)
  326. {
  327. VideoDetailedVM vid = MainWindow.videoHandler.GetAutoFileForEpisode(ep);
  328. if (vid != null)
  329. MainWindow.videoHandler.PlayVideo(vid);
  330. }
  331. else
  332. {
  333. MainWindow mainwdw = (MainWindow)Window.GetWindow(this);
  334. PlayVideosForEpisodeForm frm = new PlayVideosForEpisodeForm();
  335. frm.Owner = mainwdw;
  336. frm.Init(ep);
  337. bool? result = frm.ShowDialog();
  338. }
  339. }
  340. }
  341. catch (Exception ex)
  342. {
  343. Utils.ShowErrorMessage(ex);
  344. }
  345. }
  346. void episodesWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  347. {
  348. AnimeSeriesVM ser = this.DataContext as AnimeSeriesVM;
  349. if (ser == null) return;
  350. if (!recsWorker.IsBusy)
  351. recsWorker.RunWorkerAsync(ser);
  352. }
  353. void episodesWorker_DoWork(object sender, DoWorkEventArgs e)
  354. {
  355. try
  356. {
  357. AnimeSeriesVM ser = e.Argument as AnimeSeriesVM;
  358. List<JMMServerBinary.Contract_AnimeEpisode> rawEps = JMMServerVM.Instance.clientBinaryHTTP.GetAllUnwatchedEpisodes(ser.AnimeSeriesID.Value,
  359. JMMServerVM.Instance.CurrentUser.JMMUserID.Value);
  360. int i = 0;
  361. foreach (JMMServerBinary.Contract_AnimeEpisode raw in rawEps)
  362. {
  363. i++;
  364. AnimeEpisodeVM ep = new AnimeEpisodeVM(raw);
  365. ep.SetTvDBInfo();
  366. System.Windows.Application.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, (Action)delegate()
  367. {
  368. UnwatchedEpisodes.Add(ep);
  369. });
  370. if (i == 10) break;
  371. }
  372. }
  373. catch (Exception ex)
  374. {
  375. logger.ErrorException(ex.ToString(), ex);
  376. }
  377. }
  378. void recsWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  379. {
  380. AnimeSeriesVM ser = this.DataContext as AnimeSeriesVM;
  381. if (ser == null) return;
  382. if (!shoutsWorker.IsBusy)
  383. {
  384. IsLoadingShouts = true;
  385. shoutsWorker.RunWorkerAsync(ser);
  386. }
  387. }
  388. void recsWorker_DoWork(object sender, DoWorkEventArgs e)
  389. {
  390. try
  391. {
  392. AnimeSeriesVM ser = e.Argument as AnimeSeriesVM;
  393. System.Windows.Application.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, (Action)delegate()
  394. {
  395. Recommendations.Clear();
  396. });
  397. List<JMMServerBinary.Contract_AniDB_Anime_Similar> links = JMMServerVM.Instance.clientBinaryHTTP.GetSimilarAnimeLinks(ser.AniDB_ID,
  398. JMMServerVM.Instance.CurrentUser.JMMUserID.Value);
  399. List<AniDB_Anime_SimilarVM> tempList = new List<AniDB_Anime_SimilarVM>();
  400. foreach (JMMServerBinary.Contract_AniDB_Anime_Similar link in links)
  401. {
  402. AniDB_Anime_SimilarVM sim = new AniDB_Anime_SimilarVM();
  403. sim.Populate(link);
  404. tempList.Add(sim);
  405. }
  406. List<SortPropOrFieldAndDirection> sortCriteria = new List<SortPropOrFieldAndDirection>();
  407. sortCriteria.Add(new SortPropOrFieldAndDirection("ApprovalPercentage", true, SortType.eDoubleOrFloat));
  408. tempList = Sorting.MultiSort<AniDB_Anime_SimilarVM>(tempList, sortCriteria);
  409. foreach (AniDB_Anime_SimilarVM sim in tempList)
  410. {
  411. if (sim.AnimeInfoNotExists)
  412. {
  413. string result = JMMServerVM.Instance.clientBinaryHTTP.UpdateAnimeData(sim.SimilarAnimeID);
  414. if (string.IsNullOrEmpty(result))
  415. {
  416. JMMServerBinary.Contract_AniDBAnime animeContract = JMMServerVM.Instance.clientBinaryHTTP.GetAnime(sim.SimilarAnimeID);
  417. sim.PopulateAnime(animeContract);
  418. }
  419. }
  420. System.Windows.Application.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, (Action)delegate()
  421. {
  422. Recommendations.Add(new RecommendationTile()
  423. {
  424. Details = "",
  425. AnimeName = sim.DisplayName,
  426. Picture = sim.PosterPath,
  427. AnimeSeries = sim.AnimeSeries,
  428. TileSize = "Large",
  429. Height = 100,
  430. Source = "AniDB",
  431. AnimeID = sim.AnimeID,
  432. URL = sim.AniDB_SiteURL,
  433. SimilarAnimeID = sim.SimilarAnimeID,
  434. HasSeries = sim.LocalSeriesExists
  435. });
  436. });
  437. }
  438. }
  439. catch (Exception ex)
  440. {
  441. logger.ErrorException(ex.ToString(), ex);
  442. }
  443. }
  444. void shoutsWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  445. {
  446. IsLoadingShouts = false;
  447. }
  448. void shoutsWorker_DoWork(object sender, DoWorkEventArgs e)
  449. {
  450. AnimeSeriesVM ser = e.Argument as AnimeSeriesVM;
  451. List<Trakt_ShoutUserVM> tempShouts = new List<Trakt_ShoutUserVM>();
  452. try
  453. {
  454. System.Windows.Application.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, (Action)delegate()
  455. {
  456. Shouts.Clear();
  457. });
  458. // get shouts from trakt
  459. List<JMMServerBinary.Contract_Trakt_ShoutUser> rawShouts = JMMServerVM.Instance.clientBinaryHTTP.GetTraktShoutsForAnime(ser.AniDB_ID);
  460. foreach (JMMServerBinary.Contract_Trakt_ShoutUser contract in rawShouts)
  461. {
  462. Trakt_ShoutUserVM shout = new Trakt_ShoutUserVM(contract);
  463. shout.DelayedUserImage = @"/Images/blankposter.png";
  464. System.Windows.Application.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, (Action)delegate()
  465. {
  466. Shouts.Add(shout);
  467. });
  468. imagesToDownload.Add(shout);
  469. }
  470. // get recommendations from AniDB
  471. List<JMMServerBinary.Contract_AniDB_Recommendation> rawRecs = JMMServerVM.Instance.clientBinaryHTTP.GetAniDBRecommendations(ser.AniDB_ID);
  472. foreach (JMMServerBinary.Contract_AniDB_Recommendation contract in rawRecs)
  473. {
  474. AniDB_RecommendationVM rec = new AniDB_RecommendationVM(contract);
  475. rec.DelayedUserImage = @"/Images/blankposter.png";
  476. System.Windows.Application.Current.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, (Action)delegate()
  477. {
  478. Shouts.Add(rec);
  479. });
  480. imagesToDownload.Add(rec);
  481. }
  482. }
  483. catch (Exception ex)
  484. {
  485. logger.ErrorException(ex.ToString(), ex);
  486. }
  487. }
  488. void btnBack_Click(object sender, RoutedEventArgs e)
  489. {
  490. //MainWindow mainwdw = (MainWindow)Window.GetWindow(this);
  491. //mainwdw.ShowDashMetroView(MetroViews.MainMetro);
  492. DashboardMetroVM.Instance.NavigateBack();
  493. }
  494. private void RefreshData()
  495. {
  496. AnimeSeriesVM ser = this.DataContext as AnimeSeriesVM;
  497. if (ser == null) return;
  498. ser.RefreshBase();
  499. UnwatchedEpisodeCount = ser.UnwatchedEpisodeCount;
  500. UnwatchedEpisodes.Clear();
  501. Recommendations.Clear();
  502. Shouts.Clear();
  503. RefreshUnwatchedEpisodes();
  504. }
  505. void ContinueWatchingTileControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
  506. {
  507. AnimeSeriesVM ser = this.DataContext as AnimeSeriesVM;
  508. if (ser == null) return;
  509. ucExternalLinks.DataContext = ser;
  510. try
  511. {
  512. PosterWidth = 180;
  513. if (ser.AniDB_Anime.UsePosterOnSeries)
  514. {
  515. string imgName = ser.AniDB_Anime.FanartPathThenPosterPath;
  516. if (File.Exists(imgName))
  517. {
  518. BitmapDecoder decoder = BitmapDecoder.Create(new Uri(imgName), BitmapCreateOptions.None, BitmapCacheOption.None);
  519. BitmapFrame frame = decoder.Frames[0];
  520. PosterWidth = (double)250 * ((double)frame.PixelWidth / (double)frame.PixelHeight);
  521. }
  522. }
  523. }
  524. catch (Exception ex)
  525. {
  526. logger.ErrorException(ex.ToString(), ex);
  527. }
  528. RefreshData();
  529. }
  530. private void RefreshUnwatchedEpisodes()
  531. {
  532. AnimeSeriesVM ser = this.DataContext as AnimeSeriesVM;
  533. if (ser == null) return;
  534. if (!episodesWorker.IsBusy)
  535. episodesWorker.RunWorkerAsync(ser);
  536. }
  537. private void CommandBinding_PlayEpisode(object sender, ExecutedRoutedEventArgs e)
  538. {
  539. Window parentWindow = Window.GetWindow(this);
  540. object obj = e.Parameter;
  541. if (obj == null) return;
  542. try
  543. {
  544. if (obj.GetType() == typeof(AnimeEpisodeVM))
  545. {
  546. AnimeEpisodeVM ep = obj as AnimeEpisodeVM;
  547. if (ep.FilesForEpisode.Count == 1)
  548. MainWindow.videoHandler.PlayVideo(ep.FilesForEpisode[0]);
  549. else if (ep.FilesForEpisode.Count > 1)
  550. {
  551. if (AppSettings.AutoFileSingleEpisode)
  552. {
  553. VideoDetailedVM vid = MainWindow.videoHandler.GetAutoFileForEpisode(ep);
  554. if (vid != null)
  555. MainWindow.videoHandler.PlayVideo(vid);
  556. }
  557. else
  558. {
  559. PlayVideosForEpisodeForm frm = new PlayVideosForEpisodeForm();
  560. frm.Owner = parentWindow;
  561. frm.Init(ep);
  562. bool? result = frm.ShowDialog();
  563. }
  564. }
  565. }
  566. }
  567. catch (Exception ex)
  568. {
  569. Utils.ShowErrorMessage(ex);
  570. }
  571. }
  572. private void CommandBinding_PlayAllUnwatchedEpisode(object sender, ExecutedRoutedEventArgs e)
  573. {
  574. }
  575. private void CommandBinding_ToggleWatchedStatus(object sender, ExecutedRoutedEventArgs e)
  576. {
  577. object obj = e.Parameter;
  578. if (obj == null) return;
  579. this.Cursor = Cursors.Wait;
  580. try
  581. {
  582. Window parentWindow = Window.GetWindow(this);
  583. AnimeSeriesVM ser = null;
  584. bool newStatus = false;
  585. if (obj.GetType() == typeof(VideoDetailedVM))
  586. {
  587. VideoDetailedVM vid = obj as VideoDetailedVM;
  588. newStatus = !vid.Watched;
  589. JMMServerVM.Instance.clientBinaryHTTP.ToggleWatchedStatusOnVideo(vid.VideoLocalID, newStatus, JMMServerVM.Instance.CurrentUser.JMMUserID.Value);
  590. MainListHelperVM.Instance.UpdateHeirarchy(vid);
  591. ser = MainListHelperVM.Instance.GetSeriesForVideo(vid.VideoLocalID);
  592. }
  593. if (obj.GetType() == typeof(AnimeEpisodeVM))
  594. {
  595. AnimeEpisodeVM ep = obj as AnimeEpisodeVM;
  596. newStatus = !ep.Watched;
  597. JMMServerBinary.Contract_ToggleWatchedStatusOnEpisode_Response response = JMMServerVM.Instance.clientBinaryHTTP.ToggleWatchedStatusOnEpisode(ep.AnimeEpisodeID,
  598. newStatus, JMMServerVM.Instance.CurrentUser.JMMUserID.Value);
  599. if (!string.IsNullOrEmpty(response.ErrorMessage))
  600. {
  601. MessageBox.Show(response.ErrorMessage, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
  602. return;
  603. }
  604. MainListHelperVM.Instance.UpdateHeirarchy(response.AnimeEpisode);
  605. ser = MainListHelperVM.Instance.GetSeriesForEpisode(ep);
  606. }
  607. RefreshData();
  608. if (newStatus == true && ser != null)
  609. {
  610. Utils.PromptToRateSeries(ser, parentWindow);
  611. }
  612. }
  613. catch (Exception ex)
  614. {
  615. Utils.ShowErrorMessage(ex);
  616. }
  617. finally
  618. {
  619. this.Cursor = Cursors.Arrow;
  620. }
  621. }
  622. private void CommandBinding_VoteUp(object sender, ExecutedRoutedEventArgs e)
  623. {
  624. Window parentWindow = Window.GetWindow(this);
  625. object obj = e.Parameter;
  626. if (obj == null) return;
  627. try
  628. {
  629. if (obj.GetType() == typeof(RecommendationTile))
  630. {
  631. RecommendationTile rec = obj as RecommendationTile;
  632. Utils.AniDBVoteRecommendation(rec.AnimeID, rec.SimilarAnimeID, true);
  633. }
  634. }
  635. catch (Exception ex)
  636. {
  637. Utils.ShowErrorMessage(ex);
  638. }
  639. }
  640. private void CommandBinding_VoteDown(object sender, ExecutedRoutedEventArgs e)
  641. {
  642. Window parentWindow = Window.GetWindow(this);
  643. object obj = e.Parameter;
  644. if (obj == null) return;
  645. try
  646. {
  647. if (obj.GetType() == typeof(RecommendationTile))
  648. {
  649. RecommendationTile rec = obj as RecommendationTile;
  650. Utils.AniDBVoteRecommendation(rec.AnimeID, rec.SimilarAnimeID, false);
  651. }
  652. }
  653. catch (Exception ex)
  654. {
  655. Utils.ShowErrorMessage(ex);
  656. }
  657. }
  658. private void CommandBinding_RecDetails(object sender, ExecutedRoutedEventArgs e)
  659. {
  660. Window parentWindow = Window.GetWindow(this);
  661. object obj = e.Parameter;
  662. if (obj == null) return;
  663. try
  664. {
  665. if (obj.GetType() == typeof(RecommendationTile))
  666. {
  667. RecommendationTile rec = obj as RecommendationTile;
  668. if (rec.AnimeSeries != null)
  669. {
  670. //MainWindow mainwdw = (MainWindow)Window.GetWindow(this);
  671. //mainwdw.ShowDashMetroView(MetroViews.ContinueWatching, rec.AnimeSeries);
  672. DashboardMetroVM.Instance.NavigateForward(MetroViews.ContinueWatching, rec.AnimeSeries);
  673. }
  674. else
  675. {
  676. Uri uri = new Uri(rec.URL);
  677. Process.Start(new ProcessStartInfo(uri.AbsoluteUri));
  678. }
  679. }
  680. }
  681. catch (Exception ex)
  682. {
  683. Utils.ShowErrorMessage(ex);
  684. }
  685. }
  686. }
  687. }