Skip to content

Commit

Permalink
Added the basic advanced search
Browse files Browse the repository at this point in the history
  • Loading branch information
tidusjar committed Jul 28, 2021
1 parent 6ee9606 commit 924a562
Show file tree
Hide file tree
Showing 14 changed files with 185 additions and 72 deletions.
12 changes: 6 additions & 6 deletions src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs
Expand Up @@ -147,15 +147,15 @@ public async Task<IEnumerable<SearchMovieViewModel>> AdvancedSearch(DiscoverMode
{
var langCode = await DefaultLanguageCode(null);

var pages = PaginationHelper.GetNextPages(currentlyLoaded, toLoad, _theMovieDbMaxPageItems);
//var pages = PaginationHelper.GetNextPages(currentlyLoaded, toLoad, _theMovieDbMaxPageItems);

var results = new List<MovieDbSearchResult>();
foreach (var pagesToLoad in pages)
{
//foreach (var pagesToLoad in pages)
//{
var apiResult = await MovieApi.AdvancedSearch(model, cancellationToken);
results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take));
}
return await TransformMovieResultsToResponse(results);
//results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take));
//}
return await TransformMovieResultsToResponse(apiResult);
}

/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion src/Ombi.TheMovieDbApi/TheMovieDbApi.cs
Expand Up @@ -90,7 +90,7 @@ public async Task<List<MovieDbSearchResult>> AdvancedSearch(DiscoverModel model,
{
request.FullUri = request.FullUri.AddQueryParameter("with_watch_providers", string.Join(',', model.WatchProviders));
}
request.FullUri = request.FullUri.AddQueryParameter("sort_by", "popularity.desc");
//request.FullUri = request.FullUri.AddQueryParameter("sort_by", "popularity.desc");

var result = await Api.Request<TheMovieDbContainer<SearchResult>>(request, cancellationToken);
return Mapper.Map<List<MovieDbSearchResult>>(result.results);
Expand Down
17 changes: 9 additions & 8 deletions src/Ombi/ClientApp/src/app/discover/components/index.ts
@@ -1,15 +1,15 @@
import { DiscoverComponent } from "./discover/discover.component";
import { DiscoverCollectionsComponent } from "./collections/discover-collections.component";
import { RadarrService, RequestService, SearchService, SonarrService } from "../../services";

import { AuthGuard } from "../../auth/auth.guard";
import { CarouselListComponent } from "./carousel-list/carousel-list.component";
import { DiscoverActorComponent } from "./actor/discover-actor.component";
import { DiscoverCardComponent } from "./card/discover-card.component";
import { Routes } from "@angular/router";
import { AuthGuard } from "../../auth/auth.guard";
import { SearchService, RequestService, SonarrService, RadarrService } from "../../services";
import { MatDialog } from "@angular/material/dialog";
import { DiscoverCollectionsComponent } from "./collections/discover-collections.component";
import { DiscoverComponent } from "./discover/discover.component";
import { DiscoverSearchResultsComponent } from "./search-results/search-results.component";
import { CarouselListComponent } from "./carousel-list/carousel-list.component";
import { MatDialog } from "@angular/material/dialog";
import { RequestServiceV2 } from "../../services/requestV2.service";

import { Routes } from "@angular/router";

export const components: any[] = [
DiscoverComponent,
Expand All @@ -34,4 +34,5 @@ export const routes: Routes = [
{ path: "collection/:collectionId", component: DiscoverCollectionsComponent, canActivate: [AuthGuard] },
{ path: "actor/:actorId", component: DiscoverActorComponent, canActivate: [AuthGuard] },
{ path: ":searchTerm", component: DiscoverSearchResultsComponent, canActivate: [AuthGuard] },
{ path: "advanced/search", component: DiscoverSearchResultsComponent, canActivate: [AuthGuard] },
];
@@ -1,14 +1,15 @@
import { ActivatedRoute, NavigationEnd, Router } from "@angular/router";
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 { IMultiSearchResult, ISearchMovieResult, RequestType } from "../../../interfaces";

import { AdvancedSearchDialogDataService } from "../../../shared/advanced-search-dialog/advanced-search-dialog-data.service";
import { AuthService } from "../../../auth/auth.service";
import { FilterService } from "../../services/filter-service";
import { IDiscoverCardResult } from "../../interfaces";
import { SearchFilter } from "../../../my-nav/SearchFilter";
import { SearchV2Service } from "../../../services";
import { StorageService } from "../../../shared/storage/storage-service";

import { isEqual } from "lodash";
import { AuthService } from "../../../auth/auth.service";

@Component({
templateUrl: "./search-results.component.html",
Expand All @@ -25,22 +26,41 @@ export class DiscoverSearchResultsComponent implements OnInit {

public filter: SearchFilter;

private isAdvancedSearch: boolean;

constructor(private searchService: SearchV2Service,
private route: ActivatedRoute,
private filterService: FilterService,
private router: Router,
private advancedDataService: AdvancedSearchDialogDataService,
private store: StorageService,
private authService: AuthService) {
this.route.params.subscribe((params: any) => {
this.isAdvancedSearch = this.router.url === '/discover/advanced/search';
if (this.isAdvancedSearch) {
this.loadAdvancedData();
return;
}
this.searchTerm = params.searchTerm;
this.clear();
this.init();
});

this.advancedDataService.onDataChange.subscribe(() => {
this.clear();
this.loadAdvancedData();
});

}

public async ngOnInit() {
this.loadingFlag = true;
this.isAdmin = this.authService.isAdmin();

if (this.advancedDataService) {
return;
}
this.loadingFlag = true;

this.filterService.onFilterChange.subscribe(async x => {
if (!isEqual(this.filter, x)) {
this.filter = { ...x };
Expand Down Expand Up @@ -115,6 +135,48 @@ export class DiscoverSearchResultsComponent implements OnInit {
this.discoverResults = [];
}

private loadAdvancedData() {
const advancedData = this.advancedDataService.getData();
this.mapAdvancedData(advancedData);
return;
}

public mapAdvancedData(advancedData: ISearchMovieResult[]) {
this.finishLoading();
const type = this.advancedDataService.getType();
advancedData.forEach(m => {

let mediaType = type;

let poster = `https://image.tmdb.org/t/p/w300/${m.posterPath}`;
if (!m.posterPath) {
if (mediaType === RequestType.movie) {
poster = "images/default_movie_poster.png"
}
if (mediaType === RequestType.tvShow) {
poster = "images/default_tv_poster.png"
}
}

this.discoverResults.push({
posterPath: poster,
requested: false,
title: m.title,
type: mediaType,
id: m.id,
url: "",
rating: 0,
overview: m.overview,
approved: false,
imdbid: "",
denied: false,
background: "",
available: false,
tvMovieDb: false
});
});
}

private async search() {
this.clear();
this.results = await this.searchService
Expand Down
14 changes: 6 additions & 8 deletions src/Ombi/ClientApp/src/app/discover/discover.module.ts
@@ -1,16 +1,14 @@
import { NgModule } from "@angular/core";
import { RouterModule } from "@angular/router";
import * as fromComponents from './components';

import { CarouselModule } from 'primeng/carousel';
import { InfiniteScrollModule } from 'ngx-infinite-scroll';
import {MatButtonToggleModule} from '@angular/material/button-toggle';

import { SharedModule } from "../shared/shared.module";
import { NgModule } from "@angular/core";
import { PipeModule } from "../pipes/pipe.module";
import { CarouselModule } from 'primeng/carousel';
import { RouterModule } from "@angular/router";
import { SharedModule } from "../shared/shared.module";
import { SkeletonModule } from 'primeng/skeleton';

import * as fromComponents from './components';


@NgModule({
imports: [
RouterModule.forChild(fromComponents.routes),
Expand Down
10 changes: 10 additions & 0 deletions src/Ombi/ClientApp/src/app/my-nav/my-nav.component.scss
Expand Up @@ -234,4 +234,14 @@

.advanced-search {
margin-left: 10px;
}

::ng-deep .dialog-responsive {
width: 40%;
}

@media only screen and (max-width: 760px) {
::ng-deep .dialog-responsive {
width: 100%;
}
}
14 changes: 12 additions & 2 deletions src/Ombi/ClientApp/src/app/my-nav/my-nav.component.ts
Expand Up @@ -11,6 +11,7 @@ import { MatDialog } from '@angular/material/dialog';
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
import { Md5 } from 'ts-md5/dist/md5';
import { Observable } from 'rxjs';
import { Router } from '@angular/router';
import { SearchFilter } from './SearchFilter';
import { StorageService } from '../shared/storage/storage-service';
import { map } from 'rxjs/operators';
Expand Down Expand Up @@ -57,7 +58,8 @@ export class MyNavComponent implements OnInit {
private store: StorageService,
private filterService: FilterService,
private dialogService: MatDialog,
private readonly settingState: SettingsStateService) {
private readonly settingState: SettingsStateService,
private router: Router) {
}

public async ngOnInit() {
Expand Down Expand Up @@ -125,7 +127,15 @@ export class MyNavComponent implements OnInit {
}

public openAdvancedSearch() {
this.dialogService.open(AdvancedSearchDialogComponent, null);
const dialogRef = this.dialogService.open(AdvancedSearchDialogComponent, { panelClass: 'dialog-responsive' });

dialogRef.afterClosed().subscribe(result => {
if (result) {
this.router.navigate([`discover/advanced/search`]);
}

return;
});
}

public getUserImage(): string {
Expand Down
@@ -0,0 +1,27 @@
import { EventEmitter, Injectable, Output } from "@angular/core";

import { RequestType } from "../../interfaces";

@Injectable({
providedIn: "root"
})
export class AdvancedSearchDialogDataService {

@Output() public onDataChange = new EventEmitter<any>();
private _data: any;
private _type: RequestType;

setData(data: any, type: RequestType) {
this._data = data;
this._type = type;
this.onDataChange.emit(this._data);
}

getData(): any {
return this._data;
}

getType(): RequestType {
return this._type;
}
}
Expand Up @@ -4,40 +4,46 @@ <h1 id="advancedOptionsTitle">
</h1>
<hr />
<div class="alert alert-info" role="alert">
<i class="fas fa-x7 fa-exclamation-triangle glyphicon"></i>
<span>{{ "MediaDetails.AutoApproveOptions" | translate }}</span>
<i class="fas fa-x7 fa-search glyphicon"></i>
<span>{{ "Search.AdvancedSearch" | translate }}</span>
</div>

<div style="max-width: 0; max-height: 0; overflow: hidden">
<input autofocus="true" />
</div>

<div class="row">
<div class="col-md-6">
<div style="margin: 2%;">
<span>Please choose what type of media you are searching for:</span>
</div>
<div class="col-md-12">
<div class="md-form-field">
<mat-radio-group formControlName="type" aria-label="Select an option">
<mat-radio-button value="movie">Movies </mat-radio-button>
<mat-radio-button style="padding-left: 5px;" value="tv">TV Shows </mat-radio-button>
</mat-radio-group>
</div>
</div>
<div class="col-md-6">
<mat-form-field appearance="outline" floatLabel=always>
<mat-label>Year</mat-label>
<div class="col-md-12" style="margin-top:1%">
<mat-form-field appearance="outline" floatLabel=auto>
<mat-label>Year of Release</mat-label>
<input matInput id="releaseYear" name="releaseYear" formControlName="releaseYear">
</mat-form-field>
</div>

<div class="col-md-6">
<keyword-search [form]="form"></keyword-search>
</div>
<div class="col-md-6">

<div class="col-md-12">
<genre-select [form]="form" [mediaType]="form.controls.type.value"></genre-select>
</div>
<div class="col-md-6">

<div class="col-md-12">
<watch-providers-select [form]="form" [mediaType]="form.controls.type.value"></watch-providers-select>
</div>
<div class="col-md-12">

<span style="margin: 1%;">Please note that Keyword Searching is very hit and miss due to the inconsistent data in TheMovieDb</span>
<keyword-search [form]="form"></keyword-search>
</div>

</div>

Expand Down

0 comments on commit 924a562

Please sign in to comment.