!minor Poc'ing a new search page

pull/1614/head
Jamie.Rees 7 years ago
parent f8054317ab
commit 989be6df6c

@ -27,3 +27,7 @@
requestProcessing: boolean;
processed: boolean;
}
export interface ISearchMovieResultContainer {
movies: ISearchMovieResult[];
}

@ -0,0 +1,149 @@
<!-- Movie tab -->
<div role="tabpanel" class="tab-pane active" id="MoviesTab">
<div class="input-group">
<input id="search" type="text" class="form-control form-control-custom form-control-search form-control-withbuttons" (keyup)="search($event)">
<div class="input-group-addon right-radius">
<div class="btn-group">
<a href="#" class="btn btn-sm btn-primary-outline dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
Suggestions
<i class="fa fa-chevron-down"></i>
</a>
<ul class="dropdown-menu">
<li>
<a (click)="popularMovies()">Popular Movies</a>
</li>
<li>
<a (click)="upcomingMovies()">Upcoming Movies</a>
</li>
<li>
<a (click)="topRatedMovies()">Top Rated Movies</a>
</li>
<li>
<a (click)="nowPlayingMovies()">Now Playing Movies</a>
</li>
</ul>
</div>
<i id="movieSearchButton" class="fa fa-search"></i>
</div>
</div>
<br />
<br />
<!-- Movie content -->
<div id="movieList">
<div *ngIf="searchApplied && movieResults?.length <= 0" class='no-search-results'>
<i class='fa fa-film no-search-results-icon'></i>
<div class='no-search-results-text'>Sorry, we didn't find any results!</div>
</div>
<!--NEW-->
<div *ngFor="let grid of movieResultGrid; let i = index">
<div class="row">
<div *ngFor="let r of grid.movies">
<div class="col-md-3">
<img *ngIf="r.posterPath" class="img-responsive poster" src="https://image.tmdb.org/t/p/w150/{{r.posterPath}}"
alt="poster">
</div>
</div>
</div>
</div>
<!--END NEW-->
<br/>
<br/>
<br/>
<hr/>
<div *ngFor="let result of movieResults">
<div class="row">
<div id="imgDiv" class="col-sm-2">
<img *ngIf="result.posterPath" class="img-responsive poster" src="https://image.tmdb.org/t/p/w150/{{result.posterPath}}"
alt="poster">
</div>
<div class="col-sm-8">
<div>
<a href="https://www.themoviedb.org/movie/{{result.id}}/" target="_blank">
<h4>{{result.title}} ({{result.releaseDate | date: 'yyyy'}})</h4>
</a>
<span *ngIf="result.releaseDate" class="label label-info" target="_blank">Release Date: {{result.releaseDate | date: 'dd/MM/yyyy'}}</span>
<a *ngIf="result.homepage" href="{{result.homepage}}" target="_blank">
<span class="label label-info">HomePage</span>
</a>
<a *ngIf="result.trailer" href="{{result.trailer}}" target="_blank">
<span class="label label-info">Trailer</span>
</a>
<span *ngIf="result.quality" class="label label-success">{{result.quality}}p</span>
<ng-template [ngIf]="result.available">
<span class="label label-success">Available</span>
</ng-template>
<ng-template [ngIf]="result.approved && !result.available">
<span class="label label-info">Processing Request</span>
</ng-template>
<ng-template [ngIf]="result.requested && !result.approved && !result.available">
<span class="label label-warning">Pending Approval</span>
</ng-template>
<ng-template [ngIf]="!result.requested && !result.available && !result.approved">
<span class="label label-danger">Not Requested</span>
</ng-template>
<br/>
<br/>
</div>
<p style="font-size: 0.9rem !important">{{result.overview}}</p>
</div>
<div class="col-sm-2">
<div *ngIf="result.available">
<button style="text-align: right" class="btn btn-success-outline disabled" disabled>
<i class="fa fa-check"></i> Available</button>
<div *ngIf="result.plexUrl">
<br/>
<br/>
<a style="text-align: right" class="btn btn-sm btn-primary-outline" href="{{result.plexUrl}}" target="_blank">
<i class="fa fa-eye"></i> View In Plex</a>
</div>
</div>
<div *ngIf="!result.available">
<div *ngIf="result.requested || result.approved; then requestedBtn else notRequestedBtn"></div>
<ng-template #requestedBtn>
<button style="text-align: right" class="btn btn-primary-outline disabled" [disabled]>
<i class="fa fa-check"></i> Requested</button>
</ng-template>
<ng-template #notRequestedBtn>
<button id="{{result.id}}" style="text-align: right" class="btn btn-primary-outline" (click)="request(result)">
<i *ngIf="result.requestProcessing" class="fa fa-circle-o-notch fa-spin fa-fw"></i>
<i *ngIf="!result.requestProcessing && !result.processed" class="fa fa-plus"></i>
<i *ngIf="result.processed && !result.requestProcessing" class="fa fa-check"></i>Request</button>
</ng-template>
</div>
<br/>
<div *ngIf="result.available">
<a *ngIf="result.plexUrl" style="text-align: right" class="btn btn-sm btn-success-outline" href="{{result.plexUrl}}" target="_blank">
<i class="fa fa-eye"></i> View On Plex</a>
</div>
</div>
</div>
<hr/>
</div>
</div>
</div>

@ -0,0 +1,167 @@
import { Component, OnInit } from "@angular/core";
import "rxjs/add/operator/debounceTime";
import "rxjs/add/operator/distinctUntilChanged";
import "rxjs/add/operator/map";
import { Subject } from "rxjs/Subject";
import { AuthService } from "../auth/auth.service";
import { NotificationService, RequestService, SearchService } from "../services";
import { IRequestEngineResult, ISearchMovieResult, ISearchMovieResultContainer } from "../interfaces";
@Component({
selector: "movie-search-grid",
templateUrl: "./moviesearchgrid.component.html",
})
export class MovieSearchGridComponent implements OnInit {
public searchText: string;
public searchChanged: Subject<string> = new Subject<string>();
public movieResults: ISearchMovieResult[];
public movieResultGrid: ISearchMovieResultContainer[] = [];
public result: IRequestEngineResult;
public searchApplied = false;
constructor(private searchService: SearchService, private requestService: RequestService,
private notificationService: NotificationService, private authService: AuthService) {
this.searchChanged
.debounceTime(600) // Wait Xms afterthe last event before emitting last event
.distinctUntilChanged() // only emit if value is different from previous value
.subscribe(x => {
this.searchText = x as string;
if (this.searchText === "") {
this.clearResults();
return;
}
this.searchService.searchMovie(this.searchText)
.subscribe(x => {
this.movieResults = x;
this.searchApplied = true;
// Now let's load some exta info including IMDBId
// This way the search is fast at displaying results.
this.getExtaInfo();
});
});
}
public ngOnInit() {
this.searchText = "";
this.movieResults = [];
this.result = {
message: "",
requestAdded: false,
errorMessage: "",
};
}
public search(text: any) {
this.searchChanged.next(text.target.value);
}
public request(searchResult: ISearchMovieResult) {
searchResult.requested = true;
searchResult.requestProcessing = true;
if (this.authService.hasRole("admin") || this.authService.hasRole("AutoApproveMovie")) {
searchResult.approved = true;
}
try {
this.requestService.requestMovie(searchResult)
.subscribe(x => {
this.result = x;
if (this.result.requestAdded) {
this.notificationService.success("Request Added",
`Request for ${searchResult.title} has been added successfully`);
searchResult.processed = true;
} else {
if (this.result.errorMessage && this.result.message) {
this.notificationService.warning("Request Added", `${this.result.message} - ${this.result.errorMessage}`);
} else {
this.notificationService.warning("Request Added", this.result.message ? this.result.message : this.result.errorMessage);
}
searchResult.requested = false;
searchResult.approved = false;
searchResult.processed = false;
searchResult.requestProcessing = false;
}
});
} catch (e) {
searchResult.processed = false;
searchResult.requestProcessing = false;
this.notificationService.error("Something went wrong", e);
}
}
public popularMovies() {
this.clearResults();
this.searchService.popularMovies()
.subscribe(x => {
this.movieResults = x;
this.processGrid(x);
this.getExtaInfo();
});
}
public nowPlayingMovies() {
this.clearResults();
this.searchService.nowPlayingMovies()
.subscribe(x => {
this.movieResults = x;
this.getExtaInfo();
});
}
public topRatedMovies() {
this.clearResults();
this.searchService.topRatedMovies()
.subscribe(x => {
this.movieResults = x;
this.getExtaInfo();
});
}
public upcomingMovies() {
this.clearResults();
this.searchService.upcomignMovies()
.subscribe(x => {
this.movieResults = x;
this.getExtaInfo();
});
}
private getExtaInfo() {
this.movieResults.forEach((val, index) => {
this.searchService.getMovieInformation(val.id)
.subscribe(m => this.updateItem(val, m));
});
}
private updateItem(key: ISearchMovieResult, updated: ISearchMovieResult) {
const index = this.movieResults.indexOf(key, 0);
if (index > -1) {
this.movieResults[index] = updated;
}
}
private clearResults() {
this.movieResults = [];
this.searchApplied = false;
}
private processGrid(movies: ISearchMovieResult[]) {
let container = <ISearchMovieResultContainer>{ movies: [] };
movies.forEach((movie, i) => {
i++;
if((i % 4) === 0) {
container.movies.push(movie);
this.movieResultGrid.push(container);
container = <ISearchMovieResultContainer>{ movies: [] };
} else {
container.movies.push(movie);
}
});
this.movieResultGrid.push(container);
}
}

@ -6,6 +6,7 @@ import { RouterModule, Routes } from "@angular/router";
import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
import { MovieSearchComponent } from "./moviesearch.component";
import { MovieSearchGridComponent } from "./moviesearchgrid.component";
import { SearchComponent } from "./search.component";
import { SeriesInformationComponent } from "./seriesinformation.component";
import { TvSearchComponent } from "./tvsearch.component";
@ -35,6 +36,7 @@ const routes: Routes = [
MovieSearchComponent,
TvSearchComponent,
SeriesInformationComponent,
MovieSearchGridComponent,
],
exports: [
RouterModule,

Loading…
Cancel
Save