mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-21 05:43:19 -07:00
merge
This commit is contained in:
commit
6fc9db003e
27 changed files with 230 additions and 44 deletions
|
@ -13,6 +13,7 @@ namespace Ombi.Core.Engine.Interfaces
|
||||||
Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies();
|
Task<IEnumerable<SearchMovieViewModel>> TopRatedMovies();
|
||||||
Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies();
|
Task<IEnumerable<SearchMovieViewModel>> UpcomingMovies();
|
||||||
Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies();
|
Task<IEnumerable<SearchMovieViewModel>> NowPlayingMovies();
|
||||||
|
Task<MovieCollectionsViewModel> GetCollection(int collectionId, string langCode = null);
|
||||||
Task<int> GetTvDbId(int theMovieDbId);
|
Task<int> GetTvDbId(int theMovieDbId);
|
||||||
int ResultLimit { get; set; }
|
int ResultLimit { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
using System;
|
using AutoMapper;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using AutoMapper;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Ombi.Api.TheMovieDb;
|
using Ombi.Api.TheMovieDb;
|
||||||
using Ombi.Api.TheMovieDb.Models;
|
using Ombi.Api.TheMovieDb.Models;
|
||||||
using Ombi.Core.Authentication;
|
using Ombi.Core.Authentication;
|
||||||
|
using Ombi.Core.Engine.Interfaces;
|
||||||
using Ombi.Core.Models.Requests;
|
using Ombi.Core.Models.Requests;
|
||||||
using Ombi.Core.Models.Search;
|
using Ombi.Core.Models.Search;
|
||||||
|
using Ombi.Core.Models.Search.V2;
|
||||||
using Ombi.Core.Rule.Interfaces;
|
using Ombi.Core.Rule.Interfaces;
|
||||||
using Ombi.Core.Settings;
|
using Ombi.Core.Settings;
|
||||||
using Ombi.Helpers;
|
using Ombi.Helpers;
|
||||||
using Ombi.Settings.Settings.Models;
|
using Ombi.Settings.Settings.Models;
|
||||||
using Ombi.Store.Entities;
|
using Ombi.Store.Entities;
|
||||||
using Ombi.Store.Repository;
|
using Ombi.Store.Repository;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Security.Principal;
|
using System.Security.Principal;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Ombi.Core.Engine.Interfaces;
|
|
||||||
using Ombi.Core.Models.Search.V2;
|
|
||||||
|
|
||||||
namespace Ombi.Core.Engine.V2
|
namespace Ombi.Core.Engine.V2
|
||||||
{
|
{
|
||||||
|
@ -46,6 +46,14 @@ namespace Ombi.Core.Engine.V2
|
||||||
return await ProcessSingleMovie(movieInfo);
|
return await ProcessSingleMovie(movieInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<MovieCollectionsViewModel> GetCollection(int collectionId, string langCode = null)
|
||||||
|
{
|
||||||
|
langCode = await DefaultLanguageCode(langCode);
|
||||||
|
var collections = await MovieApi.GetCollection(langCode, collectionId);
|
||||||
|
|
||||||
|
return await ProcessCollection(collections);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<int> GetTvDbId(int theMovieDbId)
|
public async Task<int> GetTvDbId(int theMovieDbId)
|
||||||
{
|
{
|
||||||
var result = await MovieApi.GetTvExternals(theMovieDbId);
|
var result = await MovieApi.GetTvExternals(theMovieDbId);
|
||||||
|
@ -180,6 +188,30 @@ namespace Ombi.Core.Engine.V2
|
||||||
return mapped;
|
return mapped;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async Task<MovieCollectionsViewModel> ProcessCollection(Collections collection)
|
||||||
|
{
|
||||||
|
var viewMovie = Mapper.Map<MovieCollectionsViewModel>(collection);
|
||||||
|
foreach (var movie in viewMovie.Collection)
|
||||||
|
{
|
||||||
|
var mappedMovie = Mapper.Map<SearchMovieViewModel>(movie);
|
||||||
|
await RunSearchRules(mappedMovie);
|
||||||
|
|
||||||
|
// This requires the rules to be run first to populate the RequestId property
|
||||||
|
await CheckForSubscription(mappedMovie);
|
||||||
|
var mapped = Mapper.Map<MovieCollection>(movie);
|
||||||
|
|
||||||
|
mapped.Available = movie.Available;
|
||||||
|
mapped.RequestId = movie.RequestId;
|
||||||
|
mapped.Requested = movie.Requested;
|
||||||
|
mapped.PlexUrl = movie.PlexUrl;
|
||||||
|
mapped.EmbyUrl = movie.EmbyUrl;
|
||||||
|
mapped.Subscribed = movie.Subscribed;
|
||||||
|
mapped.ShowSubscribe = movie.ShowSubscribe;
|
||||||
|
}
|
||||||
|
return viewMovie;
|
||||||
|
}
|
||||||
|
|
||||||
private async Task<SearchMovieViewModel> ProcessSingleMovie(SearchMovieViewModel viewMovie)
|
private async Task<SearchMovieViewModel> ProcessSingleMovie(SearchMovieViewModel viewMovie)
|
||||||
{
|
{
|
||||||
if (viewMovie.ImdbId.IsNullOrEmpty())
|
if (viewMovie.ImdbId.IsNullOrEmpty())
|
||||||
|
|
23
src/Ombi.Core/Models/Search/V2/MovieCollectionsViewModel.cs
Normal file
23
src/Ombi.Core/Models/Search/V2/MovieCollectionsViewModel.cs
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Ombi.Store.Entities;
|
||||||
|
|
||||||
|
namespace Ombi.Core.Models.Search.V2
|
||||||
|
{
|
||||||
|
public class MovieCollectionsViewModel
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public string Overview { get; set; }
|
||||||
|
public List<MovieCollection> Collection { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MovieCollection : SearchViewModel
|
||||||
|
{
|
||||||
|
public int Id { get; set; }
|
||||||
|
public string Overview { get; set; }
|
||||||
|
public string PosterPath { get; set; }
|
||||||
|
public string Title { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public override RequestType Type => RequestType.Movie;
|
||||||
|
}
|
||||||
|
}
|
|
@ -91,6 +91,19 @@ namespace Ombi.Mapping.Profiles
|
||||||
CreateMap<BelongsToCollection, Ombi.Core.Models.Search.V2.CollectionsViewModel>().ReverseMap();
|
CreateMap<BelongsToCollection, Ombi.Core.Models.Search.V2.CollectionsViewModel>().ReverseMap();
|
||||||
CreateMap<Api.TheMovieDb.Models.Keywords, Ombi.Core.Models.Search.V2.Keywords>().ReverseMap();
|
CreateMap<Api.TheMovieDb.Models.Keywords, Ombi.Core.Models.Search.V2.Keywords>().ReverseMap();
|
||||||
CreateMap<KeywordsValue, Ombi.Core.Models.Search.V2.KeywordsValue>().ReverseMap();
|
CreateMap<KeywordsValue, Ombi.Core.Models.Search.V2.KeywordsValue>().ReverseMap();
|
||||||
|
|
||||||
|
CreateMap<Collections, Ombi.Core.Models.Search.V2.MovieCollectionsViewModel>()
|
||||||
|
.ForMember(x => x.Name, o => o.MapFrom(s => s.name))
|
||||||
|
.ForMember(x => x.Overview, o => o.MapFrom(s => s.overview))
|
||||||
|
.ForMember(x => x.Collection, o => o.MapFrom(s => s.parts));
|
||||||
|
|
||||||
|
CreateMap<Part, MovieCollection>()
|
||||||
|
.ForMember(x => x.Id, o => o.MapFrom(s => s.id))
|
||||||
|
.ForMember(x => x.Overview, o => o.MapFrom(s => s.overview))
|
||||||
|
.ForMember(x => x.PosterPath, o => o.MapFrom(s => s.poster_path))
|
||||||
|
.ForMember(x => x.Title, o => o.MapFrom(s => s.title));
|
||||||
|
|
||||||
|
CreateMap<SearchMovieViewModel, MovieCollection>().ReverseMap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -168,7 +168,7 @@
|
||||||
|
|
||||||
|
|
||||||
<div [ngClass]="user.name && roleClass()">
|
<div [ngClass]="user.name && roleClass()">
|
||||||
<app-my-nav [showNav]="showNav" [applicationName]="applicationName" [username]="user.name" (logoutClick)="logOut();"
|
<app-my-nav [showNav]="showNav" [isAdmin]="isAdmin" [applicationName]="applicationName" [username]="user.name" (logoutClick)="logOut();"
|
||||||
(themeChange)="onSetTheme($event)"></app-my-nav>
|
(themeChange)="onSetTheme($event)"></app-my-nav>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ export class AppComponent implements OnInit {
|
||||||
public userAccessToken: string;
|
public userAccessToken: string;
|
||||||
public voteEnabled = false;
|
public voteEnabled = false;
|
||||||
public applicationName: string = "Ombi"
|
public applicationName: string = "Ombi"
|
||||||
|
public isAdmin: boolean;
|
||||||
|
|
||||||
private checkedForUpdate: boolean;
|
private checkedForUpdate: boolean;
|
||||||
|
|
||||||
|
@ -61,6 +62,7 @@ export class AppComponent implements OnInit {
|
||||||
const theme = localStorage.getItem("theme");
|
const theme = localStorage.getItem("theme");
|
||||||
this.onSetTheme(theme);
|
this.onSetTheme(theme);
|
||||||
this.user = this.authService.claims();
|
this.user = this.authService.claims();
|
||||||
|
this.isAdmin = this.authService.hasRole("admin");
|
||||||
|
|
||||||
this.settingsService.getCustomization().subscribe(x => {
|
this.settingsService.getCustomization().subscribe(x => {
|
||||||
this.customizationSettings = x;
|
this.customizationSettings = x;
|
||||||
|
|
|
@ -6,9 +6,7 @@ $card-background: #2b2b2b;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark-card {
|
.dark-card {
|
||||||
background-color: $card-background;
|
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
color: white;
|
|
||||||
height: 435px;
|
height: 435px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
<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">
|
||||||
|
<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>
|
|
@ -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%;
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { Component, OnInit } from "@angular/core";
|
||||||
|
import { ActivatedRoute } from "@angular/router";
|
||||||
|
import { SearchV2Service } from "../../services";
|
||||||
|
import { IMovieCollectionsViewModel } from "../../interfaces/ISearchTvResultV2";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
templateUrl: "./discover-collections.component.html",
|
||||||
|
styleUrls: ["./discover-collections.component.scss"],
|
||||||
|
})
|
||||||
|
export class DiscoverCollectionsComponent implements OnInit {
|
||||||
|
|
||||||
|
public collectionId: number;
|
||||||
|
public collection: IMovieCollectionsViewModel;
|
||||||
|
|
||||||
|
constructor(private searchService: SearchV2Service, private route: ActivatedRoute) {
|
||||||
|
this.route.params.subscribe((params: any) => {
|
||||||
|
this.collectionId = params.collectionId;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public async ngOnInit() {
|
||||||
|
this.collection = await this.searchService.getMovieCollections(this.collectionId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,9 +10,11 @@ import { AuthGuard } from "../auth/auth.guard";
|
||||||
import { PipeModule } from "../pipes/pipe.module";
|
import { PipeModule } from "../pipes/pipe.module";
|
||||||
import { DiscoverCardDetailsComponent } from "./card/discover-card-details.component";
|
import { DiscoverCardDetailsComponent } from "./card/discover-card-details.component";
|
||||||
import { MatDialog } from "@angular/material";
|
import { MatDialog } from "@angular/material";
|
||||||
|
import { DiscoverCollectionsComponent } from "./collections/discover-collections.component";
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: "", component: DiscoverComponent, canActivate: [AuthGuard] },
|
{ path: "", component: DiscoverComponent, canActivate: [AuthGuard] },
|
||||||
|
{ path: "collection/:collectionId", component: DiscoverCollectionsComponent, canActivate: [AuthGuard] }
|
||||||
];
|
];
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -24,6 +26,7 @@ const routes: Routes = [
|
||||||
DiscoverComponent,
|
DiscoverComponent,
|
||||||
DiscoverCardComponent,
|
DiscoverCardComponent,
|
||||||
DiscoverCardDetailsComponent,
|
DiscoverCardDetailsComponent,
|
||||||
|
DiscoverCollectionsComponent,
|
||||||
],
|
],
|
||||||
entryComponents: [
|
entryComponents: [
|
||||||
DiscoverCardDetailsComponent
|
DiscoverCardDetailsComponent
|
||||||
|
|
|
@ -31,4 +31,5 @@ export interface INavBar {
|
||||||
icon: string;
|
icon: string;
|
||||||
name: string;
|
name: string;
|
||||||
link: string;
|
link: string;
|
||||||
|
requiresAdmin: boolean;
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import { INewSeasonRequests } from "./IRequestModel";
|
import { INewSeasonRequests, RequestType } from "./IRequestModel";
|
||||||
|
|
||||||
export interface ISearchTvResultV2 {
|
export interface ISearchTvResultV2 {
|
||||||
id: number;
|
id: number;
|
||||||
|
@ -44,6 +44,26 @@ export interface ISearchTvResultV2 {
|
||||||
requestId: number;
|
requestId: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IMovieCollectionsViewModel {
|
||||||
|
name: string;
|
||||||
|
overview: string;
|
||||||
|
collection: IMovieCollection[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IMovieCollection {
|
||||||
|
id: number;
|
||||||
|
overview: string;
|
||||||
|
posterPath: string;
|
||||||
|
title: string;
|
||||||
|
type: RequestType;
|
||||||
|
|
||||||
|
approved: boolean;
|
||||||
|
requested: boolean;
|
||||||
|
available: boolean;
|
||||||
|
plexUrl: string;
|
||||||
|
embyUrl: string;
|
||||||
|
imdbId: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface INetwork {
|
export interface INetwork {
|
||||||
id: number;
|
id: number;
|
||||||
|
|
|
@ -64,7 +64,7 @@
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
||||||
<div class="col-12 col-md-2">
|
<div class="col-12 col-md-2">
|
||||||
<button *ngIf="movie.belongsToCollection" mat-raised-button class="spacing-below full-width mat-elevation-z8">{{movie.belongsToCollection.name}}</button>
|
<button *ngIf="movie.belongsToCollection" [routerLink]="/discover/{{movie.belongsToCollection.id}" mat-raised-button class="spacing-below full-width mat-elevation-z8">{{movie.belongsToCollection.name}}</button>
|
||||||
|
|
||||||
<mat-card class="mat-elevation-z8">
|
<mat-card class="mat-elevation-z8">
|
||||||
<mat-card-content class="medium-font">
|
<mat-card-content class="medium-font">
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<p-carousel [value]="cast" [numVisible]="5" easing="easeOutStrong">
|
<p-carousel [value]="cast" [numVisible]="5" easing="easeOutStrong">
|
||||||
<ng-template let-item pTemplate="item">
|
<ng-template let-item pTemplate="item">
|
||||||
<div class="row justify-content-md-center">
|
<div class="row justify-content-md-center mat-card mat-card-flat">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<img class="cast-profile-img" *ngIf="item.profile_path" src="https://image.tmdb.org/t/p/w300/{{item.profile_path}}">
|
<img class="cast-profile-img" *ngIf="item.profile_path" src="https://image.tmdb.org/t/p/w300/{{item.profile_path}}">
|
||||||
<img class="cast-profile-img" *ngIf="item.character?.image?.medium" [src]="item.character.image.medium">
|
<img class="cast-profile-img" *ngIf="item.character?.image?.medium" [src]="item.character.image.medium">
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
@import "~@angular/material/theming";
|
||||||
|
@import "~styles/variables.scss";
|
||||||
|
.actor-background {
|
||||||
|
.dark & {
|
||||||
|
background: $backgroundTint-dark;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ import { Component, Input } from "@angular/core";
|
||||||
@Component({
|
@Component({
|
||||||
selector: "cast-carousel",
|
selector: "cast-carousel",
|
||||||
templateUrl: "./cast-carousel.component.html",
|
templateUrl: "./cast-carousel.component.html",
|
||||||
|
styleUrls: ["./cast-carousel.component.scss"]
|
||||||
})
|
})
|
||||||
export class CastCarouselComponent {
|
export class CastCarouselComponent {
|
||||||
|
|
||||||
|
|
|
@ -1,43 +1,43 @@
|
||||||
<a *ngIf="homepage" class="media-icons" href="{{homepage}}" target="_blank">
|
<a *ngIf="homepage" class="media-icons" href="{{homepage}}" target="_blank">
|
||||||
<i matTooltip="Homepage" class="fa fa-home fa-2x grow"></i>
|
<i matTooltip="Homepage" class="fa fa-home fa-2x grow-social"></i>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a *ngIf="theMoviedbId" href="https://www.themoviedb.org/movie/theMoviedbId" class="media-icons"
|
<a *ngIf="theMoviedbId" href="https://www.themoviedb.org/movie/theMoviedbId" class="media-icons"
|
||||||
target="_blank">
|
target="_blank">
|
||||||
<i matTooltip="The Movie DB" class="fa fa-film fa-2x grow"></i>
|
<i matTooltip="The Movie DB" class="fa fa-film fa-2x grow-social"></i>
|
||||||
</a>
|
</a>
|
||||||
<a *ngIf="tvdbId" href="https://www.thetvdb.org/tv/{{tvdbId}}" class="media-icons" target="_blank">
|
<a *ngIf="tvdbId" href="https://www.thetvdb.org/tv/{{tvdbId}}" class="media-icons" target="_blank">
|
||||||
<i matTooltip="The TV DB" class="fa fa-tv fa-2x grow"></i>
|
<i matTooltip="The TV DB" class="fa fa-tv fa-2x grow-social"></i>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a *ngIf="hasTrailer" class="media-icons" (click)="openDialog()"><i
|
<a *ngIf="hasTrailer" class="media-icons" (click)="openDialog()"><i
|
||||||
matTooltip="Trailer" class="fa fa-youtube-play fa-2x grow"></i></a>
|
matTooltip="Trailer" class="fa fa-youtube-play fa-2x grow-social"></i></a>
|
||||||
|
|
||||||
<a *ngIf="imdbId" class="media-icons" href="https://imdb.com/title/{{imdbId}}"
|
<a *ngIf="imdbId" class="media-icons" href="https://imdb.com/title/{{imdbId}}"
|
||||||
target="_blank">
|
target="_blank">
|
||||||
<i matTooltip="Imdb" class="fa fa-imdb fa-2x grow"></i>
|
<i matTooltip="Imdb" class="fa fa-imdb fa-2x grow-social"></i>
|
||||||
</a>
|
</a>
|
||||||
<a *ngIf="twitter" class="media-icons"
|
<a *ngIf="twitter" class="media-icons"
|
||||||
href="https://twitter.com/{{twitter}}" target="_blank">
|
href="https://twitter.com/{{twitter}}" target="_blank">
|
||||||
<i matTooltip="Twitter" class="fa fa-twitter fa-2x grow"></i>
|
<i matTooltip="Twitter" class="fa fa-twitter fa-2x grow-social"></i>
|
||||||
</a>
|
</a>
|
||||||
<a *ngIf="facebook" class="media-icons"
|
<a *ngIf="facebook" class="media-icons"
|
||||||
href="https://facebook.com/{{facebook}}" target="_blank">
|
href="https://facebook.com/{{facebook}}" target="_blank">
|
||||||
<i matTooltip="Facebook" class="fa fa-facebook fa-2x grow"></i>
|
<i matTooltip="Facebook" class="fa fa-facebook fa-2x grow-social"></i>
|
||||||
</a> <a *ngIf="instagram" class="media-icons"
|
</a> <a *ngIf="instagram" class="media-icons"
|
||||||
href="https://instagram.com/{{instagram}}" target="_blank">
|
href="https://instagram.com/{{instagram}}" target="_blank">
|
||||||
<i matTooltip="Instagram" class="fa fa-instagram fa-2x grow"></i>
|
<i matTooltip="Instagram" class="fa fa-instagram fa-2x grow-social"></i>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<span class="left-seperator" *ngIf="available">
|
<span class="left-seperator" *ngIf="available">
|
||||||
<a *ngIf="plexUrl" class="media-icons" href="{{plexUrl}}" target="_blank">
|
<a *ngIf="plexUrl" class="media-icons" href="{{plexUrl}}" target="_blank">
|
||||||
<i matTooltip=" {{'Search.ViewOnPlex' | translate}}"
|
<i matTooltip=" {{'Search.ViewOnPlex' | translate}}"
|
||||||
class="fa fa-play-circle fa-2x grow"></i>
|
class="fa fa-play-circle fa-2x grow-social"></i>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a *ngIf="embyUrl" class="media-icons" href="{{embyUrl}}" target="_blank">
|
<a *ngIf="embyUrl" class="media-icons" href="{{embyUrl}}" target="_blank">
|
||||||
<i matTooltip=" {{'Search.ViewOnEmby' | translate}}"
|
<i matTooltip=" {{'Search.ViewOnEmby' | translate}}"
|
||||||
class="fa fa-play-circle fa-2x grow"></i>
|
class="fa fa-play-circle fa-2x grow-social"></i>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
</span>
|
</span>
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
.grow-social {
|
||||||
|
transition: all .2s ease-in-out;
|
||||||
|
}
|
||||||
|
.grow-social:hover {
|
||||||
|
transform: scale(1.1);
|
||||||
|
color: black;
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ import { Component, Inject, Input, Output, EventEmitter } from "@angular/core";
|
||||||
@Component({
|
@Component({
|
||||||
selector: "social-icons",
|
selector: "social-icons",
|
||||||
templateUrl: "./social-icons.component.html",
|
templateUrl: "./social-icons.component.html",
|
||||||
|
styleUrls: ["./social-icons.component.scss"]
|
||||||
})
|
})
|
||||||
export class SocialIconsComponent {
|
export class SocialIconsComponent {
|
||||||
|
|
||||||
|
|
|
@ -174,14 +174,6 @@
|
||||||
width: 173px;
|
width: 173px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.grow {
|
|
||||||
transition: all .2s ease-in-out;
|
|
||||||
}
|
|
||||||
.grow:hover {
|
|
||||||
transform: scale(1.1);
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.media-icons {
|
.media-icons {
|
||||||
color: mat-color($ombi-app-primary) !important;
|
color: mat-color($ombi-app-primary) !important;
|
||||||
padding: 1%;
|
padding: 1%;
|
||||||
|
|
|
@ -3,11 +3,12 @@
|
||||||
[mode]="(isHandset$ | async) ? 'over' : 'side'" [opened]="!(isHandset$ | async)">
|
[mode]="(isHandset$ | async) ? 'over' : 'side'" [opened]="!(isHandset$ | async)">
|
||||||
<mat-toolbar>{{applicationName}}</mat-toolbar>
|
<mat-toolbar>{{applicationName}}</mat-toolbar>
|
||||||
<mat-nav-list>
|
<mat-nav-list>
|
||||||
<a *ngFor="let nav of navItems" mat-list-item [routerLink]="nav.link"
|
<span *ngFor="let nav of navItems">
|
||||||
|
<a *ngIf="nav.requiresAdmin && isAdmin || !nav.requiresAdmin" mat-list-item [routerLink]="nav.link"
|
||||||
[routerLinkActive]="getTheme()" >
|
[routerLinkActive]="getTheme()" >
|
||||||
<mat-icon aria-label="Side nav toggle icon">{{nav.icon}}</mat-icon>
|
<mat-icon aria-label="Side nav toggle icon">{{nav.icon}}</mat-icon>
|
||||||
{{nav.name | translate}}
|
{{nav.name | translate}}
|
||||||
</a>
|
</a> </span>
|
||||||
|
|
||||||
<a class="bottom-nav-link" mat-list-item [routerLinkActive]="theme === 'dark' ? 'active-list-item-dark' : 'active-list-item'" aria-label="Toggle sidenav" (click)="logOut();">
|
<a class="bottom-nav-link" mat-list-item [routerLinkActive]="theme === 'dark' ? 'active-list-item-dark' : 'active-list-item'" aria-label="Toggle sidenav" (click)="logOut();">
|
||||||
<mat-icon aria-label="Side nav toggle icon">exit_to_app</mat-icon>
|
<mat-icon aria-label="Side nav toggle icon">exit_to_app</mat-icon>
|
||||||
|
|
|
@ -19,6 +19,7 @@ export class MyNavComponent implements OnInit {
|
||||||
@Input() public showNav: boolean;
|
@Input() public showNav: boolean;
|
||||||
@Input() public applicationName: string;
|
@Input() public applicationName: string;
|
||||||
@Input() public username: string;
|
@Input() public username: string;
|
||||||
|
@Input() public isAdmin: string;
|
||||||
@Output() public logoutClick = new EventEmitter();
|
@Output() public logoutClick = new EventEmitter();
|
||||||
@Output() public themeChange = new EventEmitter<string>();
|
@Output() public themeChange = new EventEmitter<string>();
|
||||||
public theme: string;
|
public theme: string;
|
||||||
|
@ -31,10 +32,10 @@ export class MyNavComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
public navItems: INavBar[] = [
|
public navItems: INavBar[] = [
|
||||||
{ name: "NavigationBar.Discover", icon: "find_replace", link: "/discover" },
|
{ name: "NavigationBar.Discover", icon: "find_replace", link: "/discover", requiresAdmin: false },
|
||||||
{ name: "NavigationBar.Requests", icon: "list", link: "/requests-list" },
|
{ name: "NavigationBar.Requests", icon: "list", link: "/requests-list", requiresAdmin: false },
|
||||||
{ name: "NavigationBar.UserManagement", icon: "account_circle", link: "/usermanagement" },
|
{ name: "NavigationBar.UserManagement", icon: "account_circle", link: "/usermanagement", requiresAdmin: true },
|
||||||
{ name: "NavigationBar.Settings", icon: "settings", link: "/Settings/About" },
|
{ name: "NavigationBar.Settings", icon: "settings", link: "/Settings/About", requiresAdmin: true },
|
||||||
]
|
]
|
||||||
|
|
||||||
public logOut() {
|
public logOut() {
|
||||||
|
@ -57,7 +58,6 @@ export class MyNavComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTheme(){
|
public getTheme(){
|
||||||
debugger;
|
|
||||||
return this.theme === 'dark' ? 'active-list-item-dark' : 'active-list-item';
|
return this.theme === 'dark' ? 'active-list-item-dark' : 'active-list-item';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { PlatformLocation, APP_BASE_HREF } from "@angular/common";
|
import { APP_BASE_HREF } from "@angular/common";
|
||||||
import { Injectable, Inject } from "@angular/core";
|
import { Injectable, Inject } from "@angular/core";
|
||||||
|
|
||||||
import { HttpClient } from "@angular/common/http";
|
import { HttpClient } from "@angular/common/http";
|
||||||
|
@ -8,8 +8,7 @@ import { IMultiSearchResult, ISearchMovieResult, ISearchTvResult } from "../inte
|
||||||
import { ServiceHelpers } from "./service.helpers";
|
import { ServiceHelpers } from "./service.helpers";
|
||||||
|
|
||||||
import { ISearchMovieResultV2 } from "../interfaces/ISearchMovieResultV2";
|
import { ISearchMovieResultV2 } from "../interfaces/ISearchMovieResultV2";
|
||||||
import { promise } from "selenium-webdriver";
|
import { ISearchTvResultV2, IMovieCollectionsViewModel } from "../interfaces/ISearchTvResultV2";
|
||||||
import { ISearchTvResultV2 } from "../interfaces/ISearchTvResultV2";
|
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class SearchV2Service extends ServiceHelpers {
|
export class SearchV2Service extends ServiceHelpers {
|
||||||
|
@ -64,7 +63,12 @@ export class SearchV2Service extends ServiceHelpers {
|
||||||
public getTvInfo(tvdbid: number): Promise<ISearchTvResultV2> {
|
public getTvInfo(tvdbid: number): Promise<ISearchTvResultV2> {
|
||||||
return this.http.get<ISearchTvResultV2>(`${this.url}/Tv/${tvdbid}`, { headers: this.headers }).toPromise();
|
return this.http.get<ISearchTvResultV2>(`${this.url}/Tv/${tvdbid}`, { headers: this.headers }).toPromise();
|
||||||
}
|
}
|
||||||
|
|
||||||
public getTvInfoWithMovieDbId(theMovieDbId: number): Promise<ISearchTvResultV2> {
|
public getTvInfoWithMovieDbId(theMovieDbId: number): Promise<ISearchTvResultV2> {
|
||||||
return this.http.get<ISearchTvResultV2>(`${this.url}/Tv/moviedb/${theMovieDbId}`, { headers: this.headers }).toPromise();
|
return this.http.get<ISearchTvResultV2>(`${this.url}/Tv/moviedb/${theMovieDbId}`, { headers: this.headers }).toPromise();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getMovieCollections(collectionId: number): Promise<IMovieCollectionsViewModel> {
|
||||||
|
return this.http.get<IMovieCollectionsViewModel>(`${this.url}/movie/collection/${collectionId}`, { headers: this.headers }).toPromise();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,10 @@ export function getBaseLocation() {
|
||||||
let paths: string[] = location.pathname.split('/').splice(1, 1);
|
let paths: string[] = location.pathname.split('/').splice(1, 1);
|
||||||
let basePath: string = (paths && paths[0] ? paths[0] : "");
|
let basePath: string = (paths && paths[0] ? paths[0] : "");
|
||||||
if(invalidProxies.indexOf(basePath.toUpperCase()) === -1){
|
if(invalidProxies.indexOf(basePath.toUpperCase()) === -1){
|
||||||
return '/';
|
|
||||||
}
|
|
||||||
return '/' + basePath;
|
return '/' + basePath;
|
||||||
}
|
}
|
||||||
|
return '/';
|
||||||
|
}
|
||||||
|
|
||||||
const invalidProxies: string[] = [
|
const invalidProxies: string[] = [
|
||||||
'DISCOVER',
|
'DISCOVER',
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
.ui-carousel-viewport {
|
.ui-carousel-viewport {
|
||||||
border:0 !important;
|
border:0 !important;
|
||||||
background-color:$background !important;
|
background-color:transparent !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ui-carousel .ui-carousel-header {
|
.ui-carousel .ui-carousel-header {
|
||||||
|
|
|
@ -60,6 +60,16 @@ namespace Ombi.Controllers.V2
|
||||||
return await _movieEngineV2.GetFullMovieInformation(movieDbId);
|
return await _movieEngineV2.GetFullMovieInformation(movieDbId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns basic information about the provided collection
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="collectionId">The collection id from TheMovieDb</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet("movie/collection/{collectionId}")]
|
||||||
|
public async Task<MovieCollectionsViewModel> GetMovieCollections(int collectionId)
|
||||||
|
{
|
||||||
|
return await _movieEngineV2.GetCollection(collectionId);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns details for a single show
|
/// Returns details for a single show
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue