Esempio n. 1
0
        /// <summary>
        /// Search movies asynchronously
        /// </summary>
        public override async Task LoadMoviesAsync(bool reset = false)
        {
            await LoadingSemaphore.WaitAsync(CancellationLoadingMovies.Token);

            StopLoadingMovies();
            if (reset)
            {
                Movies.Clear();
                Page           = 0;
                VerticalScroll = 0d;
            }

            var watch = Stopwatch.StartNew();

            Page++;
            if (Page > 1 && Movies.Count == MaxNumberOfMovies)
            {
                Page--;
                LoadingSemaphore.Release();
                return;
            }

            Logger.Info(
                $"Loading search page {Page} with criteria: {SearchFilter}");
            HasLoadingFailed = false;
            try
            {
                IsLoadingMovies = true;
                var result =
                    await MovieService.SearchMoviesAsync(SearchFilter,
                                                         Page,
                                                         MaxMoviesPerPage,
                                                         Genre,
                                                         Rating,
                                                         CancellationLoadingMovies.Token);

                Movies.AddRange(result.movies.Except(Movies, new MovieLightComparer()));
                IsLoadingMovies       = false;
                IsMovieFound          = Movies.Any();
                CurrentNumberOfMovies = Movies.Count;
                MaxNumberOfMovies     = result.nbMovies;
                UserService.SyncMovieHistory(Movies);
            }
            catch (Exception exception)
            {
                Page--;
                Logger.Error(
                    $"Error while loading search page {Page} with criteria {SearchFilter}: {exception.Message}");
                HasLoadingFailed = true;
                Messenger.Default.Send(new ManageExceptionMessage(exception));
            }
            finally
            {
                watch.Stop();
                var elapsedMs = watch.ElapsedMilliseconds;
                Logger.Info(
                    $"Loaded search page {Page} with criteria {SearchFilter} in {elapsedMs} milliseconds.");
                LoadingSemaphore.Release();
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Load movies asynchronously
        /// </summary>
        public override async Task LoadShowsAsync(bool reset = false)
        {
            await LoadingSemaphore.WaitAsync();

            StopLoadingShows();
            if (reset)
            {
                Shows.Clear();
                Page = 0;
            }

            var watch = Stopwatch.StartNew();

            Page++;
            if (Page > 1 && Shows.Count == MaxNumberOfShows)
            {
                Page--;
                LoadingSemaphore.Release();
                return;
            }

            Logger.Info(
                $"Loading shows favorite page {Page}...");
            HasLoadingFailed = false;
            try
            {
                IsLoadingShows = true;
                var imdbIds =
                    await UserService.GetFavoritesShows(Page);

                if (!NeedSync)
                {
                    var shows = new List <ShowLightJson>();
                    await imdbIds.shows.ParallelForEachAsync(async imdbId =>
                    {
                        try
                        {
                            var show = await ShowService.GetShowLightAsync(imdbId);
                            if (show != null)
                            {
                                show.IsFavorite = true;
                                shows.Add(show);
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.Error(ex);
                        }
                    });

                    var updatedShows = shows.OrderBy(a => a.Title)
                                       .Where(a => (Genre == null || a.Genres.Contains(Genre.EnglishName)) &&
                                              a.Rating.Percentage >= Rating * 10);
                    foreach (var show in updatedShows.Except(Shows.ToList(), new ShowLightComparer()))
                    {
                        var pair = Shows
                                   .Select((value, index) => new { value, index })
                                   .FirstOrDefault(x => string.CompareOrdinal(x.value.Title, show.Title) > 0);


                        if (pair == null)
                        {
                            Shows.Add(show);
                        }
                        else
                        {
                            Shows.Insert(pair.index, show);
                        }
                    }
                }
                else
                {
                    var showsToDelete = Shows.Select(a => a.ImdbId).Except(imdbIds.allShows);
                    var showsToAdd    = imdbIds.allShows.Except(Shows.Select(a => a.ImdbId));
                    foreach (var movie in showsToDelete.ToList())
                    {
                        Shows.Remove(Shows.FirstOrDefault(a => a.ImdbId == movie));
                    }

                    var shows = showsToAdd.ToList();
                    var showsToAddAndToOrder = new List <ShowLightJson>();
                    await shows.ParallelForEachAsync(async imdbId =>
                    {
                        try
                        {
                            var show = await ShowService.GetShowLightAsync(imdbId);
                            if ((Genre == null || show.Genres.Contains(Genre.EnglishName)) && show.Rating.Percentage >= Rating * 10)
                            {
                                showsToAddAndToOrder.Add(show);
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.Error(ex);
                        }
                    });

                    foreach (var show in showsToAddAndToOrder.Except(Shows.ToList(), new ShowLightComparer()))
                    {
                        var pair = Shows
                                   .Select((value, index) => new { value, index })
                                   .FirstOrDefault(x => string.CompareOrdinal(x.value.Title, show.Title) > 0);
                        if (pair == null)
                        {
                            Shows.Add(show);
                        }
                        else
                        {
                            Shows.Insert(pair.index, show);
                        }
                    }
                }
                IsLoadingShows       = false;
                IsShowFound          = Shows.Any();
                CurrentNumberOfShows = Shows.Count;
                MaxNumberOfShows     = imdbIds.nbShows;
                await UserService.SyncShowHistoryAsync(Shows).ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                Page--;
                Logger.Error(
                    $"Error while loading shows favorite page {Page}: {exception.Message}");
                HasLoadingFailed = true;
                Messenger.Default.Send(new ManageExceptionMessage(exception));
            }
            finally
            {
                NeedSync = false;
                watch.Stop();
                var elapsedMs = watch.ElapsedMilliseconds;
                Logger.Info(
                    $"Loaded shows favorite page {Page} in {elapsedMs} milliseconds.");
                LoadingSemaphore.Release();
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Search shows asynchronously
        /// </summary>
        public override async Task LoadShowsAsync(bool reset = false)
        {
            await LoadingSemaphore.WaitAsync(CancellationLoadingShows.Token);

            await Task.Run(async() =>
            {
                StopLoadingShows();
                if (reset)
                {
                    DispatcherHelper.CheckBeginInvokeOnUI(() =>
                    {
                        Shows.Clear();
                        Page           = 0;
                        VerticalScroll = 0d;
                    });
                }

                var watch = Stopwatch.StartNew();
                Page++;
                if (Page > 1 && Shows.Count == MaxNumberOfShows)
                {
                    Page--;
                    LoadingSemaphore.Release();
                    return;
                }

                Logger.Info(
                    $"Loading search page {Page} with criteria: {SearchFilter}");
                HasLoadingFailed = false;
                try
                {
                    IsLoadingShows = true;
                    var result     =
                        await ShowService.SearchShowsAsync(SearchFilter,
                                                           Page,
                                                           MaxNumberOfShows,
                                                           Genre,
                                                           Rating * 10,
                                                           CancellationLoadingShows.Token);

                    DispatcherHelper.CheckBeginInvokeOnUI(() =>
                    {
                        Shows.AddRange(result.shows.Except(Shows, new ShowLightComparer()));
                        IsLoadingShows       = false;
                        IsShowFound          = Shows.Any();
                        CurrentNumberOfShows = Shows.Count;
                        MaxNumberOfShows     = result.nbShows;
                        UserService.SyncShowHistory(Shows);
                    });
                }
                catch (Exception exception)
                {
                    Page--;
                    Logger.Error(
                        $"Error while loading search page {Page} with criteria {SearchFilter}: {exception.Message}");
                    HasLoadingFailed = true;
                    Messenger.Default.Send(new ManageExceptionMessage(exception));
                }
                finally
                {
                    watch.Stop();
                    var elapsedMs = watch.ElapsedMilliseconds;
                    Logger.Info(
                        $"Loaded search page {Page} with criteria {SearchFilter} in {elapsedMs} milliseconds.");
                    LoadingSemaphore.Release();
                }
            });
        }
        /// <summary>
        /// Load movies asynchronously
        /// </summary>
        public override async Task LoadMoviesAsync(bool reset = false)
        {
            await LoadingSemaphore.WaitAsync(CancellationLoadingMovies.Token);

            if (reset)
            {
                Movies.Clear();
                Page           = 0;
                VerticalScroll = 0d;
            }

            var watch = Stopwatch.StartNew();

            Page++;
            if (Page > 1 && Movies.Count == MaxNumberOfMovies)
            {
                Page--;
                LoadingSemaphore.Release();
                return;
            }

            StopLoadingMovies();
            Logger.Info(
                $"Loading page {Page}...");
            HasLoadingFailed = false;
            try
            {
                IsLoadingMovies = true;
                await Task.Run(async() =>
                {
                    var getMoviesWatcher = new Stopwatch();
                    getMoviesWatcher.Start();
                    var seen      = UserService.GetSeenMovies(Page);
                    var favorites = UserService.GetFavoritesMovies(Page);
                    var movies    = seen.allMovies.Union(favorites.allMovies).Distinct().ToList();
                    var result    = await MovieService
                                    .GetSimilarAsync(Page, Utils.Constants.MaxMoviesPerPage, movies,
                                                     CancellationLoadingMovies.Token).ConfigureAwait(false);
                    getMoviesWatcher.Stop();
                    var getMoviesEllapsedTime = getMoviesWatcher.ElapsedMilliseconds;
                    if (reset && getMoviesEllapsedTime < 500)
                    {
                        // Wait for VerticalOffset to reach 0 (animation lasts 500ms)
                        await Task.Delay(500 - (int)getMoviesEllapsedTime, CancellationLoadingMovies.Token).ConfigureAwait(false);
                    }

                    DispatcherHelper.CheckBeginInvokeOnUI(() =>
                    {
                        Movies.AddRange(result.movies.Except(Movies, new MovieLightComparer()));
                        IsLoadingMovies       = false;
                        IsMovieFound          = Movies.Any();
                        CurrentNumberOfMovies = Movies.Count;
                        MaxNumberOfMovies     = result.nbMovies == 0 ? Movies.Count : result.nbMovies;
                        UserService.SyncMovieHistory(Movies);
                    });
                }, CancellationLoadingMovies.Token).ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                Page--;
                Logger.Error(
                    $"Error while loading page {Page}: {exception.Message}");
                HasLoadingFailed = true;
                Messenger.Default.Send(new ManageExceptionMessage(exception));
            }
            finally
            {
                watch.Stop();
                var elapsedMs = watch.ElapsedMilliseconds;
                Logger.Info(
                    $"Loaded page {Page} in {elapsedMs} milliseconds.");
                LoadingSemaphore.Release();
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Load movies asynchronously
        /// </summary>
        public override async Task LoadMoviesAsync(bool reset = false)
        {
            await LoadingSemaphore.WaitAsync();

            StopLoadingMovies();
            if (reset)
            {
                Movies.Clear();
                Page = 0;
            }

            var watch = Stopwatch.StartNew();

            Page++;
            if (Page > 1 && Movies.Count == MaxNumberOfMovies)
            {
                Page--;
                LoadingSemaphore.Release();
                return;
            }

            Logger.Info(
                $"Loading movies seen page {Page}...");
            HasLoadingFailed = false;
            try
            {
                IsLoadingMovies = true;
                var imdbIds =
                    await UserService.GetSeenMovies(Page);

                if (!_needSync)
                {
                    var movies = new List <MovieJson>();
                    await imdbIds.movies.ParallelForEachAsync(async imdbId =>
                    {
                        var movie = await MovieService.GetMovieAsync(imdbId);
                        if (movie != null)
                        {
                            movie.IsFavorite = true;
                            movies.Add(movie);
                        }
                    });

                    var updatedMovies = movies.OrderBy(a => a.Title)
                                        .Where(a => (Genre != null
                                        ? a.Genres.Any(
                                                         genre => genre.ToLowerInvariant() ==
                                                         Genre.EnglishName.ToLowerInvariant())
                                        : a.Genres.TrueForAll(b => true)) && a.Rating >= Rating);
                    Movies.AddRange(updatedMovies.Except(Movies.ToList(), new MovieComparer()));
                }
                else
                {
                    var moviesToDelete = Movies.Select(a => a.ImdbCode).Except(imdbIds.allMovies);
                    var moviesToAdd    = imdbIds.allMovies.Except(Movies.Select(a => a.ImdbCode));
                    foreach (var movie in moviesToDelete.ToList())
                    {
                        Movies.Remove(Movies.FirstOrDefault(a => a.ImdbCode == movie));
                    }

                    var movies = moviesToAdd.ToList();
                    await movies.ParallelForEachAsync(async imdbId =>
                    {
                        var movie = await MovieService.GetMovieAsync(imdbId);
                        if ((Genre != null
                                    ? movie.Genres.Any(
                                 genre => genre.ToLowerInvariant() ==
                                 Genre.EnglishName.ToLowerInvariant())
                                    : movie.Genres.TrueForAll(b => true)) && movie.Rating >= Rating)
                        {
                            DispatcherHelper.CheckBeginInvokeOnUI(() =>
                            {
                                Movies.Add(movie);
                            });
                        }
                    });
                }

                IsLoadingMovies       = false;
                IsMovieFound          = Movies.Any();
                CurrentNumberOfMovies = Movies.Count;
                MaxNumberOfMovies     = imdbIds.nbMovies;
                await UserService.SyncMovieHistoryAsync(Movies);
            }
            catch (Exception exception)
            {
                Page--;
                Logger.Error(
                    $"Error while loading movies seen page {Page}: {exception.Message}");
                HasLoadingFailed = true;
                Messenger.Default.Send(new ManageExceptionMessage(exception));
            }
            finally
            {
                Movies.Sort((a, b) => String.Compare(a.Title, b.Title, StringComparison.Ordinal));
                _needSync = false;
                watch.Stop();
                var elapsedMs = watch.ElapsedMilliseconds;
                Logger.Info(
                    $"Loaded movies seen page {Page} in {elapsedMs} milliseconds.");
                LoadingSemaphore.Release();
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Load movies asynchronously
        /// </summary>
        public override async Task LoadMoviesAsync(bool reset = false)
        {
            await LoadingSemaphore.WaitAsync();

            StopLoadingMovies();
            if (reset)
            {
                Movies.Clear();
                Page = 0;
            }

            var watch = Stopwatch.StartNew();

            Page++;
            if (Page > 1 && Movies.Count == MaxNumberOfMovies)
            {
                Page--;
                LoadingSemaphore.Release();
                return;
            }

            Logger.Info(
                $"Loading movies seen page {Page}...");
            HasLoadingFailed = false;
            try
            {
                IsLoadingMovies = true;
                var imdbIds =
                    await UserService.GetSeenMovies(Page);

                if (!NeedSync)
                {
                    var movies = new List <MovieLightJson>();
                    await imdbIds.movies.ParallelForEachAsync(async imdbId =>
                    {
                        try
                        {
                            var movie = await MovieService.GetMovieLightAsync(imdbId);
                            if (movie != null)
                            {
                                movie.IsFavorite = true;
                                movies.Add(movie);
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.Error(ex);
                        }
                    });

                    var updatedMovies = movies.OrderBy(a => a.Title)
                                        .Where(a => (Genre == null || a.Genres.Contains(Genre.EnglishName)) &&
                                               a.Rating >= Rating);

                    foreach (var movie in updatedMovies.Except(Movies.ToList(), new MovieLightComparer()))
                    {
                        var pair = Movies
                                   .Select((value, index) => new { value, index })
                                   .FirstOrDefault(x => string.CompareOrdinal(x.value.Title, movie.Title) > 0);

                        if (pair == null)
                        {
                            Movies.Add(movie);
                        }
                        else
                        {
                            Movies.Insert(pair.index, movie);
                        }
                    }
                }
                else
                {
                    var moviesToDelete = Movies.Select(a => a.ImdbCode).Except(imdbIds.allMovies);
                    var moviesToAdd    = imdbIds.allMovies.Except(Movies.Select(a => a.ImdbCode));

                    foreach (var movie in moviesToDelete.ToList())
                    {
                        Movies.Remove(Movies.FirstOrDefault(a => a.ImdbCode == movie));
                    }

                    var movies = moviesToAdd.ToList();
                    var moviesToAddAndToOrder = new List <MovieLightJson>();
                    await movies.ParallelForEachAsync(async imdbId =>
                    {
                        try
                        {
                            var movie = await MovieService.GetMovieLightAsync(imdbId);
                            if ((Genre == null || movie.Genres.Contains(Genre.EnglishName)) && movie.Rating >= Rating)
                            {
                                moviesToAddAndToOrder.Add(movie);
                            }
                        }
                        catch (Exception ex)
                        {
                            Logger.Error(ex);
                        }
                    });

                    foreach (var movie in moviesToAddAndToOrder.Except(Movies.ToList(), new MovieLightComparer()))
                    {
                        var pair = Movies
                                   .Select((value, index) => new { value, index })
                                   .FirstOrDefault(x => string.CompareOrdinal(x.value.Title, movie.Title) > 0);

                        if (pair == null)
                        {
                            Movies.Add(movie);
                        }
                        else
                        {
                            Movies.Insert(pair.index, movie);
                        }
                    }
                }

                IsLoadingMovies       = false;
                IsMovieFound          = Movies.Any();
                CurrentNumberOfMovies = Movies.Count;
                MaxNumberOfMovies     = imdbIds.nbMovies;
                await UserService.SyncMovieHistoryAsync(Movies).ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                Page--;
                Logger.Error(
                    $"Error while loading movies seen page {Page}: {exception.Message}");
                HasLoadingFailed = true;
                Messenger.Default.Send(new ManageExceptionMessage(exception));
            }
            finally
            {
                NeedSync = false;
                watch.Stop();
                var elapsedMs = watch.ElapsedMilliseconds;
                Logger.Info(
                    $"Loaded movies seen page {Page} in {elapsedMs} milliseconds.");
                LoadingSemaphore.Release();
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Load movies asynchronously
        /// </summary>
        public override async Task LoadMoviesAsync(bool reset = false)
        {
            await LoadingSemaphore.WaitAsync(CancellationLoadingMovies.Token);

            StopLoadingMovies();
            if (reset)
            {
                Movies.Clear();
                Page           = 0;
                VerticalScroll = 0d;
            }

            var watch = Stopwatch.StartNew();

            Page++;
            if (Page > 1 && Movies.Count == MaxNumberOfMovies && reset)
            {
                Page--;
                LoadingSemaphore.Release();
                return;
            }

            Logger.Trace(
                "Loading movies favorites page...");
            HasLoadingFailed = false;
            try
            {
                IsLoadingMovies = true;
                var imdbIds = UserService.GetFavoritesMovies(Page);

                var moviesToDelete = Movies.Select(a => a.ImdbId).Except(imdbIds.allMovies);
                var moviesToAdd    = imdbIds.movies.Except(Movies.Select(a => a.ImdbId));

                foreach (var movie in moviesToDelete.ToList())
                {
                    Movies.Remove(Movies.FirstOrDefault(a => a.ImdbId == movie));
                }

                var movies = moviesToAdd.ToList();
                var moviesToAddAndToOrder = new List <MovieLightJson>();

                if (movies.Any())
                {
                    var movieByIds = await MovieService.GetMoviesByIds(movies, CancellationLoadingMovies.Token);

                    foreach (var movie in movieByIds.movies)
                    {
                        if ((Genre == null || movie.Genres.Contains(Genre.EnglishName)) &&
                            movie.Rating >= Rating)
                        {
                            moviesToAddAndToOrder.Add(movie);
                        }
                    }
                }

                foreach (var movie in moviesToAddAndToOrder.Except(Movies.ToList(), new MovieLightComparer()))
                {
                    var pair = Movies
                               .Select((value, index) => new { value, index })
                               .FirstOrDefault(x => string.CompareOrdinal(x.value.Title, movie.Title) > 0);

                    if (pair == null)
                    {
                        Movies.Add(movie);
                    }
                    else
                    {
                        Movies.Insert(pair.index, movie);
                    }
                }

                IsLoadingMovies       = false;
                IsMovieFound          = Movies.Any();
                CurrentNumberOfMovies = Movies.Count;
                MaxNumberOfMovies     = imdbIds.nbMovies;
                UserService.SyncMovieHistory(Movies);
            }
            catch (Exception exception)
            {
                Page--;
                Logger.Error(
                    $"Error while loading movies favorite page {Page}: {exception.Message}");
                HasLoadingFailed = true;
                Messenger.Default.Send(new ManageExceptionMessage(exception));
            }
            finally
            {
                NeedSync = false;
                watch.Stop();
                var elapsedMs = watch.ElapsedMilliseconds;
                Logger.Trace(
                    $"Loaded movies favorite page {Page} in {elapsedMs} milliseconds.");
                LoadingSemaphore.Release();
            }
        }
        /// <summary>
        /// Load movies asynchronously
        /// </summary>
        public override async Task LoadShowsAsync(bool reset = false)
        {
            await LoadingSemaphore.WaitAsync();

            StopLoadingShows();
            if (reset)
            {
                Shows.Clear();
                Page = 0;
            }

            var watch = Stopwatch.StartNew();

            Page++;
            if (Page > 1 && Shows.Count == MaxNumberOfShows)
            {
                Page--;
                LoadingSemaphore.Release();
                return;
            }

            Logger.Info(
                $"Loading shows favorite page {Page}...");
            HasLoadingFailed = false;
            try
            {
                IsLoadingShows = true;
                var imdbIds =
                    await UserService.GetFavoritesShows(Page);

                if (!_needSync)
                {
                    var shows = new List <ShowJson>();
                    await imdbIds.shows.ParallelForEachAsync(async imdbId =>
                    {
                        var show = await ShowService.GetShowAsync(imdbId);
                        if (show != null)
                        {
                            show.IsFavorite = true;
                            shows.Add(show);
                        }
                    });

                    var updatedShows = shows.OrderBy(a => a.Title)
                                       .Where(a => (Genre != null
                                        ? a.Genres.Any(
                                                        genre => genre.ToLowerInvariant() ==
                                                        Genre.EnglishName.ToLowerInvariant())
                                        : a.Genres.TrueForAll(b => true)) && a.Rating.Percentage >= Rating * 10);
                    Shows.AddRange(updatedShows.Except(Shows.ToList(), new ShowComparer()));
                }
                else
                {
                    var showsToDelete = Shows.Select(a => a.ImdbId).Except(imdbIds.allShows);
                    var showsToAdd    = imdbIds.allShows.Except(Shows.Select(a => a.ImdbId));
                    foreach (var movie in showsToDelete.ToList())
                    {
                        Shows.Remove(Shows.FirstOrDefault(a => a.ImdbId == movie));
                    }

                    var shows = showsToAdd.ToList();
                    await shows.ParallelForEachAsync(async imdbId =>
                    {
                        var show = await ShowService.GetShowAsync(imdbId);
                        if ((Genre != null
                                    ? show.Genres.Any(
                                 genre => genre.ToLowerInvariant() ==
                                 Genre.EnglishName.ToLowerInvariant())
                                    : show.Genres.TrueForAll(b => true)) && show.Rating.Percentage >= Rating * 10)
                        {
                            DispatcherHelper.CheckBeginInvokeOnUI(() =>
                            {
                                Shows.Add(show);
                            });
                        }
                    });
                }

                IsLoadingShows       = false;
                IsShowFound          = Shows.Any();
                CurrentNumberOfShows = Shows.Count;
                MaxNumberOfShows     = imdbIds.nbShows;
                await UserService.SyncShowHistoryAsync(Shows);
            }
            catch (Exception exception)
            {
                Page--;
                Logger.Error(
                    $"Error while loading shows favorite page {Page}: {exception.Message}");
                HasLoadingFailed = true;
                Messenger.Default.Send(new ManageExceptionMessage(exception));
            }
            finally
            {
                Shows.Sort((a, b) => String.Compare(a.Title, b.Title, StringComparison.Ordinal));
                _needSync = false;
                watch.Stop();
                var elapsedMs = watch.ElapsedMilliseconds;
                Logger.Info(
                    $"Loaded shows favorite page {Page} in {elapsedMs} milliseconds.");
                LoadingSemaphore.Release();
            }
        }
        /// <summary>
        /// Load shows asynchronously
        /// </summary>
        public override async Task LoadShowsAsync(bool reset = false)
        {
            await LoadingSemaphore.WaitAsync();

            if (reset)
            {
                Shows.Clear();
                Page           = 0;
                VerticalScroll = 0d;
            }

            var watch = Stopwatch.StartNew();

            Page++;
            if (Page > 1 && Shows.Count == MaxNumberOfShows)
            {
                Page--;
                LoadingSemaphore.Release();
                return;
            }

            StopLoadingShows();
            Logger.Info(
                $"Loading page {Page}...");
            HasLoadingFailed = false;
            try
            {
                IsLoadingShows = true;
                await Task.Run(async() =>
                {
                    var getMoviesWatcher = new Stopwatch();
                    getMoviesWatcher.Start();
                    var result =
                        await ShowService.Discover(Page).ConfigureAwait(false);
                    getMoviesWatcher.Stop();
                    var getMoviesEllapsedTime = getMoviesWatcher.ElapsedMilliseconds;
                    if (reset && getMoviesEllapsedTime < 500)
                    {
                        // Wait for VerticalOffset to reach 0 (animation lasts 500ms)
                        await Task.Delay(500 - (int)getMoviesEllapsedTime).ConfigureAwait(false);
                    }

                    DispatcherHelper.CheckBeginInvokeOnUI(() =>
                    {
                        Shows.AddRange(result.Item1.Except(Shows, new ShowLightComparer()));
                        IsLoadingShows       = false;
                        IsShowFound          = Shows.Any();
                        CurrentNumberOfShows = Shows.Count;
                        MaxNumberOfShows     = result.nbMovies;
                        UserService.SyncShowHistory(Shows);
                    });
                }).ConfigureAwait(false);
            }
            catch (Exception exception)
            {
                Page--;
                Logger.Error(
                    $"Error while loading page {Page}: {exception.Message}");
                HasLoadingFailed = true;
                Messenger.Default.Send(new ManageExceptionMessage(exception));
            }
            finally
            {
                watch.Stop();
                var elapsedMs = watch.ElapsedMilliseconds;
                Logger.Info(
                    $"Loaded page {Page} in {elapsedMs} milliseconds.");
                LoadingSemaphore.Release();
            }
        }