diff --git a/src/Ombi/ClientApp/package.json b/src/Ombi/ClientApp/package.json index 988d20daf..82c946672 100644 --- a/src/Ombi/ClientApp/package.json +++ b/src/Ombi/ClientApp/package.json @@ -42,6 +42,7 @@ "font-awesome": "^4.7.0", "fullcalendar": "^4.0.0-alpha.4", "jquery": "3.3.1", + "lodash": "^4.17.20", "moment": "^2.23.0", "ng2-cookies": "^1.0.12", "ngx-clipboard": "^12.1.0", diff --git a/src/Ombi/ClientApp/src/app/app.module.ts b/src/Ombi/ClientApp/src/app/app.module.ts index 85d6f7a70..cfaf783cf 100644 --- a/src/Ombi/ClientApp/src/app/app.module.ts +++ b/src/Ombi/ClientApp/src/app/app.module.ts @@ -67,6 +67,7 @@ import { SignalRNotificationService } from "./services/signlarnotification.servi import { MatMenuModule } from "@angular/material/menu"; import { RemainingRequestsComponent } from "./shared/remaining-requests/remaining-requests.component"; import { UnauthorizedInterceptor } from "./auth/unauthorized.interceptor"; +import { FilterService } from "./discover/services/filter-service"; const routes: Routes = [ { path: "*", component: PageNotFoundComponent }, @@ -193,6 +194,7 @@ export function JwtTokenGetter() { MessageService, StorageService, RequestService, + FilterService, SignalRNotificationService, { provide: APP_BASE_HREF, diff --git a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html index faec960b1..57581bb32 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html +++ b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html @@ -1,5 +1,5 @@ -
- +
+
{{getAvailbilityStatus()}}
diff --git a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.scss b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.scss index 75bc29d72..5f232a48e 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.scss +++ b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.scss @@ -73,7 +73,6 @@ small { .box { position: relative; max-width: 600px; - box-shadow: 0 0 15px rgba(0,0,0,.1); } /* common */ diff --git a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts index ec3dd9986..c923de72b 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts @@ -16,6 +16,7 @@ export class DiscoverCardComponent implements OnInit { @Input() public result: IDiscoverCardResult; public RequestType = RequestType; + public hide: boolean; constructor(private searchService: SearchV2Service, private dialog: MatDialog) { } @@ -33,7 +34,15 @@ export class DiscoverCardComponent implements OnInit { } public async getExtraTvInfo() { - var result = await this.searchService.getTvInfo(this.result.id); + if (this.result.tvMovieDb) { + var result = await this.searchService.getTvInfoWithMovieDbId(this.result.id); + } else { + var result = await this.searchService.getTvInfo(this.result.id); + } + if(result.status === "404") { + this.hide = true; + return; + } this.setTvDefaults(result); this.updateTvItem(result); @@ -80,14 +89,16 @@ export class DiscoverCardComponent implements OnInit { this.result.requested = updated.requested; this.result.requested = updated.requestProcessing; this.result.rating = updated.voteAverage; + this.result.overview = updated.overview; + this.result.imdbid = updated.imdbId; } private setTvDefaults(x: ISearchTvResultV2) { - if (!x.imdbId) { - x.imdbId = "https://www.tvmaze.com/shows/" + x.seriesId; - } else { + if (x.imdbId) { x.imdbId = "http://www.imdb.com/title/" + x.imdbId + "/"; + } else { + x.imdbId = "https://www.tvmaze.com/shows/" + x.seriesId; } } @@ -98,6 +109,8 @@ export class DiscoverCardComponent implements OnInit { this.result.posterPath = updated.banner; this.result.requested = updated.requested; this.result.url = updated.imdbId; + this.result.overview = updated.overview; + this.result.approved = updated.approved; } } diff --git a/src/Ombi/ClientApp/src/app/discover/components/index.ts b/src/Ombi/ClientApp/src/app/discover/components/index.ts index e65e48bd3..11ce07d50 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/index.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/index.ts @@ -8,6 +8,7 @@ import { AuthGuard } from "../../auth/auth.guard"; import { SearchService, RequestService } from "../../services"; import { MatDialog } from "@angular/material/dialog"; import { DiscoverGridComponent } from "./grid/discover-grid.component"; +import { DiscoverSearchResultsComponent } from "./search-results/search-results.component"; export const components: any[] = [ @@ -17,6 +18,7 @@ export const components: any[] = [ DiscoverCollectionsComponent, DiscoverActorComponent, DiscoverGridComponent, + DiscoverSearchResultsComponent, ]; @@ -33,5 +35,6 @@ export const providers: any[] = [ export const routes: Routes = [ { path: "", component: DiscoverComponent, canActivate: [AuthGuard] }, { path: "collection/:collectionId", component: DiscoverCollectionsComponent, canActivate: [AuthGuard] }, - { path: "actor/:actorId", component: DiscoverActorComponent, canActivate: [AuthGuard] } + { path: "actor/:actorId", component: DiscoverActorComponent, canActivate: [AuthGuard] }, + { path: ":searchTerm", component: DiscoverSearchResultsComponent, canActivate: [AuthGuard] }, ]; \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.html b/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.html new file mode 100644 index 000000000..e6c372b57 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.html @@ -0,0 +1,10 @@ +
+
+ +
+
+
+ +
+
+
\ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.scss b/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.scss new file mode 100644 index 000000000..728ff23c5 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.scss @@ -0,0 +1,19 @@ +.full-height { + height: 100%; +} + + +.small-middle-container{ + margin: auto; + width: 80%; +} + +.small-padding { + padding-left: 20px; + padding-right: 20px; + margin-bottom: 28px; +} + +.loading-spinner { + margin: 10%; +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.ts b/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.ts new file mode 100644 index 000000000..b43581af8 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.ts @@ -0,0 +1,143 @@ +import { Component, OnInit } from "@angular/core"; +import { ActivatedRoute } from "@angular/router"; +import { SearchV2Service } from "../../../services"; +import { IDiscoverCardResult } from "../../interfaces"; +import { IMultiSearchResult, RequestType } from "../../../interfaces"; +import { FilterService } from "../../services/filter-service"; +import { SearchFilter } from "../../../my-nav/SearchFilter"; +import { StorageService } from "../../../shared/storage/storage-service"; + +import { isEqual } from "lodash"; + +@Component({ + templateUrl: "./search-results.component.html", + styleUrls: ["./search-results.component.scss"], +}) +export class DiscoverSearchResultsComponent implements OnInit { + + public loadingFlag: boolean; + public searchTerm: string; + public results: IMultiSearchResult[]; + + public discoverResults: IDiscoverCardResult[] = []; + + public filter: SearchFilter; + + constructor(private searchService: SearchV2Service, + private route: ActivatedRoute, + private filterService: FilterService, + private store: StorageService) { + this.route.params.subscribe((params: any) => { + this.searchTerm = params.searchTerm; + this.clear(); + this.init(); + }); + } + + public async ngOnInit() { + this.loadingFlag = true; + + this.filterService.onFilterChange.subscribe(async x => { + if (!isEqual(this.filter, x)) { + this.filter = { ...x }; + await this.search(); + } + }); + } + + public async init() { + var filter = this.store.get("searchFilter"); + if (filter) { + this.filter = Object.assign(new SearchFilter(), JSON.parse(filter)); + } + this.loading(); + await this.search(); + } + + public createInitalModel() { + this.finishLoading(); + this.results.forEach(m => { + + let mediaType = RequestType.movie; + if (m.mediaType == "movie") { + mediaType = RequestType.movie; + } else if (m.mediaType == "tv") { + mediaType = RequestType.tvShow; + } else if (m.mediaType == "Artist") { + mediaType = RequestType.album; + } + + this.discoverResults.push({ + posterPath: `https://image.tmdb.org/t/p/w300/${m.poster}`, + requested: false, + title: m.title, + type: mediaType, + id: +m.id, + url: "", + rating: 0, + overview: "", + approved: false, + imdbid: "", + denied: false, + background: "", + available: false, + tvMovieDb: mediaType === RequestType.tvShow ? true : false + }); + + // switch (mediaType) { + // case RequestType.movie: + // this.searchService.getFullMovieDetails(+m.id) + // .subscribe(x => { + // const index = this.discoverResults.findIndex((obj => obj.id === +m.id)); + // this.discoverResults[index].available = x.available; + // this.discoverResults[index].requested = x.requested; + // this.discoverResults[index].requested = x.requested; + // this.discoverResults[index].requested = x.requested; + // this.discoverResults[index].requested = x.requested; + // this.discoverResults[index].requested = x.requested; + // }); + // } + }); + } + + // private createModel() { + // this.finishLoading(); + // this.collection.collection.forEach(m => { + // this.discoverResults.push({ + // available: m.available, + // posterPath: `https://image.tmdb.org/t/p/w300/${m.posterPath}`, + // requested: m.requested, + // title: m.title, + // type: RequestType.movie, + // id: m.id, + // url: `http://www.imdb.com/title/${m.imdbId}/`, + // rating: 0, + // overview: m.overview, + // approved: m.approved, + // imdbid: m.imdbId, + // denied:false, + // background: "" + // }); + // }); + // } + + private loading() { + this.loadingFlag = true; + } + + private finishLoading() { + this.loadingFlag = false; + } + + private clear() { + this.results = []; + this.discoverResults = []; + } + + private async search() { + this.clear(); + this.results = await this.searchService + .multiSearch(this.searchTerm, this.filter).toPromise(); + this.createInitalModel(); + } +} diff --git a/src/Ombi/ClientApp/src/app/discover/interfaces.ts b/src/Ombi/ClientApp/src/app/discover/interfaces.ts index 8a3276a2d..bac0faafc 100644 --- a/src/Ombi/ClientApp/src/app/discover/interfaces.ts +++ b/src/Ombi/ClientApp/src/app/discover/interfaces.ts @@ -14,6 +14,8 @@ export interface IDiscoverCardResult { overview: string; imdbid: string; background: string|any; + + tvMovieDb?: boolean; } export enum DiscoverOption { diff --git a/src/Ombi/ClientApp/src/app/discover/services/filter-service.ts b/src/Ombi/ClientApp/src/app/discover/services/filter-service.ts new file mode 100644 index 000000000..bceeb05d6 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/discover/services/filter-service.ts @@ -0,0 +1,14 @@ +import { EventEmitter, Injectable, Output } from "@angular/core"; +import { SearchFilter } from "../../my-nav/SearchFilter"; + +@Injectable() +export class FilterService { + + @Output() public onFilterChange = new EventEmitter(); + public filter: SearchFilter; + + public changeFilter(filter: SearchFilter) { + this.filter = filter; + this.onFilterChange.emit(this.filter); + } +} diff --git a/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts index 7ffb79eee..bb02b0985 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts +++ b/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts @@ -68,10 +68,7 @@ export class MovieDetailsComponent implements OnInit { this.hasRequest = true; this.movieRequest = await this.requestService.getMovieRequest(this.movie.requestId); } - this.imageService.getMovieBanner(this.theMovidDbId.toString()).subscribe(x => { - this.movie.background = this.sanitizer.bypassSecurityTrustStyle - ("url(" + x + ")"); - }); + this.loadBanner(); }); } else { this.searchService.getFullMovieDetails(this.theMovidDbId).subscribe(async x => { @@ -81,10 +78,7 @@ export class MovieDetailsComponent implements OnInit { this.hasRequest = true; this.movieRequest = await this.requestService.getMovieRequest(this.movie.requestId); } - this.imageService.getMovieBanner(this.theMovidDbId.toString()).subscribe(x => { - this.movie.background = this.sanitizer.bypassSecurityTrustStyle - ("url(" + x + ")"); - }); + this.loadBanner(); }); } } @@ -178,4 +172,16 @@ export class MovieDetailsComponent implements OnInit { } }); } + + private loadBanner() { + this.imageService.getMovieBanner(this.theMovidDbId.toString()).subscribe(x => { + if (!this.movie.backdropPath) { + this.movie.background = this.sanitizer.bypassSecurityTrustStyle + ("url(" + x + ")"); + } else { + this.movie.background = this.sanitizer.bypassSecurityTrustStyle + ("url(https://image.tmdb.org/t/p/original/" + this.movie.backdropPath + ")"); + } + }); + } } diff --git a/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.html b/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.html index 849fc9f21..4a212ef8e 100644 --- a/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.html +++ b/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.html @@ -76,7 +76,7 @@
- +
diff --git a/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.ts b/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.ts index 356047885..cafef32a8 100644 --- a/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.ts +++ b/src/Ombi/ClientApp/src/app/my-nav/my-nav.component.ts @@ -9,6 +9,7 @@ import { MatSlideToggleChange } from '@angular/material/slide-toggle'; import { SearchFilter } from './SearchFilter'; import { Md5 } from 'ts-md5/dist/md5'; import { RequestType } from '../interfaces'; +import { FilterService } from '../discover/services/filter-service'; export enum SearchFilterType { Movie = 1, @@ -48,7 +49,8 @@ export class MyNavComponent implements OnInit { constructor(private breakpointObserver: BreakpointObserver, private settingsService: SettingsService, - private store: StorageService) { + private store: StorageService, + private filterService: FilterService) { } public async ngOnInit() { @@ -76,6 +78,7 @@ export class MyNavComponent implements OnInit { var filter = this.store.get("searchFilter"); if (filter) { this.searchFilter = Object.assign(new SearchFilter(), JSON.parse(filter)); + this.filterService.changeFilter(this.searchFilter); } this.navItems = [ { name: "NavigationBar.Discover", icon: "find_replace", link: "/discover", requiresAdmin: false, enabled: true, faIcon: null }, @@ -124,6 +127,7 @@ export class MyNavComponent implements OnInit { this.searchFilter.people = event.checked; break; } + this.filterService.changeFilter(this.searchFilter); this.store.save("searchFilter", JSON.stringify(this.searchFilter)); } diff --git a/src/Ombi/ClientApp/src/app/my-nav/nav-search.component.ts b/src/Ombi/ClientApp/src/app/my-nav/nav-search.component.ts index 9467f9544..4474aee4e 100644 --- a/src/Ombi/ClientApp/src/app/my-nav/nav-search.component.ts +++ b/src/Ombi/ClientApp/src/app/my-nav/nav-search.component.ts @@ -7,12 +7,12 @@ import { } from "rxjs/operators"; import { empty} from "rxjs"; -import { SearchV2Service } from "../services/searchV2.service"; import { IMultiSearchResult } from "../interfaces"; import { Router } from "@angular/router"; import { FormGroup, FormBuilder } from "@angular/forms"; import { MatAutocompleteSelectedEvent } from "@angular/material/autocomplete"; import { SearchFilter } from "./SearchFilter"; +import { FilterService } from "../discover/services/filter-service"; @Component({ selector: "app-nav-search", @@ -20,7 +20,6 @@ import { SearchFilter } from "./SearchFilter"; styleUrls: ["./nav-search.component.scss"], }) export class NavSearchComponent implements OnInit { - @Input() public filter: SearchFilter; public selectedItem: string; public results: IMultiSearchResult[]; public searching = false; @@ -28,7 +27,6 @@ export class NavSearchComponent implements OnInit { public searchForm: FormGroup; constructor( - private searchService: SearchV2Service, private router: Router, private fb: FormBuilder ) {} @@ -41,13 +39,14 @@ export class NavSearchComponent implements OnInit { this.searchForm .get("input") .valueChanges.pipe( - debounceTime(600), + debounceTime(1300), tap(() => (this.searching = true)), switchMap((value: string) => { if (value) { - return this.searchService - .multiSearch(value, this.filter) - .pipe(finalize(() => (this.searching = false))); + this.router.navigate([`discover`, value]); + // return this.searchService + // .multiSearch(value, this.filter) + // .pipe(finalize(() => (this.searching = false))); } return empty().pipe(finalize(() => (this.searching = false))); }) diff --git a/src/Ombi/ClientApp/yarn.lock b/src/Ombi/ClientApp/yarn.lock index d2dc99e84..8c55c594b 100644 --- a/src/Ombi/ClientApp/yarn.lock +++ b/src/Ombi/ClientApp/yarn.lock @@ -5242,6 +5242,11 @@ lodash@^4.17.10, lodash@^4.17.11: version "4.17.11" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" +lodash@^4.17.20: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== + log-symbols@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4"