WIP on scrolling

pull/3895/head
Jamie Rees 6 years ago
parent ea54dfa3bf
commit 227ec0a6f8

@ -109,9 +109,16 @@ namespace Ombi.Core.Engine.V2
// Pages of 20
if(toLoad > 20)
{
throw new ApplicationException("Please load less than 20 items at a time due to a API limit");
throw new ApplicationException("Please load less than or equal to 20 items at a time due to a API limit");
}
// TheMovieDb only shows pages of 20, let's work out how many we need to load
var page = Math.Round((decimal)(currentlyLoaded / 10) / 2, 0);
if(page == 0)
{
// First page
}
var result = await MovieApi.PopularMovies(langCode);

@ -0,0 +1,41 @@
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Ombi.Helpers.Tests
{
[TestFixture]
public class PaginationHelperTests
{
[TestCaseSource(nameof(TestData))]
[Ignore("https://stackoverflow.com/questions/55710966/working-out-how-many-items-to-take-in-a-paginated-list")]
public void TestPaginationPagesToLoad(int currentlyLoaded, int toLoad, int maxItemsPerPage, int[] expectedPages)
{
var result = PaginationHelper.GetNextPages(currentlyLoaded, toLoad, maxItemsPerPage);
var pages = result.Select(x => x.Page).ToArray();
Assert.That(pages.Length, Is.EqualTo(expectedPages.Length), "Did not contain the correct amount of pages");
for (int i = 0; i < pages.Length; i++)
{
Assert.That(pages[i], Is.EqualTo(expectedPages[i]));
}
}
public static IEnumerable<TestCaseData> TestData
{
get
{
yield return new TestCaseData(0, 10, 20, new [] { 1 }).SetName("Load_First_Page");
yield return new TestCaseData(20, 10, 20, new [] { 2 }).SetName("Load_Second_Page");
yield return new TestCaseData(0, 20, 20, new [] { 2 }).SetName("Load_Full_First_Page_Should_Get_NextPage");
yield return new TestCaseData(20, 20, 20, new [] { 3 }).SetName("Load_Full_Second_Page_Should_Get_Next_Page");
yield return new TestCaseData(10, 20, 20, new [] { 1, 2 }).SetName("Load_Half_First_Page_And_Half_Second_Page");
yield return new TestCaseData(19, 20, 20, new [] { 1, 2 }).SetName("Load_End_First_Page_And_Most_Second_Page");
}
}
}
}

@ -0,0 +1,75 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Ombi.Helpers
{
public static class PaginationHelper
{
public static List<PagesToLoad> GetNextPages(int currentlyLoaded, int toLoad, int maxItemsPerPage)
{
var pagesToLoad = new List<PagesToLoad>();
if (currentlyLoaded == maxItemsPerPage)
{
currentlyLoaded++;
}
var a = currentlyLoaded / maxItemsPerPage;
//var currentPage = Convert.ToInt32(Math.Round((decimal)((decimal)currentlyLoaded / (decimal)maxItemsPerPage), 2, MidpointRounding.AwayFromZero));
var currentPage = Convert.ToInt32(Math.Ceiling((decimal)((decimal)currentlyLoaded / (decimal)maxItemsPerPage)));
if (currentlyLoaded < maxItemsPerPage)
{
currentPage = 1;
}
var toBeLoaded = (currentlyLoaded + toLoad)+1;
//var toBeLoadedPage = Convert.ToInt32(Math.Round((decimal)((decimal)toBeLoaded / (decimal)maxItemsPerPage), 2, MidpointRounding.AwayFromZero));
var toBeLoadedPage = Convert.ToInt32(Math.Ceiling((decimal)((decimal)toBeLoaded / (decimal)maxItemsPerPage)));
if (currentlyLoaded == 0)
{
// If we have not loaded any yet, then we should only load
// the first page
currentPage = toBeLoadedPage;
}
var extraPageNeeded = (toBeLoadedPage != currentPage);
if(extraPageNeeded)
{
// Add the first page
pagesToLoad.Add(new PagesToLoad
{
Page = currentPage,
Skip = currentlyLoaded
});
// Add extra page
pagesToLoad.Add(new PagesToLoad
{
Page = toBeLoadedPage,
Skip = (currentlyLoaded + toLoad) - maxItemsPerPage,
Take = toLoad
});
}
else
{
pagesToLoad.Add(new PagesToLoad
{
Page = currentPage,
Skip = currentlyLoaded,
Take = toLoad
});
}
return pagesToLoad;
}
}
public class PagesToLoad
{
public int Page { get; set; }
public int Take { get; set; }
public int Skip { get; set; }
}
}

@ -171,7 +171,7 @@ namespace Ombi.Api.TheMovieDb
var request = new Request($"movie/popular", BaseUri, HttpMethod.Get);
request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken);
request.FullUri = request.FullUri.AddQueryParameter("language", langageCode);
request.FullUri = request.FullUri.AddQueryParameter("page", page,ToString());
request.FullUri = request.FullUri.AddQueryParameter("page", page.ToString());
AddRetry(request);
var result = await Api.Request<TheMovieDbContainer<SearchResult>>(request);
return Mapper.Map<List<MovieSearchResult>>(result.results);

@ -1,34 +1,28 @@
<div class="small-middle-container">
<div class="small-middle-container">
<div class="row justify-content-md-center top-spacing">
<div class="btn-group" role="group" aria-label="Basic example">
<button type="button" (click)="popular()" [attr.color]="popularActive ? 'accent' : 'primary'"
[ngClass]="popularActive ? 'mat-accent' : 'mat-primary'" mat-raised-button
class="btn grow" >{{'Discovery.PopularTab' | translate}}</button>
<button type="button" (click)="trending()"
[attr.color]="trendingActive ? 'accent' : 'primary'"
[ngClass]="trendingActive ? 'mat-accent' : 'mat-primary'"
mat-raised-button class="btn grow" color="primary">{{'Discovery.TrendingTab' | translate}}</button>
<button type="button" (click)="upcoming()"
[attr.color]="upcomingActive ? 'accent' : 'primary'"
[ngClass]="upcomingActive ? 'mat-accent' : 'mat-primary'"
mat-raised-button class="btn grow" color="primary">{{'Discovery.UpcomingTab' | translate}}</button>
</div>
</div>
<div *ngIf="loadingFlag" class="row justify-content-md-center top-spacing loading-spinner">
<mat-spinner [color]="'accent'"></mat-spinner>
</div>
<div *ngIf="discoverResults" class="row full-height discoverResults">
<div *ngIf="discoverResults"
infiniteScroll
[infiniteScrollDistance]="2"
[infiniteScrollThrottle]="300"
(scrolled)="onScroll()"
></div>
<div class="col-xl-2 col-lg-3 col-md-3 col-6 col-sm-4 small-padding" *ngFor="let result of discoverResults">
<discover-card [result]="result"></discover-card>
</div>
<div class="row justify-content-md-center top-spacing">
<div class="btn-group" role="group" aria-label="Basic example">
<button type="button" (click)="popular()" [attr.color]="popularActive ? 'accent' : 'primary'"
[ngClass]="popularActive ? 'mat-accent' : 'mat-primary'" mat-raised-button
class="btn grow">{{'Discovery.PopularTab' | translate}}</button>
<button type="button" (click)="trending()" [attr.color]="trendingActive ? 'accent' : 'primary'"
[ngClass]="trendingActive ? 'mat-accent' : 'mat-primary'" mat-raised-button class="btn grow"
color="primary">{{'Discovery.TrendingTab' | translate}}</button>
<button type="button" (click)="upcoming()" [attr.color]="upcomingActive ? 'accent' : 'primary'"
[ngClass]="upcomingActive ? 'mat-accent' : 'mat-primary'" mat-raised-button class="btn grow"
color="primary">{{'Discovery.UpcomingTab' | translate}}</button>
</div>
</div>
<div *ngIf="loadingFlag" class="row justify-content-md-center top-spacing loading-spinner">
<mat-spinner [color]="'accent'"></mat-spinner>
</div>
<div *ngIf="discoverResults" class="row full-height discoverResults"
infiniteScroll
[fromRoot]="true"
[infiniteScrollDistance]="1"
(scrolled)="onScroll()">
<div class="col-xl-2 col-lg-3 col-md-3 col-6 col-sm-4 small-padding" *ngFor="let result of discoverResults">
<discover-card [result]="result"></discover-card>
</div>
</div>
</div>

@ -16,4 +16,8 @@
.loading-spinner {
margin: 10%;
}
}
#scroller {
height: 100vh;
overflow: scroll;
}
Loading…
Cancel
Save