mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-07-16 02:02:55 -07:00
phew! !wip
This commit is contained in:
parent
1757b1c88d
commit
2702747549
20 changed files with 356 additions and 54 deletions
|
@ -24,7 +24,7 @@
|
|||
"src/assets"
|
||||
],
|
||||
"styles": [
|
||||
"src/styles/styles.scss",
|
||||
"src/styles/_imports.scss",
|
||||
"node_modules/bootstrap/scss/bootstrap.scss",
|
||||
"node_modules/angular-bootstrap-md/scss/mdb-free.scss",
|
||||
"node_modules/pace/themes/orange/pace-theme-flash.css",
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
<mat-card>
|
||||
<div class="card-spacing" *ngIf="result">
|
||||
<mat-card class="mat-elevation-z8">
|
||||
|
||||
<a [routerLink]="result.type === RequestType.movie ? '/details/movie/' + result.id : '/details/tv/' + result.id">
|
||||
<img mat-card-image src="{{result.posterPath}}" class="card-poster" alt="{{result.title}}">
|
||||
</a>
|
||||
<mat-card-content>
|
||||
<div class="rating">{{result.rating | number:'1.0-1'}}</div>
|
||||
<a [routerLink]="result.type === RequestType.movie ? '/details/movie/' + result.id : '/details/tv/' + result.id">
|
||||
<img mat-card-image src="{{result.posterPath}}" class="card-poster" alt="{{result.title}}">
|
||||
</a>
|
||||
<mat-card-content>
|
||||
|
||||
<h5 *ngIf="result.title.length <= 10">{{result.title}}</h5>
|
||||
<h6 *ngIf="result.title.length > 10 && result.title.length <= 13">{{result.title}}</h6>
|
||||
<h6 *ngIf="result.title.length > 13" matTooltip="{{result.title}}">{{result.title | truncate:13}}</h6>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button *ngIf="!result.requested && !result.available" mat-raised-button color="primary">Request</button>
|
||||
<button *ngIf="result.requested && !result.available" mat-raised-button color="warn">Requested</button>
|
||||
<button *ngIf="!result.requested && result.available" mat-raised-button color="accent">Available</button>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
<h5 *ngIf="result.title.length <= 10">{{result.title}}</h5>
|
||||
<h6 *ngIf="result.title.length > 10 && result.title.length <= 13">{{result.title}}</h6>
|
||||
<h6 *ngIf="result.title.length > 13" matTooltip="{{result.title}}">{{result.title | truncate:13}}</h6>
|
||||
</mat-card-content>
|
||||
<mat-card-actions>
|
||||
<button *ngIf="!result.requested && !result.available" mat-raised-button color="primary">Request</button>
|
||||
<button *ngIf="result.requested && !result.available" mat-raised-button color="warn">Requested</button>
|
||||
<button *ngIf="!result.requested && result.available" mat-raised-button class="btn-green">Available</button>
|
||||
</mat-card-actions>
|
||||
</mat-card>
|
||||
</div>
|
|
@ -1,3 +1,12 @@
|
|||
.card-poster {
|
||||
max-height: 225px;
|
||||
}
|
||||
|
||||
.card-spacing {
|
||||
margin-top:10%;
|
||||
}
|
||||
|
||||
.rating {
|
||||
position: absolute;
|
||||
font-weight: bold;
|
||||
}
|
|
@ -45,6 +45,7 @@ export class DiscoverCardComponent implements OnInit {
|
|||
this.result.available = updated.available;
|
||||
this.result.requested = updated.requested;
|
||||
this.result.requested = updated.requestProcessing;
|
||||
this.result.rating = updated.voteAverage;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<div *ngIf="discoverResults" class="row" >
|
||||
<div class="col-lg-2 col-md-4 col-6" *ngFor="let result of discoverResults" [@slideIn]>
|
||||
<discover-card [result]="result"></discover-card>
|
||||
<div class="container">
|
||||
<div *ngIf="discoverResults" class="row top-spacing full-height">
|
||||
<div class="col-lg-2 col-md-4 col-6" *ngFor="let result of discoverResults" [@slideIn]>
|
||||
<discover-card [result]="result"></discover-card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,3 @@
|
|||
.full-height {
|
||||
height:100%;
|
||||
}
|
|
@ -6,6 +6,7 @@ import { trigger, transition, style, animate } from "@angular/animations";
|
|||
|
||||
@Component({
|
||||
templateUrl: "./discover.component.html",
|
||||
styleUrls: ["./discover.component.scss"],
|
||||
animations: [
|
||||
trigger('slideIn', [
|
||||
transition(':enter', [
|
||||
|
@ -38,7 +39,8 @@ export class DiscoverComponent implements OnInit {
|
|||
title: m.title,
|
||||
type: RequestType.movie,
|
||||
id: m.id,
|
||||
url: `http://www.imdb.com/title/${m.imdbId}/`
|
||||
url: `http://www.imdb.com/title/${m.imdbId}/`,
|
||||
rating: m.voteAverage
|
||||
});
|
||||
});
|
||||
this.tvShows.forEach(m => {
|
||||
|
@ -49,7 +51,8 @@ export class DiscoverComponent implements OnInit {
|
|||
title: m.title,
|
||||
type: RequestType.tvShow,
|
||||
id: m.id,
|
||||
url: undefined
|
||||
url: undefined,
|
||||
rating: +m.rating,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import { SharedModule } from "../shared/shared.module";
|
|||
import { DiscoverComponent } from "./discover.component";
|
||||
import { DiscoverCardComponent } from "./card/discover-card.component";
|
||||
import { AuthGuard } from "../auth/auth.guard";
|
||||
import { PipeModule } from "../pipes/pipe.module";
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: "", component: DiscoverComponent, canActivate: [AuthGuard] },
|
||||
|
@ -15,6 +16,7 @@ const routes: Routes = [
|
|||
imports: [
|
||||
RouterModule.forChild(routes),
|
||||
SharedModule,
|
||||
PipeModule,
|
||||
],
|
||||
declarations: [
|
||||
DiscoverComponent,
|
||||
|
|
|
@ -8,4 +8,5 @@ export interface IDiscoverCardResult {
|
|||
type: RequestType;
|
||||
available: boolean;
|
||||
requested: boolean;
|
||||
rating: number;
|
||||
}
|
|
@ -5,6 +5,7 @@ import { SearchService } from "../services";
|
|||
|
||||
import { SharedModule } from "../shared/shared.module";
|
||||
import { MovieDetailsComponent } from "./movie-details.component";
|
||||
import { PipeModule } from "../pipes/pipe.module";
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: "movie/:movieDbId", component: MovieDetailsComponent },
|
||||
|
@ -13,6 +14,7 @@ const routes: Routes = [
|
|||
imports: [
|
||||
RouterModule.forChild(routes),
|
||||
SharedModule,
|
||||
PipeModule,
|
||||
],
|
||||
declarations: [
|
||||
MovieDetailsComponent,
|
||||
|
|
|
@ -1,12 +1,102 @@
|
|||
<div *ngIf="movie">
|
||||
<div>
|
||||
<img src="{{movie.background}}" class="banner" />
|
||||
</div>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div>
|
||||
{{movie.title}}
|
||||
|
||||
<section id="summary-wrapper">
|
||||
<div class="full-screenshot enabled" [style.background-image]="movie.background"></div>
|
||||
<div class="shadow-base"></div>
|
||||
|
||||
<div class="container summary">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-10 offset-lg-2 col-md-8 offset-md-4 col-sm-7 offset-sm-5 col-6 offset-6">
|
||||
<h1>{{movie.title}} <span *ngIf="movie.releaseDate" class="year align-middle">({{movie.releaseDate
|
||||
| date:'yyyy'}})</span>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="info-wrapper">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-md-2 col-sm-3 hidden-xs">
|
||||
<div class="sidebar affixable affix-top" style="width: 173px;">
|
||||
<div class="poster">
|
||||
<img class="real" src="https://image.tmdb.org/t/p/w300/{{movie.posterPath}}" alt="Poster"
|
||||
style="display: block;">
|
||||
</div>
|
||||
<!--Underneith poster-->
|
||||
<br />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--Next to poster-->
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-3 ">
|
||||
|
||||
<mat-card class="card-full mat-elevation-z8">
|
||||
<mat-card-content>
|
||||
<div>
|
||||
<small><strong>Theatrical Release:</strong> {{movie.releaseDate | date: 'mediumDate'}}</small></div>
|
||||
<div>
|
||||
<small *ngIf="movie.digitalReleaseDate"><strong>Digital Release:</strong>
|
||||
{{movie.digitalReleaseDate | date:
|
||||
'mediumDate'}}</small>
|
||||
</div>
|
||||
<div>
|
||||
<small *ngIf="movie.voteAverage"><strong>User Score:</strong> {{movie.voteAverage |
|
||||
number:'1.0-1'}}/10</small>
|
||||
</div>
|
||||
<div>
|
||||
<small *ngIf="movie.voteCount"><strong>Votes:</strong> {{movie.voteCount |
|
||||
thousandShort: 1}}</small>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
<div class="col-md-7">
|
||||
<mat-card class="card-full mat-elevation-z8">
|
||||
<mat-card-content>
|
||||
{{movie.overview}}
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
<div class="col-md-2 card-full">
|
||||
<div><button mat-raised-button class="btn-spacing" color="accent">Request</button></div>
|
||||
<div><button mat-raised-button class="btn-green btn-spacing">Available</button></div>
|
||||
<div><button mat-raised-button class="btn-spacing" color="warn">Deny</button></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="row card-spacer">
|
||||
<div class="col-md-2">
|
||||
<div>
|
||||
<a *ngIf="movie.homepage" class="btn-spacing" href="{{movie.homepage}}" target="_blank" mat-raised-button color="accent">Home Page</a>
|
||||
<a *ngIf="movie.theMovieDbId" href="https://www.themoviedb.org/movie/{{movie.theMovieDbId}}" target="_blank" mat-raised-button class="btn-blue btn-spacing">The Movie DB</a>
|
||||
<a *ngIf="movie.imdbId" href="https://www.imdb.com/title/tt1727824/{{movie.imdbId}}" target="_blank" mat-raised-button class="imdb-color btn-spacing">IMDb</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
|
@ -1,7 +1,150 @@
|
|||
.banner {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
width: 100%;
|
||||
//MINE
|
||||
@media (max-width: 570px) {
|
||||
h1 {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
// Change
|
||||
|
||||
|
||||
#summary-wrapper .full-screenshot,
|
||||
.summary-wrapper .full-screenshot,
|
||||
#watching-wrapper .full-screenshot,
|
||||
.hero-wrapper .full-screenshot,
|
||||
#statics-top-wrapper .full-screenshot {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-position: 50% 10%;
|
||||
opacity: 0;
|
||||
transition: all 1s;
|
||||
}
|
||||
|
||||
#summary-wrapper,
|
||||
.summary-wrapper {
|
||||
background-color: #000;
|
||||
background-size: cover;
|
||||
background-position: 50% 10%;
|
||||
transition: all .5s;
|
||||
height: 550px;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
#summary-wrapper .full-screenshot.enabled,
|
||||
.summary-wrapper .full-screenshot.enabled,
|
||||
#watching-wrapper .full-screenshot.enabled,
|
||||
.hero-wrapper .full-screenshot.enabled,
|
||||
#statics-top-wrapper .full-screenshot.enabled {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#summary-wrapper .shadow-base,
|
||||
.summary-wrapper .shadow-base {
|
||||
height: 120px;
|
||||
bottom: 0;
|
||||
background-image: -webkit-linear-gradient(top, transparent 0%, rgba(0, 0, 0, 0.8) 100%);
|
||||
background-image: -o-linear-gradient(top, transparent 0%, rgba(0, 0, 0, 0.8) 100%);
|
||||
background-image: linear-gradient(to bottom, transparent 0%, rgba(0, 0, 0, 0.8) 100%);
|
||||
background-repeat: repeat-x;
|
||||
}
|
||||
|
||||
.shadow-base {
|
||||
height: 75px;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background-image: -webkit-linear-gradient(top, transparent 0%, rgba(0, 0, 0, 0.3) 100%);
|
||||
background-image: -o-linear-gradient(top, transparent 0%, rgba(0, 0, 0, 0.3) 100%);
|
||||
background-image: linear-gradient(to bottom, transparent 0%, rgba(0, 0, 0, 0.3) 100%);
|
||||
background-repeat: repeat-x;
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#4D000000', GradientType=0);
|
||||
}
|
||||
|
||||
#summary-wrapper .summary .container,
|
||||
.summary-wrapper .summary .container {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
#summary-wrapper,
|
||||
.summary-wrapper {
|
||||
background-color: #000;
|
||||
background-size: cover;
|
||||
background-position: 50% 10%;
|
||||
transition: all .5s;
|
||||
height: 550px;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#summary-wrapper .summary .container h1 .year,
|
||||
.summary-wrapper .summary .container h1 .year {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
#summary-wrapper .summary .container h1,
|
||||
.summary-wrapper .summary .container h1 {
|
||||
margin: 0;
|
||||
text-shadow: 0 0 20px #000;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
#info-wrapper {
|
||||
min-height: 600px;
|
||||
}
|
||||
|
||||
section {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
#info-wrapper .sidebar.affixable.affix-top {
|
||||
position: relative !important;
|
||||
}
|
||||
|
||||
#info-wrapper .sidebar {
|
||||
margin-top: -180px;
|
||||
}
|
||||
|
||||
#info-wrapper .sidebar .poster {
|
||||
border: solid 3px #fff !important;
|
||||
position: relative;
|
||||
-webkit-box-shadow: 0 0 20px 0 #666;
|
||||
box-shadow: 0 0 20px 0 #666;
|
||||
}
|
||||
|
||||
#info-wrapper .sidebar .poster img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#info-wrapper .sidebar .poster .real {
|
||||
height: 100%;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.card-spacer {
|
||||
padding-top:1%;
|
||||
}
|
||||
|
||||
.card-full {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.imdb-color {
|
||||
color:black;
|
||||
background-color: #f5de50;
|
||||
}
|
||||
|
||||
.btn-spacing {
|
||||
margin-top:10px;
|
||||
}
|
|
@ -24,7 +24,10 @@ export class MovieDetailsComponent {
|
|||
this.searchService.getMovieInformation(this.theMovidDbId).subscribe(x => {
|
||||
this.movie = x;
|
||||
|
||||
this.imageService.getMovieBanner(this.theMovidDbId.toString()).subscribe(x => this.movie.background = x);
|
||||
this.imageService.getMovieBanner(this.theMovidDbId.toString()).subscribe(x => {
|
||||
this.movie.background = this.sanitizer.bypassSecurityTrustStyle
|
||||
("url(" + x + ")");
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
|
|
@ -19,17 +19,6 @@
|
|||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
@media (max-width: 978px) {
|
||||
.top-spacing {
|
||||
padding-top: 10%
|
||||
}
|
||||
}
|
||||
@media (min-width: 979px) {
|
||||
.top-spacing {
|
||||
padding-top: 4%
|
||||
}
|
||||
}
|
||||
|
||||
.example-form {
|
||||
min-width: 150px;
|
||||
max-width: 500px;
|
||||
|
|
|
@ -40,9 +40,8 @@
|
|||
</mat-toolbar>
|
||||
|
||||
<!-- Page -->
|
||||
<div class="container top-spacing">
|
||||
<ng-container *ngTemplateOutlet="template"></ng-container>
|
||||
</div>
|
||||
|
||||
|
||||
</mat-sidenav-content>
|
||||
</mat-sidenav-container>
|
||||
|
|
23
src/Ombi/ClientApp/src/app/pipes/ThousandShortPipe.ts
Normal file
23
src/Ombi/ClientApp/src/app/pipes/ThousandShortPipe.ts
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { Pipe, PipeTransform } from "@angular/core";
|
||||
|
||||
@Pipe({
|
||||
name: "thousandShort",
|
||||
})
|
||||
export class ThousandShortPipe implements PipeTransform {
|
||||
transform(input: any, args?: any): any {
|
||||
var exp, rounded,
|
||||
suffixes = ['k', 'M', 'G', 'T', 'P', 'E'];
|
||||
|
||||
if (Number.isNaN(input)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (input < 1000) {
|
||||
return input;
|
||||
}
|
||||
|
||||
exp = Math.floor(Math.log(input) / Math.log(1000));
|
||||
|
||||
return (input / Math.pow(1000, exp)).toFixed(args) + suffixes[exp - 1];
|
||||
}
|
||||
}
|
|
@ -1,10 +1,11 @@
|
|||
import { ModuleWithProviders, NgModule } from "@angular/core";
|
||||
import { HumanizePipe } from "./HumanizePipe";
|
||||
import { ThousandShortPipe } from "./ThousandShortPipe";
|
||||
|
||||
@NgModule({
|
||||
imports: [],
|
||||
declarations: [HumanizePipe],
|
||||
exports: [HumanizePipe],
|
||||
declarations: [HumanizePipe, ThousandShortPipe],
|
||||
exports: [HumanizePipe, ThousandShortPipe],
|
||||
})
|
||||
export class PipeModule {
|
||||
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
@import "./styles.scss"
|
||||
@import "./styles.scss";
|
||||
@import "./shared.scss";
|
27
src/Ombi/ClientApp/src/styles/shared.scss
Normal file
27
src/Ombi/ClientApp/src/styles/shared.scss
Normal file
|
@ -0,0 +1,27 @@
|
|||
|
||||
@media (max-width: 978px) {
|
||||
.top-spacing {
|
||||
padding-top: 10%;
|
||||
}
|
||||
}
|
||||
@media (min-width: 979px) {
|
||||
.top-spacing {
|
||||
padding-top: 4%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.btn-blue {
|
||||
background-color: #1976D2;
|
||||
}
|
||||
|
||||
.btn-pink {
|
||||
background-color: #C2185B;
|
||||
}
|
||||
.btn-green {
|
||||
background-color: #1DE9B6;
|
||||
}
|
||||
|
||||
.btn-orange {
|
||||
background-color: #F57C00;
|
||||
}
|
|
@ -159,12 +159,12 @@ namespace Ombi.Controllers.V1
|
|||
return string.Empty;
|
||||
}
|
||||
|
||||
if (images.moviebanner?.Any() ?? false)
|
||||
if (images.moviebackground?.Any() ?? false)
|
||||
{
|
||||
var enImage = images.moviebanner.Where(x => x.lang == "en").OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault();
|
||||
var enImage = images.moviebackground.Where(x => x.lang == "en").OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault();
|
||||
if (enImage == null)
|
||||
{
|
||||
return images.moviebanner.OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault();
|
||||
return images.moviebackground.OrderByDescending(x => x.likes).Select(x => x.url).FirstOrDefault();
|
||||
}
|
||||
return enImage;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue