Started on a infinite scroll on the discover page

pull/3895/head
tidusjar 5 years ago
parent aedc94686b
commit ea54dfa3bf

@ -15,6 +15,7 @@ namespace Ombi.Core.Engine.Interfaces
Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies();
Task<MovieCollectionsViewModel> GetCollection(int collectionId, string langCode = null);
Task<int> GetTvDbId(int theMovieDbId);
Task<IEnumerable<SearchMovieViewModel>> PopularMovies(int currentlyLoaded, int toLoad);
int ResultLimit { get; set; }
}
}

@ -98,6 +98,31 @@ namespace Ombi.Core.Engine.V2
return null;
}
/// <summary>
/// Gets popular movies by paging
/// </summary>
/// <returns></returns>
public async Task<IEnumerable<SearchMovieViewModel>> PopularMovies(int currentlyLoaded, int toLoad)
{
var langCode = await DefaultLanguageCode(null);
// Pages of 20
if(toLoad > 20)
{
throw new ApplicationException("Please load less than 20 items at a time due to a API limit");
}
var result = await MovieApi.PopularMovies(langCode);
if (result != null)
{
return await TransformMovieResultsToResponse(result.Shuffle().Take(ResultLimit)); // Take x to stop us overloading the API
}
return null;
}
/// <summary>
/// Gets top rated movies.
/// </summary>

@ -25,5 +25,6 @@ namespace Ombi.Api.TheMovieDb
Task<FullMovieInfo> GetFullMovieInfo(int movieId, string langCode);
Task<TheMovieDbContainer<DiscoverMovies>> DiscoverMovies(string langCode, int keywordId);
Task<Collections> GetCollection(string langCode, int collectionId);
Task<List<MovieSearchResult>> PopularMovies(string langageCode, int page);
}
}

@ -166,6 +166,17 @@ namespace Ombi.Api.TheMovieDb
return Mapper.Map<List<MovieSearchResult>>(result.results);
}
public async Task<List<MovieSearchResult>> PopularMovies(string langageCode, int page)
{
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());
AddRetry(request);
var result = await Api.Request<TheMovieDbContainer<SearchResult>>(request);
return Mapper.Map<List<MovieSearchResult>>(result.results);
}
public async Task<List<MovieSearchResult>> TopRated(string langageCode)
{
var request = new Request($"movie/top_rated", BaseUri, HttpMethod.Get);

@ -48,7 +48,7 @@
"ngx-bootstrap": "^3.1.4",
"ngx-clipboard": "^11.1.1",
"ngx-editor": "^4.1.0",
"ngx-infinite-scroll": "^6.0.1",
"ngx-infinite-scroll": "^7.1.0",
"ngx-moment": "^3.0.1",
"ngx-order-pipe": "^2.0.1",
"ngx-page-scroll": "^5.0.1",

@ -1,5 +1,6 @@
<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'"
@ -18,9 +19,16 @@
<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">
<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>
</div>
</div>

@ -19,8 +19,8 @@ import { trigger, transition, style, animate } from "@angular/animations";
export class DiscoverComponent implements OnInit {
public discoverResults: IDiscoverCardResult[] = [];
private movies: ISearchMovieResult[];
private tvShows: ISearchTvResult[];
public movies: ISearchMovieResult[];
public tvShows: ISearchTvResult[];
public defaultTvPoster: string;
@ -30,6 +30,8 @@ export class DiscoverComponent implements OnInit {
public loadingFlag: boolean;
private contentLoaded: number;
constructor(private searchService: SearchV2Service) { }
public async ngOnInit() {
@ -38,13 +40,25 @@ export class DiscoverComponent implements OnInit {
this.movies = await this.searchService.popularMovies().toPromise();
this.tvShows = await this.searchService.popularTv().toPromise();
this.contentLoaded = 12;
this.createModel();
this.createModel(true);
}
public async onScroll() {
console.log("SCROLLED!")
this.movies = await this.searchService.popularMoviesByPage(this.contentLoaded, 12).toPromise();
this.tvShows = [];
this.contentLoaded+=12;
this.createModel(false);
}
public async popular() {
this.clear();
this.contentLoaded = 12;
this.loading()
this.popularActive = true;
this.trendingActive = false;
@ -53,11 +67,13 @@ export class DiscoverComponent implements OnInit {
this.tvShows = await this.searchService.popularTv().toPromise();
this.createModel();
this.createModel(true);
}
public async trending() {
this.clear();
this.contentLoaded = 12;
this.loading()
this.popularActive = false;
this.trendingActive = true;
@ -65,11 +81,12 @@ export class DiscoverComponent implements OnInit {
this.movies = await this.searchService.nowPlayingMovies().toPromise();
this.tvShows = await this.searchService.trendingTv().toPromise();
this.createModel();
this.createModel(true);
}
public async upcoming() {
this.clear();
this.contentLoaded = 12;
this.loading()
this.popularActive = false;
this.trendingActive = false;
@ -77,10 +94,10 @@ export class DiscoverComponent implements OnInit {
this.movies = await this.searchService.upcomingMovies().toPromise();
this.tvShows = await this.searchService.anticipatedTv().toPromise();
this.createModel();
this.createModel(true);
}
private createModel() {
private createModel(shuffle: boolean) {
this.finishLoading();
this.movies.forEach(m => {
this.discoverResults.push({
@ -110,8 +127,9 @@ export class DiscoverComponent implements OnInit {
approved: m.approved
});
});
this.shuffle(this.discoverResults);
if(shuffle) {
this.shuffle(this.discoverResults);
}
}
private shuffle(discover: IDiscoverCardResult[]) : IDiscoverCardResult[] {

@ -1,5 +1,6 @@
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
import { SearchService, RequestService } from "../services";
@ -21,6 +22,7 @@ const routes: Routes = [
RouterModule.forChild(routes),
SharedModule,
PipeModule,
InfiniteScrollModule,
],
declarations: [
DiscoverComponent,

@ -34,6 +34,10 @@ export class SearchV2Service extends ServiceHelpers {
return this.http.get<ISearchMovieResult[]>(`${this.url}/Movie/Popular`);
}
public popularMoviesByPage(currentlyLoaded: number, toLoad: number): Observable<ISearchMovieResult[]> {
return this.http.get<ISearchMovieResult[]>(`${this.url}/Movie/Popular/${currentlyLoaded}/${toLoad}`);
}
public upcomingMovies(): Observable<ISearchMovieResult[]> {
return this.http.get<ISearchMovieResult[]>(`${this.url}/Movie/upcoming`);
}

@ -567,10 +567,6 @@ ansi-colors@^3.0.0:
version "3.2.3"
resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813"
ansi-escapes@^1.1.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
ansi-escapes@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30"
@ -815,14 +811,6 @@ babel-messages@^6.23.0:
dependencies:
babel-runtime "^6.22.0"
babel-polyfill@6.23.0:
version "6.23.0"
resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d"
dependencies:
babel-runtime "^6.22.0"
core-js "^2.4.0"
regenerator-runtime "^0.10.0"
babel-runtime@^6.22.0, babel-runtime@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
@ -1200,7 +1188,7 @@ caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
chalk@1.1.3, chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
chalk@^1.1.1, chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
dependencies:
@ -1218,10 +1206,6 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1, chalk@^2.4
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chardet@^0.4.0:
version "0.4.2"
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2"
chardet@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
@ -2216,14 +2200,6 @@ extend@^3.0.0, extend@~3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa"
external-editor@^2.0.1:
version "2.2.0"
resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5"
dependencies:
chardet "^0.4.0"
iconv-lite "^0.4.17"
tmp "^0.0.33"
external-editor@^3.0.0:
version "3.0.3"
resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.0.3.tgz#5866db29a97826dbe4bf3afd24070ead9ea43a27"
@ -2857,7 +2833,7 @@ iconv-lite@0.4.23:
dependencies:
safer-buffer ">= 2.1.2 < 3"
iconv-lite@^0.4.17, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
dependencies:
@ -2945,24 +2921,6 @@ ini@1.3.5, ini@^1.3.4, ini@~1.3.0:
version "1.3.5"
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
inquirer@3.0.6:
version "3.0.6"
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.0.6.tgz#e04aaa9d05b7a3cb9b0f407d04375f0447190347"
dependencies:
ansi-escapes "^1.1.0"
chalk "^1.0.0"
cli-cursor "^2.1.0"
cli-width "^2.0.0"
external-editor "^2.0.1"
figures "^2.0.0"
lodash "^4.3.0"
mute-stream "0.0.7"
run-async "^2.2.0"
rx "^4.1.0"
string-width "^2.0.0"
strip-ansi "^3.0.0"
through "^2.3.6"
inquirer@6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.2.0.tgz#51adcd776f661369dc1e894859c2560a224abdd8"
@ -3573,7 +3531,7 @@ lodash.tail@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.tail/-/lodash.tail-4.1.1.tgz#d2333a36d9e7717c8ad2f7cacafec7c32b444664"
lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0, lodash@~4.17.10:
lodash@^4.0.0, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@~4.17.10:
version "4.17.11"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
@ -3832,7 +3790,7 @@ minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
minimist@1.2.0, minimist@^1.1.3, minimist@^1.2.0:
minimist@^1.1.3, minimist@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
@ -4009,11 +3967,12 @@ ngx-editor@^4.1.0:
dependencies:
tslib "^1.9.0"
ngx-infinite-scroll@^6.0.1:
version "6.0.1"
resolved "https://registry.yarnpkg.com/ngx-infinite-scroll/-/ngx-infinite-scroll-6.0.1.tgz#571e54860ce32839451569bcf6e7a63cfae327bd"
ngx-infinite-scroll@^7.1.0:
version "7.1.0"
resolved "https://registry.yarnpkg.com/ngx-infinite-scroll/-/ngx-infinite-scroll-7.1.0.tgz#87dd5e0c596cd4795d2a487f7e30a0eabbb5e442"
integrity sha512-uytsKxUgGcPQjYMcf7FObcducQHkEsilPHZGJ3AMhOM4mtxP+YramnXXdyp2thEcuMgfNr9fBJjYnP0YcJciEQ==
dependencies:
opencollective "^1.0.3"
opencollective-postinstall "^2.0.2"
ngx-moment@^3.0.1:
version "3.3.0"
@ -4047,13 +4006,6 @@ node-fetch-npm@^2.0.2:
json-parse-better-errors "^1.0.0"
safe-buffer "^5.1.1"
node-fetch@1.6.3:
version "1.6.3"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04"
dependencies:
encoding "^0.1.11"
is-stream "^1.0.1"
node-fetch@^1.0.1:
version "1.7.3"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef"
@ -4351,23 +4303,10 @@ onetime@^2.0.0:
dependencies:
mimic-fn "^1.0.0"
opencollective@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/opencollective/-/opencollective-1.0.3.tgz#aee6372bc28144583690c3ca8daecfc120dd0ef1"
dependencies:
babel-polyfill "6.23.0"
chalk "1.1.3"
inquirer "3.0.6"
minimist "1.2.0"
node-fetch "1.6.3"
opn "4.0.2"
opn@4.0.2:
version "4.0.2"
resolved "https://registry.yarnpkg.com/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95"
dependencies:
object-assign "^4.0.1"
pinkie-promise "^2.0.0"
opencollective-postinstall@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89"
integrity sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==
opn@5.3.0:
version "5.3.0"
@ -5074,10 +5013,6 @@ regenerate@^1.2.1:
version "1.4.0"
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
regenerator-runtime@^0.10.0:
version "0.10.5"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658"
regenerator-runtime@^0.11.0:
version "0.11.1"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
@ -5243,10 +5178,6 @@ run-queue@^1.0.0, run-queue@^1.0.3:
dependencies:
aproba "^1.1.1"
rx@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782"
rxjs@6.3.3, rxjs@^6.0.0, rxjs@^6.1.0:
version "6.3.3"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.3.3.tgz#3c6a7fa420e844a81390fb1158a9ec614f4bad55"

@ -107,7 +107,7 @@ namespace Ombi.Controllers.V2
return await _movieEngineV2.SimilarMovies(model.TheMovieDbId, model.LanguageCode);
}
/// <summary>
/// Returns Popular Movies
/// </summary>
@ -121,6 +121,20 @@ namespace Ombi.Controllers.V2
return await _movieEngineV2.PopularMovies();
}
/// <summary>
/// Returns Popular Movies using paging
/// </summary>
/// <remarks>We use TheMovieDb as the Movie Provider</remarks>
/// <returns></returns>
[HttpGet("movie/popular/{currentPostion}/{amountToLoad}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesDefaultResponseType]
public async Task<IEnumerable<SearchMovieViewModel>> Popular(int currentPosition, int amountToLoad)
{
return await _movieEngineV2.PopularMovies(currentPosition, amountToLoad);
}
/// <summary>
/// Returns Now Playing Movies
/// </summary>

Loading…
Cancel
Save