mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-14 02:26:55 -07:00
Merge pull request #4019 from Ombi-app/develop-test2
Redesign of the wizard Movie Details improvements and some CSS fixes
This commit is contained in:
commit
91b65f321f
70 changed files with 1003 additions and 449 deletions
26
src/Ombi/Attributes/WizardActionFilter.cs
Normal file
26
src/Ombi/Attributes/WizardActionFilter.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Attributes
|
||||
{
|
||||
public class WizardActionFilter : IAsyncActionFilter
|
||||
{
|
||||
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
||||
{
|
||||
var settingsService = context.HttpContext.RequestServices.GetRequiredService<ISettingsService<OmbiSettings>>();
|
||||
|
||||
var settings = await settingsService.GetSettingsAsync();
|
||||
|
||||
if (!settings.Wizard)
|
||||
{
|
||||
await next();
|
||||
return;
|
||||
}
|
||||
context.Result = new UnauthorizedResult();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,7 +29,10 @@
|
|||
"src/styles/_imports.scss",
|
||||
"node_modules/bootstrap/scss/bootstrap.scss",
|
||||
"node_modules/primeng/resources/themes/md-dark-deeppurple/theme.css",
|
||||
"node_modules/font-awesome/scss/font-awesome.scss",
|
||||
"node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss",
|
||||
"node_modules/@fortawesome/fontawesome-free/scss/regular.scss",
|
||||
"node_modules/@fortawesome/fontawesome-free/scss/solid.scss",
|
||||
"node_modules/@fortawesome/fontawesome-free/scss/brands.scss",
|
||||
"node_modules/primeng/resources/primeng.min.css",
|
||||
"node_modules/primeicons/primeicons.css",
|
||||
"node_modules/please-wait/src/please-wait.scss",
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
"@angularclass/hmr": "^2.1.3",
|
||||
"@aspnet/signalr": "^1.1.0",
|
||||
"@auth0/angular-jwt": "^2.1.0",
|
||||
"@fortawesome/fontawesome-free": "^5.15.2",
|
||||
"@fullcalendar/core": "^4.2.0",
|
||||
"@fullcalendar/daygrid": "^4.4.0",
|
||||
"@fullcalendar/interaction": "^4.2.0",
|
||||
|
@ -39,7 +40,6 @@
|
|||
"chart.js": "2.9.4",
|
||||
"core-js": "^2.5.4",
|
||||
"eventemitter2": "^5.0.1",
|
||||
"font-awesome": "^4.7.0",
|
||||
"fullcalendar": "^4.0.0-alpha.4",
|
||||
"jquery": "3.3.1",
|
||||
"lodash": "^4.17.20",
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
<ul *ngIf="customizationSettings.recentlyAddedPage" class="nav navbar-nav">
|
||||
<li id="RecentlyAdded" [routerLinkActive]="['active']">
|
||||
<a [routerLink]="['/recentlyadded']">
|
||||
<i class="fa fa-check"></i> {{ 'NavigationBar.RecentlyAdded' | translate }}</a>
|
||||
<i class="fas fa-check"></i> {{ 'NavigationBar.RecentlyAdded' | translate }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<div class="form-group">
|
||||
<label for="Ip" class="control-label">Page Title
|
||||
|
||||
<i *ngIf="form.get('title').hasError('required')" class="fa fa-exclamation-circle error-text" pTooltip="Title is required"></i>
|
||||
<i *ngIf="form.get('title').hasError('required')" class="fas fa-exclamation-circle error-text" pTooltip="Title is required"></i>
|
||||
</label>
|
||||
|
||||
<input type="text" class="form-control form-control-custom " id="Ip" name="Ip" formControlName="title" [ngClass]="{'form-error': form.get('title').hasError('required')}">
|
||||
|
@ -14,7 +14,7 @@
|
|||
<div class="form-group">
|
||||
<label for="Ip" class="control-label">Font Awesome Icon
|
||||
|
||||
<i *ngIf="form.get('fontAwesomeIcon').hasError('required')" class="fa fa-exclamation-circle error-text" pTooltip="Font Awesome Icon is required"></i>
|
||||
<i *ngIf="form.get('fontAwesomeIcon').hasError('required')" class="fas fa-exclamation-circle error-text" pTooltip="Font Awesome Icon is required"></i>
|
||||
</label>
|
||||
|
||||
<input type="text" class="form-control form-control-custom " id="fontAwesomeIcon" name="fontAwesomeIcon" formControlName="fontAwesomeIcon" [ngClass]="{'form-error': form.get('fontAwesomeIcon').hasError('required')}">
|
||||
|
|
|
@ -16,35 +16,35 @@
|
|||
<span *ngIf="movie">
|
||||
<a *ngIf="movie.plexUrl" class="media-icons" href="{{movie.plexUrl}}" target="_blank">
|
||||
<i matTooltip=" {{'Search.ViewOnPlex' | translate}}"
|
||||
class="fa fa-play-circle fa-2x grow"></i>
|
||||
class="fas fa-play-circle fa-2x grow"></i>
|
||||
</a>
|
||||
<a *ngIf="movie.embyUrl" class="media-icons" href="{{movie.embyUrl}}" target="_blank">
|
||||
<i matTooltip=" {{'Search.ViewOnEmby' | translate}}"
|
||||
class="fa fa-play-circle fa-2x grow"></i>
|
||||
class="fas fa-play-circle fa-2x grow"></i>
|
||||
</a>
|
||||
<a *ngIf="movie.jellyfinUrl" class="media-icons" href="{{movie.jellyfinUrl}}" target="_blank">
|
||||
<i matTooltip=" {{'Search.ViewOnJellyfin' | translate}}"
|
||||
class="fa fa-play-circle fa-2x grow"></i>
|
||||
class="fas fa-play-circle fa-2x grow"></i>
|
||||
</a>
|
||||
</span>
|
||||
|
||||
<span *ngIf="tv">
|
||||
<a *ngIf="tv.plexUrl" class="media-icons" href="{{tv.plexUrl}}" target="_blank">
|
||||
<i matTooltip=" {{'Search.ViewOnPlex' | translate}}"
|
||||
class="fa fa-play-circle fa-2x grow"></i>
|
||||
class="fas fa-play-circle fa-2x grow"></i>
|
||||
</a>
|
||||
<a *ngIf="tv.embyUrl" class="media-icons" href="{{tv.embyUrl}}" target="_blank">
|
||||
<i matTooltip=" {{'Search.ViewOnEmby' | translate}}"
|
||||
class="fa fa-play-circle fa-2x grow"></i>
|
||||
class="fas fa-play-circle fa-2x grow"></i>
|
||||
</a>
|
||||
<a *ngIf="tv.jellyfinUrl" class="media-icons" href="{{tv.jellyfinUrl}}" target="_blank">
|
||||
<i matTooltip=" {{'Search.ViewOnJellyfin' | translate}}"
|
||||
class="fa fa-play-circle fa-2x grow"></i>
|
||||
class="fas fa-play-circle fa-2x grow"></i>
|
||||
</a>
|
||||
</span>
|
||||
|
||||
<a class="media-icons" (click)="close()">
|
||||
<i class="fa fa-window-close fa-2x grow"></i>
|
||||
<i class="fas fa-window-close fa-2x grow"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
|
@ -123,14 +123,14 @@
|
|||
<span *ngIf="!movie.available">
|
||||
<span *ngIf="movie.requested || movie.approved; then requestedBtn else notRequestedBtn"></span>
|
||||
<ng-template #requestedBtn>
|
||||
<button mat-raised-button class="btn-spacing btn-orange" [disabled]><i class="fa fa-check"></i>
|
||||
<button mat-raised-button class="btn-spacing btn-orange" [disabled]><i class="fas fa-check"></i>
|
||||
{{ 'Common.Requested' | translate }}</button>
|
||||
</ng-template>
|
||||
<ng-template #notRequestedBtn>
|
||||
<button mat-raised-button class="btn-spacing" color="primary" (click)="request()">
|
||||
<i *ngIf="movie.requestProcessing" class="fa fa-circle-o-notch fa-spin fa-fw"></i> <i
|
||||
*ngIf="!movie.requestProcessing && !movie.processed" class="fa fa-plus"></i>
|
||||
<i *ngIf="movie.processed && !movie.requestProcessing" class="fa fa-check"></i> {{
|
||||
<i *ngIf="movie.requestProcessing" class="fas fa-circle-notch fa-spin fa-fw"></i> <i
|
||||
*ngIf="!movie.requestProcessing && !movie.processed" class="fas fa-plus"></i>
|
||||
<i *ngIf="movie.processed && !movie.requestProcessing" class="fas fa-check"></i> {{
|
||||
'Common.Request' | translate }}</button>
|
||||
</ng-template>
|
||||
</span>
|
||||
|
@ -140,27 +140,27 @@
|
|||
|
||||
<div *ngIf="!tv.fullyAvailable" class="dropdown">
|
||||
<button mat-raised-button class="btn-orange btn-spacing" type="button" (click)="request()">
|
||||
<i class="fa fa-plus"></i>
|
||||
<i class="fas fa-plus"></i>
|
||||
{{ 'Common.Request' | translate }}
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button *ngIf="tv.fullyAvailable" mat-raised-button class="btn-spacing" color="accent" [disabled]>
|
||||
<i class="fa fa-check"></i> {{'Common.Available' | translate }}</button>
|
||||
<i class="fas fa-check"></i> {{'Common.Available' | translate }}</button>
|
||||
<button *ngIf="tv.partlyAvailable && !tv.fullyAvailable" mat-raised-button class="btn-spacing" color="accent"
|
||||
[disabled]>
|
||||
<i class="fa fa-check"></i> {{'Common.PartiallyAvailable' | translate }}</button>
|
||||
<i class="fas fa-check"></i> {{'Common.PartiallyAvailable' | translate }}</button>
|
||||
|
||||
<span *ngIf="tv.available">
|
||||
<a *ngIf="tv.plexUrl" mat-raised-button style="text-align: right" class="btn-spacing btn-greem"
|
||||
href="{{tv.plexUrl}}" target="_blank"><i class="fa fa-eye"></i> {{'Search.ViewOnPlex' |
|
||||
href="{{tv.plexUrl}}" target="_blank"><i class="far fa-eye"></i> {{'Search.ViewOnPlex' |
|
||||
translate}}</a>
|
||||
<a *ngIf="tv.embyUrl" mat-raised-button class="btn-green btn-spacing" href="{{tv.embyUrl}}"
|
||||
target="_blank"><i class="fa fa-eye"></i> {{'Search.ViewOnEmby' |
|
||||
target="_blank"><i class="far fa-eye"></i> {{'Search.ViewOnEmby' |
|
||||
translate}}</a>
|
||||
<a *ngIf="tv.jellyfinUrl" mat-raised-button class="btn-green btn-spacing" href="{{tv.jellyfinUrl}}"
|
||||
target="_blank"><i class="fa fa-eye"></i> {{'Search.ViewOnJellyfin' |
|
||||
target="_blank"><i class="far fa-eye"></i> {{'Search.ViewOnJellyfin' |
|
||||
translate}}</a>
|
||||
</span>
|
||||
<button mat-raised-button class="btn-green btn-spacing" (click)="openDetails()"> {{
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
{{RequestType[result.type] | humanize}}
|
||||
</div>
|
||||
<div class="{{getStatusClass()}} top-right">
|
||||
<span>{{getAvailbilityStatus()}}</span>
|
||||
<span class="indicator"></span><span class="indicator-text">{{getAvailbilityStatus()}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<img [routerLink]="generateDetailsLink()" id="cardImage" src="{{result.posterPath}}" class="image"
|
||||
|
@ -22,7 +22,7 @@
|
|||
<div class="col-12">
|
||||
<button mat-raised-button class="btn-green full-width poster-request-btn" (click)="request($event)">
|
||||
<mat-icon *ngIf="!loading">cloud_download</mat-icon>
|
||||
<i *ngIf="loading" class="fa fa-spinner fa-pulse fa-2x fa-fw" aria-hidden="true"></i>
|
||||
<i *ngIf="loading" class="fas fa-spinner fa-pulse fa-2x fa-fw" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -159,17 +159,27 @@ small {
|
|||
}
|
||||
|
||||
/* common */
|
||||
.top-right span {
|
||||
.top-right{
|
||||
display:flex;
|
||||
}
|
||||
|
||||
.top-right span.indicator, span.indicator-text {
|
||||
display: none;
|
||||
background-color: transparent;
|
||||
color: #fff;
|
||||
text-shadow: 0 1px 1px rgba(0,0,0,.2);
|
||||
text-align: right;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.top-right span.indicator{
|
||||
padding-right: 0px;
|
||||
}
|
||||
.top-right span.indicator-text{
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.top-right span:before{
|
||||
.top-right span.indicator:before{
|
||||
content: '';
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
|
@ -179,29 +189,29 @@ small {
|
|||
margin-right:5px;
|
||||
}
|
||||
|
||||
.top-right.available span{
|
||||
.top-right.available span.indicator, span.indicator-text{
|
||||
display:block;
|
||||
}
|
||||
|
||||
.top-right.available span:before{
|
||||
.top-right.available span.indicator:before{
|
||||
display: inline-block;
|
||||
background-color: #1DE9B6;
|
||||
}
|
||||
|
||||
.top-right.approved span {
|
||||
.top-right.approved span.indicator, span.indicator-text {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.top-right.approved span:before{
|
||||
.top-right.approved span.indicator:before{
|
||||
display: inline-block;
|
||||
background-color: #ff5722;
|
||||
}
|
||||
|
||||
.top-right.requested span {
|
||||
.top-right.requested span.indicator, span.indicator-text {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.top-right.requested span:before{
|
||||
.top-right.requested span.indicator:before{
|
||||
display: inline-block;
|
||||
background-color: #ffd740;
|
||||
}
|
||||
|
@ -212,4 +222,18 @@ small {
|
|||
|
||||
a.poster-overlay:hover{
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 400px){
|
||||
.ellipsis{
|
||||
display:none;
|
||||
}
|
||||
|
||||
.top-right span.indicator-text{
|
||||
display:none;
|
||||
}
|
||||
|
||||
.top-right span.indicator{
|
||||
padding-right:1em;
|
||||
}
|
||||
}
|
|
@ -9,4 +9,9 @@ h2{
|
|||
margin-top:40px;
|
||||
margin-left:40px;
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
::ng-deep .p-carousel-item{
|
||||
min-height:290px;
|
||||
max-height:290px;
|
||||
}
|
|
@ -118,14 +118,14 @@
|
|||
*ngIf="movie.requested || movie.approved; then requestedBtn else notRequestedBtn"></span>
|
||||
<ng-template #requestedBtn>
|
||||
<button mat-raised-button class="btn-spacing btn-orange" [disabled]><i
|
||||
class="fa fa-check"></i>
|
||||
class="fas fa-check"></i>
|
||||
{{ 'Common.Requested' | translate }}</button>
|
||||
</ng-template>
|
||||
<ng-template #notRequestedBtn>
|
||||
<button mat-raised-button class="btn-spacing" color="primary" (click)="request()">
|
||||
<i *ngIf="movie.requestProcessing" class="fa fa-circle-o-notch fa-spin fa-fw"></i>
|
||||
<i *ngIf="!movie.requestProcessing && !movie.processed" class="fa fa-plus"></i>
|
||||
<i *ngIf="movie.processed && !movie.requestProcessing" class="fa fa-check"></i> {{
|
||||
<i *ngIf="movie.requestProcessing" class="fas fa-circle-notch fa-spin fa-fw"></i>
|
||||
<i *ngIf="!movie.requestProcessing && !movie.processed" class="fas fa-plus"></i>
|
||||
<i *ngIf="movie.processed && !movie.requestProcessing" class="fas fa-check"></i> {{
|
||||
'Common.Request' | translate }}</button>
|
||||
</ng-template>
|
||||
</span>
|
||||
|
@ -135,7 +135,7 @@
|
|||
|
||||
<div *ngIf="!tv.fullyAvailable" class="dropdown">
|
||||
<button mat-raised-button class="btn-orange btn-spacing" type="button" (click)="request()">
|
||||
<i class="fa fa-plus"></i>
|
||||
<i class="fas fa-plus"></i>
|
||||
{{ 'Common.Request' | translate }}
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
|
@ -143,21 +143,21 @@
|
|||
|
||||
<button *ngIf="tv.fullyAvailable" mat-raised-button class="btn-spacing" color="accent"
|
||||
[disabled]>
|
||||
<i class="fa fa-check"></i> {{'Common.Available' | translate }}</button>
|
||||
<i class="fas fa-check"></i> {{'Common.Available' | translate }}</button>
|
||||
<button *ngIf="tv.partlyAvailable && !tv.fullyAvailable" mat-raised-button class="btn-spacing"
|
||||
color="accent" [disabled]>
|
||||
<i class="fa fa-check"></i> {{'Common.PartiallyAvailable' | translate }}</button>
|
||||
<i class="fas fa-check"></i> {{'Common.PartiallyAvailable' | translate }}</button>
|
||||
|
||||
<span *ngIf="tv.available">
|
||||
<a *ngIf="tv.plexUrl" mat-raised-button style="text-align: right"
|
||||
class="btn-spacing btn-greem" href="{{tv.plexUrl}}" target="_blank"><i
|
||||
class="fa fa-eye"></i> {{'Search.ViewOnPlex' |
|
||||
class="far fa-eye"></i> {{'Search.ViewOnPlex' |
|
||||
translate}}</a>
|
||||
<a *ngIf="tv.embyUrl" mat-raised-button class="btn-green btn-spacing" href="{{tv.embyUrl}}"
|
||||
target="_blank"><i class="fa fa-eye"></i> {{'Search.ViewOnEmby' |
|
||||
target="_blank"><i class="far fa-eye"></i> {{'Search.ViewOnEmby' |
|
||||
translate}}</a>
|
||||
<a *ngIf="tv.jellyfinUrl" mat-raised-button class="btn-green btn-spacing" href="{{tv.jellyfinUrl}}"
|
||||
target="_blank"><i class="fa fa-eye"></i> {{'Search.ViewOnJellyfin' |
|
||||
target="_blank"><i class="far fa-eye"></i> {{'Search.ViewOnJellyfin' |
|
||||
translate}}</a>
|
||||
</span>
|
||||
</div>
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</div>
|
||||
<div *ngIf="!discoverResults || discoverResults.length === 0">
|
||||
<div class="row justify-content-md-center top-spacing loading-spinner">
|
||||
<h1> {{'Discovery.NoSearch' | translate}} <i class="fa fa-frown-o" aria-hidden="true"></i></h1>
|
||||
<h1> {{'Discovery.NoSearch' | translate}} <i class="far fa-frown" aria-hidden="true"></i></h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -14,6 +14,8 @@ export interface IPlexOAuthViewModel {
|
|||
|
||||
export interface IPlexOAuthAccessToken {
|
||||
accessToken: string;
|
||||
success: boolean;
|
||||
error: string;
|
||||
}
|
||||
|
||||
export interface IPlexUser {
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
<div *ngFor="let comment of comments" class="row msg_container" [ngClass]="{'base_sent': comment.adminComment, 'base_receive': !comment.adminComment}">
|
||||
<div class="col-md-10 col-xs-10">
|
||||
|
||||
<div class="messages msg_sent"> <i *ngIf="isAdmin" style="float:right;" class="fa fa-times" aria-hidden="true" (click)="deleteComment(comment.id)"></i>
|
||||
<div class="messages msg_sent"> <i *ngIf="isAdmin" style="float:right;" class="fas fa-times" aria-hidden="true" (click)="deleteComment(comment.id)"></i>
|
||||
<p>{{comment.comment}}</p>
|
||||
<time>{{comment.username}} • {{comment.date | amLocal | amDateFormat: 'l LT'}}</time>
|
||||
</div>
|
||||
|
|
|
@ -13,21 +13,21 @@
|
|||
</div>
|
||||
<div class="col-md-4 col-md-push-3 vcenter">
|
||||
<div *ngIf="landingPageSettings.noticeEnabled">
|
||||
<h3><i class="fa fa-bell-o"></i> <b>Notice</b></h3>
|
||||
<h3><i class="far fa-bell"></i> <b>Notice</b></h3>
|
||||
<span [innerHtml]="landingPageSettings.noticeText"></span>
|
||||
</div>
|
||||
<br>
|
||||
<div *ngIf="!mediaServerStatus">
|
||||
<i class="fa fa-spinner fa-spin fa-3x fa-fw"></i>
|
||||
<i class="fas fa-spinner fa-spin fa-3x fa-fw"></i>
|
||||
</div>
|
||||
<div *ngIf="mediaServerStatus">
|
||||
<div *ngIf="mediaServerStatus.fullyAvailable">
|
||||
<h3 class="online"><i class="fa fa-check-circle "></i> {{ 'LandingPage.OnlineHeading' | translate }}</h3>
|
||||
<h3 class="online"><i class="fas fa-check-circle "></i> {{ 'LandingPage.OnlineHeading' | translate }}</h3>
|
||||
<span [translate]="'LandingPage.OnlineParagraph'"></span>
|
||||
<p [translate]="'LandingPage.CheckPageForUpdates'"></p>
|
||||
</div>
|
||||
<div *ngIf="mediaServerStatus.partiallyDown">
|
||||
<h3 class="partial"><i class="fa fa-exclamation-triangle "></i> {{ 'LandingPage.PartiallyOnlineHeading' | translate }}</h3>
|
||||
<h3 class="partial"><i class="fas fa-exclamation-triangle "></i> {{ 'LandingPage.PartiallyOnlineHeading' | translate }}</h3>
|
||||
<span [translate]="'LandingPage.PartiallyOnlineParagraph'"></span>
|
||||
<p *ngIf="mediaServerStatus.serversUnavailable > 1" [translate]="'LandingPage.MultipleServersUnavailable'" [translateParams]="{serversUnavailable: mediaServerStatus.serversUnavailable, totalServers: mediaServerStatus.totalServers}"></p>
|
||||
<p *ngIf="mediaServerStatus.serversUnavailable == 1" [translate]="'LandingPage.SingleServerUnavailable'" [translateParams]="{serversUnavailable: mediaServerStatus.serversUnavailable, totalServers: mediaServerStatus.totalServers}">There is {{mediaServerStatus.serversUnavailable}} server offline out of {{mediaServerStatus.totalServers}}.</p>
|
||||
|
@ -35,7 +35,7 @@
|
|||
</div>
|
||||
|
||||
<div *ngIf="mediaServerStatus.completelyDown">
|
||||
<h3 class="offline"><i class="fa fa-times "></i> {{ 'LandingPage.OfflineHeading' | translate }}</h3>
|
||||
<h3 class="offline"><i class="fas fa-times "></i> {{ 'LandingPage.OfflineHeading' | translate }}</h3>
|
||||
<span [translate]="'LandingPage.OfflineParagraph'"></span>
|
||||
<p [translate]="'LandingPage.CheckPageForUpdates'"></p>
|
||||
</div>
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
<button id="sign-in" mat-raised-button color="primary" type="submit" (click)="loginWithOmbi = true">{{'Login.SignInWith' | translate:appNameTranslate}}</button>
|
||||
<button id="sign-plex" mat-raised-button color="accent" type="button" (click)="oauth()">
|
||||
<span *ngIf="!oauthLoading">{{'Login.SignInWithPlex' | translate}}</span>
|
||||
<span *ngIf="oauthLoading"><i class="fa fa-circle-o-notch fa-spin fa-fw"></i></span>
|
||||
<span *ngIf="oauthLoading"><i class="fas fa-circle-notch fa-spin fa-fw"></i></span>
|
||||
</button>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
|
|
|
@ -23,12 +23,12 @@
|
|||
<div class="col-12 col-lg-6 col-xl-6 media-row">
|
||||
|
||||
<button mat-raised-button *ngIf="selectedAlbums.length === 0" class="btn-spacing" color="primary" (click)="requestAllAlbums()">
|
||||
<i class="fa fa-plus"></i> {{ 'MediaDetails.RequestAllAlbums' | translate }}</button>
|
||||
<i class="fas fa-plus"></i> {{ 'MediaDetails.RequestAllAlbums' | translate }}</button>
|
||||
<button mat-raised-button *ngIf="selectedAlbums.length > 0" class="btn-spacing" color="primary" (click)="requestAllAlbums()">
|
||||
<i class="fa fa-plus"></i> {{ 'MediaDetails.RequestSelectedAlbums' | translate }}</button>
|
||||
<i class="fas fa-plus"></i> {{ 'MediaDetails.RequestSelectedAlbums' | translate }}</button>
|
||||
|
||||
<button mat-raised-button *ngIf="selectedAlbums.length > 0" class="btn-spacing" color="accent" (click)="clearSelection()">
|
||||
<i class="fa fa-minus"></i> {{ 'MediaDetails.ClearSelection' | translate }}</button>
|
||||
<i class="fas fa-minus"></i> {{ 'MediaDetails.ClearSelection' | translate }}</button>
|
||||
|
||||
|
||||
|
||||
|
@ -39,39 +39,39 @@
|
|||
|
||||
<ng-template #requestedBtn>
|
||||
<button mat-raised-button *ngIf="!hasRequest || hasRequest && movieRequest && !movieRequest.denied"
|
||||
class="btn-spacing" color="warn" [disabled]><i class="fa fa-check"></i>
|
||||
class="btn-spacing" color="warn" [disabled]><i class="fas fa-check"></i>
|
||||
{{ 'Common.Requested' | translate }}</button>
|
||||
</ng-template>
|
||||
<ng-template #notRequestedBtn>
|
||||
<button mat-raised-button class="btn-spacing" color="primary" (click)="request()">
|
||||
<i *ngIf="movie.requestProcessing" class="fa fa-circle-o-notch fa-spin fa-fw"></i> <i
|
||||
*ngIf="!movie.requestProcessing && !movie.processed" class="fa fa-plus"></i>
|
||||
<i *ngIf="movie.processed && !movie.requestProcessing" class="fa fa-check"></i> {{
|
||||
<i *ngIf="movie.requestProcessing" class="fas fa-circle-notch fa-spin fa-fw"></i> <i
|
||||
*ngIf="!movie.requestProcessing && !movie.processed" class="fas fa-plus"></i>
|
||||
<i *ngIf="movie.processed && !movie.requestProcessing" class="fas fa-check"></i> {{
|
||||
'Common.Request' | translate }}</button>
|
||||
</ng-template>
|
||||
</span> -->
|
||||
<!-- <span *ngIf="isAdmin && hasRequest">
|
||||
<button (click)="approve()" mat-raised-button class="btn-spacing" color="accent">
|
||||
<i class="fa fa-plus"></i> {{ 'Common.Approve' | translate }}
|
||||
<i class="fas fa-plus"></i> {{ 'Common.Approve' | translate }}
|
||||
</button>
|
||||
<button *ngIf="!movie.available" (click)="markAvailable()" mat-raised-button class="btn-spacing"
|
||||
color="accent">
|
||||
<i class="fa fa-plus"></i> {{ 'Requests.MarkAvailable' | translate }}
|
||||
<i class="fas fa-plus"></i> {{ 'Requests.MarkAvailable' | translate }}
|
||||
</button>
|
||||
|
||||
<button *ngIf="movieRequest && !movieRequest.denied" mat-raised-button class="btn-spacing" color="warn"
|
||||
(click)="deny()">
|
||||
<i class="fa fa-times"></i> {{
|
||||
<i class="fas fa-times"></i> {{
|
||||
'Requests.Deny' | translate }}</button>
|
||||
<button *ngIf="movieRequest && movieRequest.denied" [matTooltip]="movieRequest.deniedReason"
|
||||
mat-raised-button class="btn-spacing" color="warn">
|
||||
<i class="fa fa-times"></i> {{
|
||||
<i class="fas fa-times"></i> {{
|
||||
'MediaDetails.Denied' | translate }}</button>
|
||||
</span> -->
|
||||
|
||||
<!-- <button *ngIf="(hasRequest && movieRequest) || movie.available" mat-raised-button class="btn-spacing"
|
||||
color="danger" (click)="issue()">
|
||||
<i class="fa fa-exclamation"></i> {{
|
||||
<i class="fas fa-exclamation"></i> {{
|
||||
'Requests.ReportIssue' | translate }}</button> -->
|
||||
|
||||
|
||||
|
|
|
@ -32,68 +32,71 @@
|
|||
<section id="info-wrapper">
|
||||
<div class="small-middle-container">
|
||||
|
||||
<div class="row justify-content-center justify-content-sm-start">
|
||||
|
||||
<media-poster [posterPath]="'https://image.tmdb.org/t/p/w300/' + movie.posterPath"></media-poster>
|
||||
<div class="row justify-content-center justify-content-sm-start header-container">
|
||||
<div class="details-poster-container">
|
||||
<media-poster [posterPath]="'https://image.tmdb.org/t/p/w300/' + movie.posterPath"></media-poster>
|
||||
</div>
|
||||
|
||||
<!--Next to poster-->
|
||||
<div class="col-12 col-lg-9 col-xl-9 media-row">
|
||||
<span *ngIf="movie.available">
|
||||
<a *ngIf="movie.plexUrl" href="{{movie.plexUrl}}" mat-raised-button target="_blank" class="btn-spacing viewon-btn plex">
|
||||
{{'Search.ViewOnPlex' | translate}}
|
||||
<i class="fa fa-play-circle fa-2x"></i>
|
||||
</a>
|
||||
<a *ngIf="movie.embyUrl" href="{{movie.embyUrl}}" mat-raised-button target="_blank" class="btn-spacing viewon-btn emby">
|
||||
{{'Search.ViewOnEmby' | translate}}
|
||||
<i class="fa fa-play-circle fa-2x"></i>
|
||||
</a>
|
||||
<a *ngIf="movie.jellyfinUrl" href="{{movie.jellyfinUrl}}" mat-raised-button target="_blank" class="btn-spacing viewon-btn jellyfinUrl">
|
||||
{{'Search.ViewOnJellyfin' | translate}}
|
||||
<i class="fa fa-play-circle fa-2x"></i>
|
||||
</a>
|
||||
</span>
|
||||
<button mat-raised-button class="btn-green btn-spacing" *ngIf="movie.available && !movie.plexUrl && !movie.embyUrl && !movie.jellyfinUrl"> {{
|
||||
'Common.Available' | translate }}</button>
|
||||
<span *ngIf="!movie.available">
|
||||
<span *ngIf="movie.requested || movie.approved; then requestedBtn else notRequestedBtn"></span>
|
||||
<ng-template #requestedBtn>
|
||||
<button mat-raised-button *ngIf="!hasRequest || hasRequest && movieRequest && !movieRequest.denied" class="btn-spacing" color="warn" [disabled]>
|
||||
<i class="fa fa-check"></i>
|
||||
{{ 'Common.Requested' | translate }}
|
||||
</button>
|
||||
</ng-template>
|
||||
<ng-template #notRequestedBtn>
|
||||
<button mat-raised-button class="btn-spacing" color="primary" (click)="request()">
|
||||
<i *ngIf="movie.requestProcessing" class="fa fa-circle-o-notch fa-spin fa-fw"></i>
|
||||
<i *ngIf="!movie.requestProcessing && !movie.processed" class="fa fa-plus"></i>
|
||||
<i *ngIf="movie.processed && !movie.requestProcessing" class="fa fa-check"></i>
|
||||
{{'Common.Request' | translate }}
|
||||
</button>
|
||||
</ng-template>
|
||||
<div class="details-button-container">
|
||||
<div class="col-12 media-row">
|
||||
<span *ngIf="movie.available">
|
||||
<a *ngIf="movie.plexUrl" href="{{movie.plexUrl}}" mat-raised-button target="_blank" class="btn-spacing viewon-btn plex">
|
||||
{{'Search.ViewOnPlex' | translate}}
|
||||
<i class="far fa-play-circle fa-2x"></i>
|
||||
</a>
|
||||
<a *ngIf="movie.embyUrl" href="{{movie.embyUrl}}" mat-raised-button target="_blank" class="btn-spacing viewon-btn emby">
|
||||
{{'Search.ViewOnEmby' | translate}}
|
||||
<i class="far fa-play-circle fa-2x"></i>
|
||||
</a>
|
||||
<a *ngIf="movie.jellyfinUrl" href="{{movie.jellyfinUrl}}" mat-raised-button target="_blank" class="btn-spacing viewon-btn jellyfinUrl">
|
||||
{{'Search.ViewOnJellyfin' | translate}}
|
||||
<i class="far fa-play-circle fa-2x"></i>
|
||||
</a>
|
||||
</span>
|
||||
<span *ngIf="isAdmin && hasRequest">
|
||||
<button *ngIf="!movie.approved" (click)="approve()" mat-raised-button class="btn-spacing" color="accent">
|
||||
<i class="fa fa-plus"></i> {{ 'Common.Approve' | translate }}
|
||||
</button>
|
||||
<button *ngIf="!movie.available" (click)="markAvailable()" mat-raised-button class="btn-spacing"
|
||||
color="accent">
|
||||
<i class="fa fa-plus"></i> {{ 'Requests.MarkAvailable' | translate }}
|
||||
</button>
|
||||
<button mat-raised-button class="btn-green btn-spacing" *ngIf="movie.available && !movie.plexUrl && !movie.embyUrl && !movie.jellyfinUrl"> {{
|
||||
'Common.Available' | translate }}</button>
|
||||
<span *ngIf="!movie.available">
|
||||
<span *ngIf="movie.requested || movie.approved; then requestedBtn else notRequestedBtn"></span>
|
||||
<ng-template #requestedBtn>
|
||||
<button mat-raised-button *ngIf="!hasRequest || hasRequest && movieRequest && !movieRequest.denied" class="btn-spacing" color="warn" [disabled]>
|
||||
<i class="fas fa-check"></i>
|
||||
{{ 'Common.Requested' | translate }}
|
||||
</button>
|
||||
</ng-template>
|
||||
<ng-template #notRequestedBtn>
|
||||
<button mat-raised-button class="btn-spacing" color="primary" (click)="request()">
|
||||
<i *ngIf="movie.requestProcessing" class="fas fa-circle-notch fa-spin fa-fw"></i>
|
||||
<i *ngIf="!movie.requestProcessing && !movie.processed" class="fas fa-plus"></i>
|
||||
<i *ngIf="movie.processed && !movie.requestProcessing" class="fas fa-check"></i>
|
||||
{{'Common.Request' | translate }}
|
||||
</button>
|
||||
</ng-template>
|
||||
</span>
|
||||
<span *ngIf="isAdmin && hasRequest">
|
||||
<button *ngIf="!movie.approved" (click)="approve()" mat-raised-button class="btn-spacing" color="accent">
|
||||
<i class="fas fa-plus"></i> {{ 'Common.Approve' | translate }}
|
||||
</button>
|
||||
<button *ngIf="!movie.available" (click)="markAvailable()" mat-raised-button class="btn-spacing"
|
||||
color="accent">
|
||||
<i class="fas fa-plus"></i> {{ 'Requests.MarkAvailable' | translate }}
|
||||
</button>
|
||||
|
||||
<button *ngIf="movieRequest && !movieRequest.denied && !movie.available" mat-raised-button class="btn-spacing" color="warn" (click)="deny()">
|
||||
<i class="fa fa-times"></i> {{'Requests.Deny' | translate }}
|
||||
</button>
|
||||
<button *ngIf="movieRequest && movieRequest.denied" [matTooltip]="movieRequest.deniedReason" mat-raised-button class="btn-spacing" color="warn">
|
||||
<i class="fa fa-times"></i> {{'MediaDetails.Denied' | translate }}
|
||||
</button>
|
||||
</span>
|
||||
<button *ngIf="movieRequest && !movieRequest.denied && !movie.available" mat-raised-button class="btn-spacing" color="warn" (click)="deny()">
|
||||
<i class="fas fa-times"></i> {{'Requests.Deny' | translate }}
|
||||
</button>
|
||||
<button *ngIf="movieRequest && movieRequest.denied" [matTooltip]="movieRequest.deniedReason" mat-raised-button class="btn-spacing" color="warn">
|
||||
<i class="fas fa-times"></i> {{'MediaDetails.Denied' | translate }}
|
||||
</button>
|
||||
</span>
|
||||
|
||||
<button mat-raised-button class="btn-spacing" color="danger" (click)="issue()">
|
||||
<i class="fa fa-exclamation"></i> {{'Requests.ReportIssue' | translate }}
|
||||
</button>
|
||||
<button *ngIf="movie.belongsToCollection" [routerLink]="'/discover/collection/' + movie.belongsToCollection.id" mat-raised-button class="btn-spacing">
|
||||
<i class="fa fa-list"></i> {{'MediaDetails.ViewCollection' | translate}}
|
||||
</button>
|
||||
<button mat-raised-button class="btn-spacing" color="danger" (click)="issue()">
|
||||
<i class="fas fa-exclamation"></i> {{'Requests.ReportIssue' | translate }}
|
||||
</button>
|
||||
<button *ngIf="movie.belongsToCollection" [routerLink]="'/discover/collection/' + movie.belongsToCollection.id" mat-raised-button class="btn-spacing">
|
||||
<i class="fas fa-list"></i> {{'MediaDetails.ViewCollection' | translate}}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -125,6 +128,28 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="row card-spacer" *ngIf="movie.videos?.results?.length > 0">
|
||||
|
||||
<div class="col-md-6" *ngFor="let video of movie.videos?.results">
|
||||
<iframe width="100%" height="315px" [src]="'https://www.youtube.com/embed/' + video.key | safe" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div class="row" *ngIf="movie.videos?.results?.length > 0">
|
||||
<div class="col-12">
|
||||
<mat-card class="mat-elevation-z8">
|
||||
<mat-card-header>Trailers</mat-card-header>
|
||||
<mat-card-content>
|
||||
<p-carousel class="no-indicator" [numVisible]="2" [numScroll]="10" [page]="0" [value]="movie.videos?.results">
|
||||
<ng-template let-result pTemplate="item">
|
||||
<iframe width="98%" height="315px" [src]="'https://www.youtube.com/embed/' + result.key | safe" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</ng-template>
|
||||
</p-carousel>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="issuesPanel">
|
||||
|
@ -172,20 +197,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
<mat-expansion-panel>
|
||||
<mat-expansion-panel-header>
|
||||
<mat-panel-title>
|
||||
{{'MediaDetails.VideosTitle' | translate}}
|
||||
</mat-panel-title>
|
||||
</mat-expansion-panel-header>
|
||||
|
||||
<div class="row card-spacer" *ngIf="movie.videos?.results?.length > 0">
|
||||
|
||||
<div class="col-md-6" *ngFor="let video of movie.videos?.results">
|
||||
<iframe width="100%" height="315px" [src]="'https://www.youtube.com/embed/' + video.key | safe" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</mat-expansion-panel>
|
||||
</mat-accordion>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,32 +1,32 @@
|
|||
<div class="social-icons-container-inner">
|
||||
<a *ngIf="homepage" class="media-icons" href="{{homepage}}" target="_blank">
|
||||
<i matTooltip="Homepage" class="fa fa-home fa-2x grow-social"></i>
|
||||
<i matTooltip="Homepage" class="sfa-home fa-2x grow-social"></i>
|
||||
</a>
|
||||
<a *ngIf="theMoviedbId" href="https://www.themoviedb.org/movie/{{theMoviedbId}}" class="media-icons"
|
||||
target="_blank">
|
||||
<i matTooltip="The Movie DB" class="fa fa-film fa-2x grow-social"></i>
|
||||
<i matTooltip="The Movie DB" class="fas fa-film fa-2x grow-social"></i>
|
||||
</a>
|
||||
<a *ngIf="tvdbId" href="https://www.thetvdb.com/?id={{tvdbId}}&tab=series" class="media-icons" target="_blank">
|
||||
<i matTooltip="The TV DB" class="fa fa-tv fa-2x grow-social"></i>
|
||||
<i matTooltip="The TV DB" class="fas fa-tv fa-2x grow-social"></i>
|
||||
</a>
|
||||
|
||||
<a *ngIf="hasTrailer" class="media-icons youtube" (click)="openDialog()">
|
||||
<i matTooltip="Trailer" class="fa fa-youtube-play fa-2x grow-social"></i>
|
||||
<i matTooltip="Trailer" class="fab fa-youtube fa-2x grow-social"></i>
|
||||
</a>
|
||||
<a *ngIf="imdbId" class="media-icons imdb" [href]="doNotAppend ? imdbid : 'https://imdb.com/title/' + imdbId" target="_blank">
|
||||
<i matTooltip="Imdb" class="fa fa-imdb fa-2x grow-social"></i>
|
||||
<i matTooltip="Imdb" class="fab fa-imdb fa-2x grow-social"></i>
|
||||
</a>
|
||||
<a *ngIf="twitter" class="media-icons" [href]="doNotAppend ? twitter : 'https://twitter.com/' + twitter" target="_blank">
|
||||
<i matTooltip="Twitter" class="fa fa-twitter fa-2x grow-social"></i>
|
||||
<i matTooltip="Twitter" class="fab fa-twitter fa-2x grow-social"></i>
|
||||
</a>
|
||||
<a *ngIf="facebook" class="media-icons" [href]="doNotAppend ? facebook : 'https://facebook.com/' + facebook" target="_blank">
|
||||
<i matTooltip="Facebook" class="fa fa-facebook fa-2x grow-social"></i>
|
||||
<i matTooltip="Facebook" class="fab fa-facebook fa-2x grow-social"></i>
|
||||
</a> <a *ngIf="instagram" class="media-icons" [href]="doNotAppend ? instagram : 'https://instagram.com/' + instagram" target="_blank">
|
||||
<i matTooltip="Instagram" class="fa fa-instagram fa-2x grow-social"></i>
|
||||
<i matTooltip="Instagram" class="fab fa-instagram fa-2x grow-social"></i>
|
||||
</a>
|
||||
<!-- Setting/Configuration admin area -->
|
||||
<button *ngIf="isAdmin" mat-icon-button [matMenuTriggerFor]="menu">
|
||||
<mat-icon>settings</mat-icon>
|
||||
<button *ngIf="isAdmin" mat-icon-button [matMenuTriggerFor]="menu" class="admin-cog">
|
||||
<i class="fas fa-cog fa-2x "></i>
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<button mat-menu-item (click)="openRequestOnBehalf()" [disabled]="!canRequestOnBehalf">
|
||||
|
|
|
@ -4,3 +4,7 @@ a.media-icons:hover{
|
|||
color:$ombi-active;
|
||||
}
|
||||
|
||||
button.admin-cog{
|
||||
margin-left:40px;
|
||||
color:$ombi-active;
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
|
||||
<section id="summary-wrapper">
|
||||
<div class="full-screenshot enabled" [style.background-image]="background"></div>
|
||||
<div class="shadow-base" [ngClass]="available ? 'available-bottom-border' : ''"></div>
|
||||
<div class="full-screenshot enabled overlay"></div>
|
||||
<!--<div class="shadow-base" [ngClass]="available ? 'available-bottom-border' : ''"></div>-->
|
||||
|
||||
<div class="container summary">
|
||||
<div class="container title-top-banner">
|
||||
|
|
|
@ -8,7 +8,14 @@
|
|||
margin-left:0px;
|
||||
}}
|
||||
|
||||
@media (min-width:2400px){
|
||||
.title-top-banner{
|
||||
padding-left:390px;
|
||||
margin-left:0px;
|
||||
}}
|
||||
|
||||
@media (max-width:571px){
|
||||
.title-top-banner{
|
||||
text-align:center;
|
||||
top:50px;
|
||||
}}
|
|
@ -4,7 +4,7 @@
|
|||
<div *ngIf="tv">
|
||||
<div *ngIf="tv.id === 0; else main">
|
||||
<div class="small-middle-container no-info">
|
||||
<h1><i class="fa fa-frown-o" aria-hidden="true"></i></h1>
|
||||
<h1><i class="far fa-frown-o" aria-hidden="true"></i></h1>
|
||||
<h3> {{ 'MediaDetails.NotEnoughInfo' | translate }}</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -37,18 +37,18 @@
|
|||
<div class="col-12 col-lg-5 col-xl-5 media-row">
|
||||
|
||||
<!-- <button *ngIf="!tv.fullyAvailable" mat-raised-button class="btn-spacing" color="primary"
|
||||
(click)="request()"><i class="fa fa-plus"></i>
|
||||
(click)="request()"><i class="fas fa-plus"></i>
|
||||
{{ 'Common.Request' | translate }}</button> -->
|
||||
|
||||
<button *ngIf="tv.fullyAvailable" mat-raised-button class="btn-spacing" color="accent"
|
||||
[disabled]>
|
||||
<i class="fa fa-check"></i> {{'Common.Available' | translate }}</button>
|
||||
<i class="fas fa-check"></i> {{'Common.Available' | translate }}</button>
|
||||
<button *ngIf="tv.partlyAvailable && !tv.fullyAvailable" mat-raised-button
|
||||
class="btn-spacing" color="accent" [disabled]>
|
||||
<i class="fa fa-check"></i> {{'Common.PartiallyAvailable' | translate }}</button>
|
||||
<i class="fas fa-check"></i> {{'Common.PartiallyAvailable' | translate }}</button>
|
||||
|
||||
<button mat-raised-button class="btn-spacing" color="danger" (click)="issue()">
|
||||
<i class="fa fa-exclamation"></i> {{
|
||||
<i class="fas fa-exclamation"></i> {{
|
||||
'Requests.ReportIssue' | translate }}</button>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -14,12 +14,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
#summary-wrapper {
|
||||
height: 350px !important;
|
||||
}
|
||||
}
|
||||
|
||||
#summary-wrapper .full-screenshot,
|
||||
.summary-wrapper .full-screenshot,
|
||||
#watching-wrapper .full-screenshot,
|
||||
|
@ -43,7 +37,7 @@
|
|||
background-size: cover;
|
||||
background-position: 50% 10%;
|
||||
transition: all .5s;
|
||||
height: 300px;
|
||||
height: 600px;
|
||||
color: #fff;
|
||||
position: relative;
|
||||
}
|
||||
|
@ -85,7 +79,7 @@
|
|||
#summary-wrapper .summary .container,
|
||||
.summary-wrapper .summary .container {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
bottom: 300px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
@ -176,7 +170,8 @@
|
|||
}
|
||||
|
||||
.media-row {
|
||||
padding-top: 2%;
|
||||
padding-top: 56px;
|
||||
padding-left: 26px;
|
||||
}
|
||||
|
||||
.cast-profile-img {
|
||||
|
@ -235,7 +230,7 @@
|
|||
text-align:right;
|
||||
display:flex;
|
||||
justify-content: flex-end;
|
||||
padding-right:2em;
|
||||
padding-right:2.5%
|
||||
}
|
||||
|
||||
.viewon-btn {
|
||||
|
@ -255,3 +250,27 @@
|
|||
border: 1px solid #00a4dc;
|
||||
color: #00a4dc;
|
||||
}
|
||||
|
||||
::ng-deep .p-carousel-indicators {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
|
||||
#info-wrapper{
|
||||
margin-top:-200px;
|
||||
}
|
||||
.full-screenshot.enabled.overlay{
|
||||
background-image: linear-gradient(to bottom, transparent, 50%, $ombi-background-primary);
|
||||
}
|
||||
|
||||
.row.justify-content-center.justify-content-sm-start.header-container{
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.details-button-container{
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.info-wrapper .row{
|
||||
flex-wrap:wrap;
|
||||
}
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
<mat-icon *ngIf="nav.icon" aria-label="Side nav toggle icon" [style]="nav.style">{{nav.icon}}
|
||||
</mat-icon>
|
||||
<i *ngIf="nav.faIcon" class="fa fa-lg {{nav.faIcon}}"
|
||||
<i *ngIf="nav.faIcon" class="far fa-lg {{nav.faIcon}}"
|
||||
style="padding-left: 5px; padding-right: 5px;" aria-hidden="true"></i>
|
||||
{{nav.name | translate}}
|
||||
</a>
|
||||
|
|
|
@ -87,7 +87,7 @@ export class MyNavComponent implements OnInit {
|
|||
// { name: "NavigationBar.Calendar", icon: "calendar_today", link: "/calendar", requiresAdmin: false, enabled: true },
|
||||
{ name: "NavigationBar.Donate", icon: "attach_money", link: "https://www.paypal.me/PlexRequestsNet", externalLink: true, requiresAdmin: true, enabled: true, toolTip: true, style: "color:red;", toolTipMessage: 'NavigationBar.DonateTooltip', faIcon: null },
|
||||
{ name: "NavigationBar.Donate", icon: "attach_money", link: customizationSettings.customDonationUrl, externalLink: true, requiresAdmin: false, enabled: customizationSettings.enableCustomDonations, toolTip: true, toolTipMessage: customizationSettings.customDonationMessage, faIcon: null },
|
||||
{ name: "NavigationBar.FeatureSuggestion", icon: null, link: "https://features.ombi.io/", externalLink: true, requiresAdmin: true, enabled: true, toolTip: true, toolTipMessage: 'NavigationBar.FeatureSuggestionTooltip', faIcon: "fa-lightbulb-o" },
|
||||
{ name: "NavigationBar.FeatureSuggestion", icon: null, link: "https://features.ombi.io/", externalLink: true, requiresAdmin: true, enabled: true, toolTip: true, toolTipMessage: 'NavigationBar.FeatureSuggestionTooltip', faIcon: "fa-lightbulb" },
|
||||
{ name: "NavigationBar.Settings", icon: "settings", link: "/Settings/About", requiresAdmin: true, enabled: true, faIcon: null },
|
||||
{ name: "NavigationBar.UserPreferences", icon: "person", link: "/user-preferences", requiresAdmin: false, enabled: true, faIcon: null },
|
||||
];
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
(keyup)="search($event)">
|
||||
<span class="input-group-btn">
|
||||
<button id="filterBtn" class="btn btn-sm btn-info-outline" (click)="filterDisplay = !filterDisplay">
|
||||
<i class="fa fa-filter"></i> {{ 'Requests.Filter' | translate }}
|
||||
<i class="fas fa-filter"></i> {{ 'Requests.Filter' | translate }}
|
||||
</button>
|
||||
|
||||
|
||||
<button class="btn btn-sm btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown"
|
||||
aria-haspopup="true" aria-expanded="true">
|
||||
<i class="fa fa-sort"></i> {{ 'Requests.Sort' | translate }}
|
||||
<i class="fas fa-sort"></i> {{ 'Requests.Sort' | translate }}
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu2">
|
||||
|
@ -93,7 +93,7 @@
|
|||
</div>
|
||||
<div *ngIf="request.denied" id="requestDenied">
|
||||
{{ 'Requests.Denied' | translate }}
|
||||
<i style="color:red;" class="fa fa-check" pTooltip="{{request.deniedReason}}"></i>
|
||||
<i style="color:red;" class="fas fa-check" pTooltip="{{request.deniedReason}}"></i>
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -124,11 +124,11 @@
|
|||
|
||||
<a *ngIf="request.showSubscribe && !request.subscribed" style="color:white" (click)="subscribe(request)"
|
||||
pTooltip="Subscribe for notifications">
|
||||
<i class="fa fa-rss"></i>
|
||||
<i class="fas fa-rss"></i>
|
||||
</a>
|
||||
<a *ngIf="request.showSubscribe && request.subscribed" style="color:red" (click)="unSubscribe(request)"
|
||||
pTooltip="Unsubscribe notification">
|
||||
<i class="fa fa-rss"></i>
|
||||
<i class="fas fa-rss"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -137,14 +137,14 @@
|
|||
<form>
|
||||
<button (click)="approve(request)" style="text-align: right" class="btn btn-sm btn-success-outline approve"
|
||||
type="submit">
|
||||
<i class="fa fa-plus"></i> {{ 'Common.Approve' | translate }}
|
||||
<i class="fas fa-plus"></i> {{ 'Common.Approve' | translate }}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!--Radarr Root Folder-->
|
||||
<div *ngIf="radarrRootFolders?.length > 1" class="btn-group btn-split" id="rootFolderBtn">
|
||||
<button type="button" class="btn btn-sm btn-warning-outline">
|
||||
<i class="fa fa-plus"></i> {{ 'Requests.ChangeRootFolder' | translate }}
|
||||
<i class="fas fa-plus"></i> {{ 'Requests.ChangeRootFolder' | translate }}
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning-outline dropdown-toggle" data-toggle="dropdown"
|
||||
aria-haspopup="true" aria-expanded="false">
|
||||
|
@ -161,7 +161,7 @@
|
|||
<!--Radarr Quality Profiles -->
|
||||
<div *ngIf="radarrProfiles?.length > 1" class="btn-group btn-split" id="changeQualityBtn">
|
||||
<button type="button" class="btn btn-sm btn-warning-outline">
|
||||
<i class="fa fa-plus"></i> {{ 'Requests.ChangeQualityProfile' | translate }}
|
||||
<i class="fas fa-plus"></i> {{ 'Requests.ChangeQualityProfile' | translate }}
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning-outline dropdown-toggle" data-toggle="dropdown"
|
||||
aria-haspopup="true" aria-expanded="false">
|
||||
|
@ -177,7 +177,7 @@
|
|||
|
||||
<div *ngIf="!request.denied" id="denyBtn">
|
||||
<button type="button" (click)="deny(request)" class="btn btn-sm btn-danger-outline deny">
|
||||
<i class="fa fa-times"></i> {{ 'Requests.Deny' | translate }}
|
||||
<i class="fas fa-times"></i> {{ 'Requests.Deny' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -186,11 +186,11 @@
|
|||
<form id="markBtnGroup">
|
||||
<button id="unavailableBtn" *ngIf="request.available" (click)="changeAvailability(request, false)"
|
||||
style="text-align: right" value="false" class="btn btn-sm btn-info-outline change">
|
||||
<i class="fa fa-minus"></i> {{ 'Requests.MarkUnavailable' | translate }}
|
||||
<i class="fas fa-minus"></i> {{ 'Requests.MarkUnavailable' | translate }}
|
||||
</button>
|
||||
<button id="availableBtn" *ngIf="!request.available" (click)="changeAvailability(request, true)"
|
||||
style="text-align: right" value="true" class="btn btn-sm btn-success-outline change">
|
||||
<i class="fa fa-plus"></i> {{ 'Requests.MarkAvailable' | translate }}
|
||||
<i class="fas fa-plus"></i> {{ 'Requests.MarkAvailable' | translate }}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
|
@ -200,14 +200,14 @@
|
|||
<div *ngIf="isAdmin || isRequestUser(request)">
|
||||
<form>
|
||||
<button id="removeBtn" (click)="removeRequest(request)" style="text-align: right" class="btn btn-sm btn-danger-outline delete">
|
||||
<i class="fa fa-minus"></i> {{ 'Requests.Remove' | translate }}
|
||||
<i class="fas fa-minus"></i> {{ 'Requests.Remove' | translate }}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="dropdown" *ngIf="issueCategories && issuesEnabled" id="issuesBtn">
|
||||
<button class="btn btn-sm btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown"
|
||||
aria-haspopup="true" aria-expanded="true">
|
||||
<i class="fa fa-plus"></i> {{ 'Requests.ReportIssue' | translate }}
|
||||
<i class="fas fa-plus"></i> {{ 'Requests.ReportIssue' | translate }}
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||
|
@ -284,5 +284,5 @@
|
|||
</div>
|
||||
|
||||
<button class="btn btn-sm btn-primary-outline" (click)="clearFilter($event)">
|
||||
<i class="fa fa-filter"></i> {{ 'Filter.ClearFilter' | translate }}</button>
|
||||
<i class="fas fa-filter"></i> {{ 'Filter.ClearFilter' | translate }}</button>
|
||||
</p-sidebar>
|
||||
|
|
|
@ -4,13 +4,13 @@
|
|||
(keyup)="search($event)">
|
||||
<span class="input-group-btn">
|
||||
<button id="filterBtn" class="btn btn-sm btn-info-outline" (click)="filterDisplay = !filterDisplay">
|
||||
<i class="fa fa-filter"></i> {{ 'Requests.Filter' | translate }}
|
||||
<i class="fas fa-filter"></i> {{ 'Requests.Filter' | translate }}
|
||||
</button>
|
||||
|
||||
|
||||
<button class="btn btn-sm btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown"
|
||||
aria-haspopup="true" aria-expanded="true">
|
||||
<i class="fa fa-sort"></i> {{ 'Requests.Sort' | translate }}
|
||||
<i class="fas fa-sort"></i> {{ 'Requests.Sort' | translate }}
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu2">
|
||||
|
@ -91,7 +91,7 @@
|
|||
[translate]="'Common.ProcessingRequest'"></span>
|
||||
<span *ngIf="request.denied" class="label label-danger" id="requestDeclinedLabel" [translate]="'Common.RequestDenied'"></span>
|
||||
<span *ngIf="request.deniedReason" title="{{request.deniedReason}}">
|
||||
<i class="fa fa-info-circle"></i>
|
||||
<i class="fas fa-info-circle"></i>
|
||||
</span>
|
||||
<span *ngIf="!request.approved && !request.availble && !request.denied" id="pendingApprovalLabel"
|
||||
class="label label-warning" [translate]="'Common.PendingApproval'"></span>
|
||||
|
@ -99,7 +99,7 @@
|
|||
</div>
|
||||
<div *ngIf="request.denied" id="requestDenied">
|
||||
{{ 'Requests.Denied' | translate }}
|
||||
<i style="color:red;" class="fa fa-check" pTooltip="{{request.deniedReason}}"></i>
|
||||
<i style="color:red;" class="fas fa-check" pTooltip="{{request.deniedReason}}"></i>
|
||||
|
||||
</div>
|
||||
|
||||
|
@ -125,10 +125,10 @@
|
|||
<div class="col-md-2 col-md-push-6">
|
||||
|
||||
<a *ngIf="request.showSubscribe && !request.subscribed" style="color:white" (click)="subscribe(request)" pTooltip="Subscribe for notifications">
|
||||
<i class="fa fa-rss"></i>
|
||||
<i class="fas fa-rss"></i>
|
||||
</a>
|
||||
<a *ngIf="request.showSubscribe && request.subscribed" style="color:red" (click)="unSubscribe(request)" pTooltip="Unsubscribe notification">
|
||||
<i class="fa fa-rss"></i>
|
||||
<i class="fas fa-rss"></i>
|
||||
</a>
|
||||
</div>
|
||||
</div> -->
|
||||
|
@ -137,14 +137,14 @@
|
|||
<form class="col-md-6">
|
||||
<button (click)="approve(request)" style="text-align: right" class="btn btn-sm btn-success-outline approve"
|
||||
type="submit">
|
||||
<i class="fa fa-plus"></i> {{ 'Common.Approve' | translate }}
|
||||
<i class="fas fa-plus"></i> {{ 'Common.Approve' | translate }}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<!--Radarr Root Folder-->
|
||||
<!-- <div *ngIf="radarrRootFolders" class="btn-group btn-split" id="rootFolderBtn">
|
||||
<button type="button" class="btn btn-sm btn-warning-outline">
|
||||
<i class="fa fa-plus"></i> {{ 'Requests.ChangeRootFolder' | translate }}
|
||||
<i class="fas fa-plus"></i> {{ 'Requests.ChangeRootFolder' | translate }}
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning-outline dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="caret"></span>
|
||||
|
@ -160,7 +160,7 @@
|
|||
<!--Radarr Quality Profiles -->
|
||||
<!-- <div *ngIf="radarrProfiles" class="btn-group btn-split" id="changeQualityBtn">
|
||||
<button type="button" class="btn btn-sm btn-warning-outline">
|
||||
<i class="fa fa-plus"></i> {{ 'Requests.ChangeQualityProfile' | translate }}
|
||||
<i class="fas fa-plus"></i> {{ 'Requests.ChangeQualityProfile' | translate }}
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning-outline dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="caret"></span>
|
||||
|
@ -175,7 +175,7 @@
|
|||
|
||||
<div *ngIf="!request.denied" id="denyBtn" class="col-md-6">
|
||||
<button type="button" (click)="deny(request)" class="btn btn-sm btn-danger-outline deny">
|
||||
<i class="fa fa-times"></i> {{ 'Requests.Deny' | translate }}
|
||||
<i class="fas fa-times"></i> {{ 'Requests.Deny' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -184,11 +184,11 @@
|
|||
<form id="markBtnGroup">
|
||||
<button id="unavailableBtn" *ngIf="request.available" (click)="changeAvailability(request, false)"
|
||||
style="text-align: right" value="false" class="btn btn-sm btn-info-outline change">
|
||||
<i class="fa fa-minus"></i> {{ 'Requests.MarkUnavailable' | translate }}
|
||||
<i class="fas fa-minus"></i> {{ 'Requests.MarkUnavailable' | translate }}
|
||||
</button>
|
||||
<button id="availableBtn" *ngIf="!request.available" (click)="changeAvailability(request, true)"
|
||||
style="text-align: right" value="true" class="btn btn-sm btn-success-outline change">
|
||||
<i class="fa fa-plus"></i> {{ 'Requests.MarkAvailable' | translate }}
|
||||
<i class="fas fa-plus"></i> {{ 'Requests.MarkAvailable' | translate }}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
|
@ -198,14 +198,14 @@
|
|||
<div *ngIf="isAdmin || isRequestUser(request)">
|
||||
<form id="removeBtn">
|
||||
<button (click)="removeRequest(request)" style="text-align: right" class="btn btn-sm btn-danger-outline delete">
|
||||
<i class="fa fa-minus"></i> {{ 'Requests.Remove' | translate }}
|
||||
<i class="fas fa-minus"></i> {{ 'Requests.Remove' | translate }}
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="dropdown" *ngIf="issueCategories && issuesEnabled" id="issuesBtn">
|
||||
<button class="btn btn-sm btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown"
|
||||
aria-haspopup="true" aria-expanded="true">
|
||||
<i class="fa fa-plus"></i> {{ 'Requests.ReportIssue' | translate }}
|
||||
<i class="fas fa-plus"></i> {{ 'Requests.ReportIssue' | translate }}
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||
|
@ -274,7 +274,7 @@
|
|||
</div>
|
||||
|
||||
<button class="btn btn-sm btn-primary-outline" (click)="clearFilter($event)">
|
||||
<i class="fa fa-filter"></i> {{ 'Filter.ClearFilter' | translate }}</button>
|
||||
<i class="fas fa-filter"></i> {{ 'Filter.ClearFilter' | translate }}</button>
|
||||
</p-sidebar>
|
||||
|
||||
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
|
||||
<ul id="nav-tabs" class="nav nav-tabs" role="tablist">
|
||||
<li role="presentation" class="active">
|
||||
<a id="movieTabButton" aria-controls="home" role="tab" data-toggle="tab" (click)="selectMovieTab()" href="#movieTab"><i class="fa fa-film"></i> {{ 'Requests.MoviesTab' | translate }}</a>
|
||||
<a id="movieTabButton" aria-controls="home" role="tab" data-toggle="tab" (click)="selectMovieTab()" href="#movieTab"><i class="fas fa-film"></i> {{ 'Requests.MoviesTab' | translate }}</a>
|
||||
</li>
|
||||
<li role="presentation">
|
||||
<a id="tvTabButton" aria-controls="profile" role="tab" data-toggle="tab" (click)="selectTvTab()" href="#tvTab"><i class="fa fa-television"></i> {{ 'Requests.TvTab' | translate }}</a>
|
||||
<a id="tvTabButton" aria-controls="profile" role="tab" data-toggle="tab" (click)="selectTvTab()" href="#tvTab"><i class="fas fa-tv"></i> {{ 'Requests.TvTab' | translate }}</a>
|
||||
|
||||
</li>
|
||||
<li role="presentation" *ngIf="musicEnabled">
|
||||
<a id="albumTabButton" aria-controls="profile" role="tab" data-toggle="tab" (click)="selectMusicTab()" href="#albumTab"><i class="fa fa-music"></i> {{ 'Requests.MusicTab' | translate }}</a>
|
||||
<a id="albumTabButton" aria-controls="profile" role="tab" data-toggle="tab" (click)="selectMusicTab()" href="#albumTab"><i class="fas fa-music"></i> {{ 'Requests.MusicTab' | translate }}</a>
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -16,29 +16,29 @@
|
|||
<div class="col-md-1 col-md-push-9">
|
||||
<button id="subscribeBtn" *ngIf="child.showSubscribe && !child.subscribed" (click)="subscribe(child)"
|
||||
class="btn btn-sm btn-primary-outline" pTooltip="Subscribe for notifications" type="submit"><i
|
||||
class="fa fa-rss"></i> Subscribe</button>
|
||||
class="fas fa-rss"></i> Subscribe</button>
|
||||
<button id="subscribeBtn" *ngIf="child.showSubscribe && child.subscribed" (click)="unSubscribe(child)"
|
||||
class="btn btn-sm btn-danger-outline" pTooltip="UnSubscribe for notifications" type="submit"><i
|
||||
class="fa fa-rss"></i> UnSubscribe</button>
|
||||
class="fas fa-rss"></i> UnSubscribe</button>
|
||||
|
||||
|
||||
<div *ngIf="isAdmin">
|
||||
<button id="approveBtn" *ngIf="child.canApprove && !child.approved" (click)="approve(child)" class="btn btn-sm btn-success-outline"
|
||||
type="submit"><i class="fa fa-plus"></i> {{ 'Common.Approve' | translate }}</button>
|
||||
type="submit"><i class="fas fa-plus"></i> {{ 'Common.Approve' | translate }}</button>
|
||||
<button id="unavailableBtn" *ngIf="child.available" (click)="changeAvailability(child, false)"
|
||||
style="text-align: right" value="false" class="btn btn-sm btn-info-outline change"><i class="fa fa-minus"></i>
|
||||
style="text-align: right" value="false" class="btn btn-sm btn-info-outline change"><i class="fas fa-minus"></i>
|
||||
{{ 'Requests.MarkUnavailable' | translate }}</button>
|
||||
<button id="availableBtn" *ngIf="!child.available" (click)="changeAvailability(child, true)" style="text-align: right"
|
||||
value="true" class="btn btn-sm btn-success-outline change"><i class="fa fa-plus"></i> {{
|
||||
value="true" class="btn btn-sm btn-success-outline change"><i class="fas fa-plus"></i> {{
|
||||
'Requests.MarkAvailable' | translate }}</button>
|
||||
|
||||
<button id="denyBtn" *ngIf="!child.denied" type="button" (click)="deny(child)" class="btn btn-sm btn-danger-outline deny">
|
||||
<i class="fa fa-times"></i> {{ 'Requests.Deny' | translate }}</button>
|
||||
<i class="fas fa-times"></i> {{ 'Requests.Deny' | translate }}</button>
|
||||
|
||||
</div>
|
||||
<div *ngIf="isAdmin || isRequestUser(child)">
|
||||
<button id="removeBtn" type="button" (click)="removeRequest(child)" class="btn btn-sm btn-danger-outline deny"><i
|
||||
class="fa fa-times"></i> {{ 'Requests.Remove' | translate }}</button>
|
||||
class="fas fa-times"></i> {{ 'Requests.Remove' | translate }}</button>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -91,7 +91,7 @@
|
|||
<td>
|
||||
<span *ngIf="child.denied" class="label label-danger" id="deniedLabel"
|
||||
[translate]="'Common.Denied'">
|
||||
<i style="color:red;" class="fa fa-check" pTooltip="{{child.deniedReason}}"></i>
|
||||
<i style="color:red;" class="fas fa-check" pTooltip="{{child.deniedReason}}"></i>
|
||||
</span>
|
||||
<span *ngIf="!child.denied && ep.available" class="label label-success" id="availableLabel"
|
||||
[translate]="'Common.Available'"></span>
|
||||
|
|
|
@ -47,12 +47,12 @@
|
|||
<div class="col-sm-3 col-sm-push-3 small-padding">
|
||||
|
||||
<button style="text-align: right" class="btn btn-sm btn-success-outline" (click)="openClosestTab(node,$event)">
|
||||
<i class="fa fa-plus"></i> View</button>
|
||||
<i class="fas fa-plus"></i> View</button>
|
||||
<div *ngIf="isAdmin">
|
||||
<!--Sonarr Root Folder-->
|
||||
<div *ngIf="sonarrRootFolders?.length > 1" class="btn-group btn-split" id="rootFolderBtn">
|
||||
<button type="button" class="btn btn-sm btn-warning-outline">
|
||||
<i class="fa fa-plus"></i> {{ 'Requests.ChangeRootFolder' | translate }}
|
||||
<i class="fas fa-plus"></i> {{ 'Requests.ChangeRootFolder' | translate }}
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning-outline dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="caret"></span>
|
||||
|
@ -68,7 +68,7 @@
|
|||
<!--Sonarr Quality Profiles -->
|
||||
<div *ngIf="sonarrProfiles?.length > 1" class="btn-group btn-split" id="changeQualityBtn">
|
||||
<button type="button" class="btn btn-sm btn-warning-outline">
|
||||
<i class="fa fa-plus"></i> {{ 'Requests.ChangeQualityProfile' | translate }}
|
||||
<i class="fas fa-plus"></i> {{ 'Requests.ChangeQualityProfile' | translate }}
|
||||
</button>
|
||||
<button type="button" class="btn btn-warning-outline dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||||
<span class="caret"></span>
|
||||
|
@ -84,7 +84,7 @@
|
|||
</div>
|
||||
<div class="dropdown" *ngIf="issueCategories && issuesEnabled" id="issueBtn">
|
||||
<button class="btn btn-sm btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
<i class="fa fa-plus"></i> {{ 'Requests.ReportIssue' | translate }}
|
||||
<i class="fas fa-plus"></i> {{ 'Requests.ReportIssue' | translate }}
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<div class="btn-group" role="group">
|
||||
<a href="#" class="btn btn-sm btn-primary-outline dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
|
||||
{{ 'Search.Suggestions' | translate }}
|
||||
<i class="fa fa-chevron-down"></i>
|
||||
<i class="fa-list fa-chevron-down"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a (click)="popularMovies()" [translate]="'Search.Movies.PopularMovies'"></a></li>
|
||||
|
@ -15,7 +15,7 @@
|
|||
</ul>
|
||||
<button class="btn btn-sm btn-primary-outline" (click)="refineOpen()">
|
||||
{{ 'Search.Refine' | translate }}
|
||||
<i class="fa" [ngClass]="{'fa-chevron-down': !refineSearchEnabled, 'fa-chevron-up': refineSearchEnabled}"></i>
|
||||
<i class="fas" [ngClass]="{'fa-chevron-down': !refineSearchEnabled, 'fa-chevron-up': refineSearchEnabled}"></i>
|
||||
</button>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
@ -28,7 +28,7 @@
|
|||
<div class="search-button-container-inline">
|
||||
<ng-template [ngTemplateOutlet]="FilterRef"></ng-template>
|
||||
</div>
|
||||
<i class="fa fa-search"></i>
|
||||
<i class="fas fa-search"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -77,7 +77,7 @@
|
|||
<!-- 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>
|
||||
<i class='fas fa-film no-search-results-icon'></i>
|
||||
<div class='no-search-results-text' [translate]="'Search.NoResults'"></div>
|
||||
</div>
|
||||
|
||||
|
@ -132,50 +132,50 @@
|
|||
|
||||
<div class="col-sm-2 small-padding">
|
||||
<div *ngIf="result.available">
|
||||
<button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fa fa-check"></i>
|
||||
<button style="text-align: right" class="btn btn-success-outline disabled" disabled><i class="fas fa-check"></i>
|
||||
{{ 'Common.Available' | translate }}</button>
|
||||
</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> {{ 'Common.Requested' | translate }}</button>
|
||||
class="fas fa-check"></i> {{ 'Common.Requested' | translate }}</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> {{
|
||||
<i *ngIf="result.requestProcessing" class="fas fa-circle-notch fa-spin fa-fw"></i> <i
|
||||
*ngIf="!result.requestProcessing && !result.processed" class="fas fa-plus"></i>
|
||||
<i *ngIf="result.processed && !result.requestProcessing" class="fas fa-check"></i> {{
|
||||
'Common.Request' | translate }}</button>
|
||||
</ng-template>
|
||||
</div>
|
||||
<div *ngIf="result.requested">
|
||||
<a *ngIf="result.showSubscribe && !result.subscribed" style="text-align: right" class="btn btn btn-success-outline"
|
||||
(click)="subscribe(result)" pTooltip="Subscribe for notifications when this movie becomes available">
|
||||
<i class="fa fa-rss"></i> Subscribe</a>
|
||||
<i class="fas fa-rss"></i> Subscribe</a>
|
||||
<a *ngIf="result.showSubscribe && result.subscribed" style="text-align: right;" class="btn btn btn-warning-outline"
|
||||
(click)="unSubscribe(result)" pTooltip="Unsubscribe notifications when this movie becomes available">
|
||||
<i class="fa fa-rss"></i> Unsubscribe</a>
|
||||
<i class="fas fa-rss"></i> Unsubscribe</a>
|
||||
</div>
|
||||
<button style="text-align: right" class="btn btn-sm btn-info-outline" (click)="similarMovies(result.id)">
|
||||
<i class="fa fa-eye"></i> {{ 'Search.Similar' | translate }}</button>
|
||||
<i class="far fa-eye"></i> {{ 'Search.Similar' | translate }}</button>
|
||||
|
||||
<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> {{'Search.ViewOnPlex' | translate}}</a>
|
||||
target="_blank"><i class="far fa-eye"></i> {{'Search.ViewOnPlex' | translate}}</a>
|
||||
<a *ngIf="result.embyUrl" style="text-align: right" id="embybtn" class="btn btn-sm btn-success-outline"
|
||||
href="{{result.embyUrl}}" target="_blank"><i class="fa fa-eye"></i> {{'Search.ViewOnEmby' |
|
||||
href="{{result.embyUrl}}" target="_blank"><i class="far fa-eye"></i> {{'Search.ViewOnEmby' |
|
||||
translate}}</a>
|
||||
<a *ngIf="result.jellyfinUrl" style="text-align: right" id="jellyfinbtn" class="btn btn-sm btn-success-outline"
|
||||
href="{{result.jellyfinUrl}}" target="_blank"><i class="fa fa-eye"></i> {{'Search.ViewOnJellyfin' |
|
||||
href="{{result.jellyfinUrl}}" target="_blank"><i class="far fa-eye"></i> {{'Search.ViewOnJellyfin' |
|
||||
translate}}</a>
|
||||
</div>
|
||||
<div class="dropdown" *ngIf="result.available && issueCategories && issuesEnabled">
|
||||
<button class="btn btn-sm btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown"
|
||||
aria-haspopup="true" aria-expanded="true">
|
||||
<i class="fa fa-plus"></i> {{'Requests.ReportIssue' | translate}}
|
||||
<i class="fas fa-plus"></i> {{'Requests.ReportIssue' | translate}}
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<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>
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
|
@ -23,7 +23,7 @@
|
|||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<i id="movieSearchButton" class="fa fa-search"></i>
|
||||
<i id="movieSearchButton" class="fas fa-search"></i>
|
||||
</div>
|
||||
</div>
|
||||
<br />
|
||||
|
@ -31,7 +31,7 @@
|
|||
<!-- 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>
|
||||
<i class='fas fa-film no-search-results-icon'></i>
|
||||
<div class='no-search-results-text'>Sorry, we didn't find any results!</div>
|
||||
</div>
|
||||
|
||||
|
@ -108,13 +108,13 @@
|
|||
|
||||
<div *ngIf="result.available">
|
||||
<button style="text-align: right" class="btn btn-success-outline disabled" disabled>
|
||||
<i class="fa fa-check"></i> Available</button>
|
||||
<i class="fas 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>
|
||||
<i class="far fa-eye"></i> View In Plex</a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
@ -122,20 +122,20 @@
|
|||
<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>
|
||||
<i class="fas 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>
|
||||
<i *ngIf="result.requestProcessing" class="fas fa-circle-notch fa-spin fa-fw"></i>
|
||||
<i *ngIf="!result.requestProcessing && !result.processed" class="fas fa-plus"></i>
|
||||
<i *ngIf="result.processed && !result.requestProcessing" class="fas 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>
|
||||
<i class="far fa-eye"></i> View On Plex</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -71,25 +71,25 @@
|
|||
<!-- <div class="row" *ngIf="result.requested">
|
||||
<div class="col-md-2 col-md-push-10">
|
||||
|
||||
<a *ngIf="result.showSubscribe && !result.subscribed" style="color:white" (click)="subscribe(result)" pTooltip="Subscribe for notifications"> <i class="fa fa-rss"></i></a>
|
||||
<a *ngIf="result.showSubscribe && result.subscribed" style="color:red" (click)="unSubscribe(result)" pTooltip="Unsubscribe notification"> <i class="fa fa-rss"></i></a>
|
||||
<a *ngIf="result.showSubscribe && !result.subscribed" style="color:white" (click)="subscribe(result)" pTooltip="Subscribe for notifications"> <i class="fas fa-rss"></i></a>
|
||||
<a *ngIf="result.showSubscribe && result.subscribed" style="color:red" (click)="unSubscribe(result)" pTooltip="Unsubscribe notification"> <i class="fas fa-rss"></i></a>
|
||||
</div>
|
||||
</div> -->
|
||||
<div *ngIf="result.fullyAvailable">
|
||||
<button style="text-align: right" class="btn btn-success-outline disabled" disabled>
|
||||
<i class="fa fa-check"></i> {{ 'Common.Available' | translate }}</button>
|
||||
<i class="fas fa-check"></i> {{ 'Common.Available' | translate }}</button>
|
||||
</div>
|
||||
<div *ngIf="!result.fullyAvailable">
|
||||
<div *ngIf="result.requested || result.approved || result.monitored; 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> {{ 'Common.Requested' | translate }}</button>
|
||||
<i class="fas fa-check"></i> {{ 'Common.Requested' | translate }}</button>
|
||||
</ng-template>
|
||||
<ng-template #notRequestedBtn>
|
||||
<button 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> {{ 'Common.Request'
|
||||
<i *ngIf="result.requestProcessing" class="fas fa-circle-notch fa-spin fa-fw"></i>
|
||||
<i *ngIf="!result.requestProcessing && !result.processed" class="fas fa-plus"></i>
|
||||
<i *ngIf="result.processed && !result.requestProcessing" class="fas fa-check"></i> {{ 'Common.Request'
|
||||
| translate }}</button>
|
||||
</ng-template>
|
||||
</div>
|
||||
|
@ -98,7 +98,7 @@
|
|||
<div class="dropdown" *ngIf="(result.partiallyAvailable || result.fullyAvailable) && issueCategories && issuesEnabled">
|
||||
<button class="btn btn-sm btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true"
|
||||
aria-expanded="true">
|
||||
<i class="fa fa-plus"></i> Report Issue
|
||||
<i class="fas fa-plus"></i> Report Issue
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||
|
|
|
@ -47,15 +47,15 @@
|
|||
<div class="row" *ngIf="result.requested">
|
||||
<div class="col-md-2 col-md-push-10">
|
||||
|
||||
<!-- <a *ngIf="result.showSubscribe && !result.subscribed" style="color:white" (click)="subscribe(result)" pTooltip="Subscribe for notifications"> <i class="fa fa-rss"></i></a>
|
||||
<a *ngIf="result.showSubscribe && result.subscribed" style="color:red" (click)="unSubscribe(result)" pTooltip="Unsubscribe notification"> <i class="fa fa-rss"></i></a> -->
|
||||
<!-- <a *ngIf="result.showSubscribe && !result.subscribed" style="color:white" (click)="subscribe(result)" pTooltip="Subscribe for notifications"> <i class="fas fa-rss"></i></a>
|
||||
<a *ngIf="result.showSubscribe && result.subscribed" style="color:red" (click)="unSubscribe(result)" pTooltip="Unsubscribe notification"> <i class="fas fa-rss"></i></a> -->
|
||||
</div>
|
||||
</div>
|
||||
<button style="text-align: right" class="btn btn-info-outline" [disabled]="searchingAlbums" (click)="viewAllAlbums()">
|
||||
<i class="fa fa-eye"></i> View Albums</button>
|
||||
<i class="far fa-eye"></i> View Albums</button>
|
||||
|
||||
</div>
|
||||
<!-- <button style="text-align: right" class="btn btn-sm btn-info-outline" (click)="similarMovies(result.id)"> <i class="fa fa-eye"></i> {{ 'Search.Similar' | translate }}</button> -->
|
||||
<!-- <button style="text-align: right" class="btn btn-sm btn-info-outline" (click)="similarMovies(result.id)"> <i class="far fa-eye"></i> {{ 'Search.Similar' | translate }}</button> -->
|
||||
|
||||
<br/>
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<div class="input-group">
|
||||
<input id="search" type="text" placeholder="{{ 'Search.SearchBarPlaceholder' | translate }}" class="form-control form-control-custom form-control-search form-control-withbuttons" (keyup)="search($event)">
|
||||
<div class="input-group-addon right-radius">
|
||||
<i class="fa fa-search"></i>
|
||||
<i class="fas fa-search"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -20,11 +20,11 @@
|
|||
<br />
|
||||
<div id="movieList">
|
||||
<div *ngIf="searchApplied && artistResult?.length <= 0 && !searchAlbum" class='no-search-results'>
|
||||
<i class='fa fa-music no-search-results-icon'></i>
|
||||
<i class='fas fa-music no-search-results-icon'></i>
|
||||
<div class='no-search-results-text' [translate]="'Search.NoResults'"></div>
|
||||
</div>
|
||||
<div *ngIf="searchApplied && albumResult?.length <= 0 && searchAlbum" class='no-search-results'>
|
||||
<i class='fa fa-music no-search-results-icon'></i>
|
||||
<i class='fas fa-music no-search-results-icon'></i>
|
||||
<div class='no-search-results-text' [translate]="'Search.NoResults'"></div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
<ul id="nav-tabs" class="nav nav-tabs nav-justified" role="tablist">
|
||||
|
||||
<li role="presentation" class="active">
|
||||
<a id="movieTabButton" href="#MoviesTab" aria-controls="home" role="tab" data-toggle="tab" (click)="selectMovieTab()"><i class="fa fa-film"></i> {{ 'Search.MoviesTab' | translate }}</a>
|
||||
<a id="movieTabButton" href="#MoviesTab" aria-controls="home" role="tab" data-toggle="tab" (click)="selectMovieTab()"><i class="fas fa-film"></i> {{ 'Search.MoviesTab' | translate }}</a>
|
||||
</li>
|
||||
|
||||
<li role="presentation">
|
||||
<a id="tvTabButton" href="#TvShowTab" aria-controls="profile" role="tab" data-toggle="tab" (click)="selectTvTab()"><i class="fa fa-television"></i> {{ 'Search.TvTab' | translate }}</a>
|
||||
<a id="tvTabButton" href="#TvShowTab" aria-controls="profile" role="tab" data-toggle="tab" (click)="selectTvTab()"><i class="fas fa-tv"></i> {{ 'Search.TvTab' | translate }}</a>
|
||||
</li>
|
||||
<li role="presentation" *ngIf="musicEnabled">
|
||||
<a id="tvTabButton" href="#MusicTab" aria-controls="profile" role="tab" data-toggle="tab" (click)="selectMusicTab()"><i class="fa fa-music"></i> {{ 'Search.MusicTab' | translate }}</a>
|
||||
<a id="tvTabButton" href="#MusicTab" aria-controls="profile" role="tab" data-toggle="tab" (click)="selectMusicTab()"><i class="fas fa-music"></i> {{ 'Search.MusicTab' | translate }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<div class="btn-group" role="group">
|
||||
<a href="#" class="btn btn-sm btn-primary-outline dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
|
||||
{{ 'Search.Suggestions' | translate }}
|
||||
<i class="fa fa-chevron-down"></i>
|
||||
<i class="fas fa-chevron-down"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li>
|
||||
|
@ -31,7 +31,7 @@
|
|||
<div class="search-button-container-inline">
|
||||
<ng-template [ngTemplateOutlet]="FilterRef"></ng-template>
|
||||
</div>
|
||||
<i id="tvSearchButton" class="fa fa-search"></i>
|
||||
<i id="tvSearchButton" class="fas fa-search"></i>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -49,7 +49,7 @@
|
|||
<div id="tvList">
|
||||
|
||||
<div *ngIf="searchApplied && tvResults?.length <= 0" class='no-search-results'>
|
||||
<i class='fa fa-film no-search-results-icon'></i>
|
||||
<i class='fas fa-film no-search-results-icon'></i>
|
||||
<div class='no-search-results-text'>{{ 'Search.NoResults' | translate }}</div>
|
||||
</div>
|
||||
<div *ngIf="tvResults" >
|
||||
|
@ -107,7 +107,7 @@
|
|||
<div class="col-sm-2 small-padding">
|
||||
<div *ngIf="!node.fullyAvailable" class="dropdown">
|
||||
<button class="btn btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||
<i class="fa fa-plus"></i> {{ 'Common.Request' | translate }}
|
||||
<i class="fas fa-plus"></i> {{ 'Common.Request' | translate }}
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||
|
@ -128,29 +128,29 @@
|
|||
|
||||
<div *ngIf="node.fullyAvailable">
|
||||
<button style="text-align: right" class="btn btn-success-outline disabled" disabled>
|
||||
<i class="fa fa-check"></i> {{ 'Common.Available' | translate }}
|
||||
<i class="fas fa-check"></i> {{ 'Common.Available' | translate }}
|
||||
</button>
|
||||
</div>
|
||||
<br />
|
||||
<div *ngIf="node.plexUrl && node.available">
|
||||
<a style="text-align: right" class="btn btn-sm btn-success-outline" href="{{node.plexUrl}}" target="_blank">
|
||||
<i class="fa fa-eye"></i> {{ 'Search.ViewOnPlex' | translate }}
|
||||
<i class="far fa-eye"></i> {{ 'Search.ViewOnPlex' | translate }}
|
||||
</a>
|
||||
</div>
|
||||
<div *ngIf="node.embyUrl && node.available">
|
||||
<a style="text-align: right" id="embybtn" class="btn btn-sm btn-success-outline" href="{{node.embyUrl}}" target="_blank">
|
||||
<i class="fa fa-eye"></i> {{ 'Search.ViewOnEmby' | translate }}
|
||||
<i class="far fa-eye"></i> {{ 'Search.ViewOnEmby' | translate }}
|
||||
</a>
|
||||
</div>
|
||||
<div *ngIf="node.jellyfinUrl && node.available">
|
||||
<a style="text-align: right" id="jellyfinbtn" class="btn btn-sm btn-success-outline" href="{{node.jellyfinUrl}}" target="_blank">
|
||||
<i class="fa fa-eye"></i> {{ 'Search.ViewOnJellyfin' | translate }}
|
||||
<i class="far fa-eye"></i> {{ 'Search.ViewOnJellyfin' | translate }}
|
||||
</a>
|
||||
</div>
|
||||
<div class="dropdown" *ngIf="issueCategories && issuesEnabled">
|
||||
<button class="btn btn-sm btn-primary-outline dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true"
|
||||
aria-expanded="true">
|
||||
<i class="fa fa-plus"></i> {{ 'Requests.ReportIssue' | translate }}
|
||||
<i class="fas fa-plus"></i> {{ 'Requests.ReportIssue' | translate }}
|
||||
<span class="caret"></span>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||
|
|
|
@ -62,7 +62,7 @@
|
|||
</div>
|
||||
<div class="md-form-field" style="display:inline;margin-left:20px;">
|
||||
<button mat-raised-button id="profiles" (click)="getProfiles(form)" class="mat-stroked-button load">
|
||||
Load Quality Profiles <span *ngIf="profilesRunning" class="fa fa-spinner fa-spin"></span></button>
|
||||
Load Quality Profiles <span *ngIf="profilesRunning" class="fas fa-spinner fa-spin"></span></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
</td>
|
||||
<td>{{RequestType[v.type] | humanize}}</td>
|
||||
<td class="vcenter">{{v.retryCount}}</td>
|
||||
<td class="vcenter"> <i [pTooltip]="v.error" class="fa fa-info-circle"></i></td>
|
||||
<td class="vcenter"> <i [pTooltip]="v.error" class="fas fa-info-circle"></i></td>
|
||||
<td class="vcenter"><button type="button" class="mat-focus-indicator mat-flat-button mat-button-base mat-warn" (click)="remove(v)">Remove</button></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
<div class="md-form-field">
|
||||
<div class="md-form-field" style="display:inline;">
|
||||
<button mat-raised-button type="button" (click)="getProfiles(form)" color="primary">Load Profiles <span
|
||||
*ngIf="profilesRunning" class="fa fa-spinner fa-spin"></span></button>
|
||||
*ngIf="profilesRunning" class="fas fa-spinner fa-spin"></span></button>
|
||||
</div>
|
||||
<div class="md-form-field" style="margin-top:1em;"></div>
|
||||
<mat-form-field appearance="outline" floatLabel=always>
|
||||
|
@ -72,7 +72,7 @@
|
|||
<div class="md-form-field">
|
||||
<div class="md-form-field" style="display:inline;">
|
||||
<button mat-raised-button type="button" (click)="getRootFolders(form)" color="primary">Load Root Folders <span
|
||||
*ngIf="rootFoldersRunning" class="fa fa-spinner fa-spin"></span></button>
|
||||
*ngIf="rootFoldersRunning" class="fas fa-spinner fa-spin"></span></button>
|
||||
</div>
|
||||
|
||||
<div class="md-form-field" style="margin-top:1em;"></div>
|
||||
|
@ -90,7 +90,7 @@
|
|||
<div class="md-form-field">
|
||||
<div class="md-form-field" style="display:inline;">
|
||||
<button mat-raised-button type="button" (click)="getMetadataProfiles(form)" color="primary">Load Metadata <span
|
||||
*ngIf="metadataRunning" class="fa fa-spinner fa-spin"></span></button></div>
|
||||
*ngIf="metadataRunning" class="fas fa-spinner fa-spin"></span></button></div>
|
||||
<div class="md-form-field" style="margin-top:1em;"></div>
|
||||
</div>
|
||||
<mat-form-field appearance="outline" floatLabel=always>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
<div class="form-group">
|
||||
<label for="applicationToken" class="control-label">Application Token
|
||||
<i class="fa fa-question-circle" pTooltip="Optional authentication token. Will be sent as 'Access-Token' header."></i>
|
||||
<i class="far fa-question-circle" pTooltip="Optional authentication token. Will be sent as 'Access-Token' header."></i>
|
||||
</label>
|
||||
|
||||
<input type="text" class="form-control form-control-custom " id="applicationToken" name="applicationToken" [ngClass]="{'form-error': form.get('applicationToken').hasError('required')}" formControlName="applicationToken" pTooltip="Enter your Application token from Webhook.">
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<mat-label>Api Key</mat-label>
|
||||
<input matInput id="ApiKey" name="ApiKey" formControlName="apiKey" readonly="readonly">
|
||||
<button type="button" matSuffix (click)="refreshApiKey()" style="display:inline-block;">
|
||||
<mat-icon class="fa fa-refresh"></mat-icon>
|
||||
<mat-icon class="fas fa-sync"></mat-icon>
|
||||
</button>
|
||||
|
||||
</mat-form-field>
|
||||
|
|
|
@ -102,7 +102,7 @@
|
|||
<div>
|
||||
<button mat-raised-button (click)="loadLibraries(server)"
|
||||
class="mat-focus-indicator mat-stroked-button mat-button-base">Load Libraries
|
||||
<i class="fa fa-film"></i>
|
||||
<i class="fas fa-film"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -143,7 +143,7 @@
|
|||
<div>
|
||||
<button mat-raised-button id="requestToken" (click)="requestServers(server)"
|
||||
class="mat-stroked-button">Load Servers
|
||||
<i class="fa fa-key"></i>
|
||||
<i class="fas fa-key"></i>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -59,7 +59,7 @@
|
|||
<label for="username" class="control-label"><h3>Radarr Interface</h3></label>
|
||||
<div class="md-form-field">
|
||||
<div class="md-form-field" style="display:inline;">
|
||||
<button mat-raised-button (click)="getProfiles(form)" color="primary">Load Profiles <span *ngIf="profilesRunning" class="fa fa-spinner fa-spin"></span></button>
|
||||
<button mat-raised-button (click)="getProfiles(form)" color="primary">Load Profiles <span *ngIf="profilesRunning" class="fas fa-spinner fa-spin"></span></button>
|
||||
</div>
|
||||
<div class="md-form-field" style="margin-top:1em;"></div>
|
||||
<mat-form-field appearance="outline" >
|
||||
|
@ -74,7 +74,7 @@
|
|||
</div>
|
||||
<div class="md-form-field">
|
||||
<div class="md-form-field" style="display:inline;">
|
||||
<button mat-raised-button (click)="getRootFolders(form)" color="primary">Load Root Folders <span *ngIf="rootFoldersRunning" class="fa fa-spinner fa-spin"></span></button>
|
||||
<button mat-raised-button (click)="getRootFolders(form)" color="primary">Load Root Folders <span *ngIf="rootFoldersRunning" class="fas fa-spinner fa-spin"></span></button>
|
||||
</div>
|
||||
<div class="md-form-field" style="margin-top:1em;"></div>
|
||||
<mat-form-field appearance="outline" >
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
|
||||
<button mat-button [matMenuTriggerFor]="configurationmenu"><i class="fa fa-cogs" aria-hidden="true"></i> Configuration</button>
|
||||
<button mat-button [matMenuTriggerFor]="configurationmenu"><i class="fas fa-wrench" aria-hidden="true"></i> Configuration</button>
|
||||
<mat-menu #configurationmenu="matMenu">
|
||||
<button mat-menu-item [routerLink]="['/Settings/Ombi']">General</button>
|
||||
<button mat-menu-item [routerLink]="['/Settings/Customization']">Customization</button>
|
||||
|
@ -11,33 +11,33 @@
|
|||
<button mat-menu-item [routerLink]="['/Settings/TheMovieDb']">The Movie Database</button>
|
||||
</mat-menu>
|
||||
|
||||
<button mat-button [matMenuTriggerFor]="mediaservermenu"><i class="fa fa-server" aria-hidden="true"></i> Media Server</button>
|
||||
<button mat-button [matMenuTriggerFor]="mediaservermenu"><i class="fas fa-server" aria-hidden="true"></i> Media Server</button>
|
||||
<mat-menu #mediaservermenu="matMenu">
|
||||
<button mat-menu-item [routerLink]="['/Settings/Plex']">Plex</button>
|
||||
<button mat-menu-item [routerLink]="['/Settings/Emby']">Emby</button>
|
||||
<button mat-menu-item [routerLink]="['/Settings/Jellyfin']">Jellyfin</button>
|
||||
</mat-menu>
|
||||
|
||||
<button mat-button [matMenuTriggerFor]="tvmenu"><i class="fa fa-television" aria-hidden="true"></i> TV</button>
|
||||
<button mat-button [matMenuTriggerFor]="tvmenu"><i class="fas fa-tv" aria-hidden="true"></i> TV</button>
|
||||
<mat-menu #tvmenu="matMenu">
|
||||
<button mat-menu-item [routerLink]="['/Settings/Sonarr']">Sonarr</button>
|
||||
<button mat-menu-item [routerLink]="['/Settings/DogNzb']">DogNzb</button>
|
||||
<button mat-menu-item [routerLink]="['/Settings/SickRage']">SickRage</button>
|
||||
</mat-menu>
|
||||
|
||||
<button mat-button [matMenuTriggerFor]="movieMenu"><i class="fa fa-film" aria-hidden="true"></i> Movies</button>
|
||||
<button mat-button [matMenuTriggerFor]="movieMenu"><i class="fas fa-film" aria-hidden="true"></i> Movies</button>
|
||||
<mat-menu #movieMenu="matMenu">
|
||||
<button mat-menu-item [routerLink]="['/Settings/CouchPotato']">CouchPotato</button>
|
||||
<button mat-menu-item [routerLink]="['/Settings/DogNzb']">DogNzb</button>
|
||||
<button mat-menu-item [routerLink]="['/Settings/Radarr']">Radarr</button>
|
||||
</mat-menu>
|
||||
|
||||
<button mat-button [matMenuTriggerFor]="musicMenu"><i class="fa fa-music" aria-hidden="true"></i> Music</button>
|
||||
<button mat-button [matMenuTriggerFor]="musicMenu"><i class="fas fa-music" aria-hidden="true"></i> Music</button>
|
||||
<mat-menu #musicMenu="matMenu">
|
||||
<button mat-menu-item [routerLink]="['/Settings/Lidarr']">Lidarr</button>
|
||||
</mat-menu>
|
||||
|
||||
<button mat-button [matMenuTriggerFor]="notificationMenu"><i class="fa fa-bell-o" aria-hidden="true"></i> Notifications</button>
|
||||
<button mat-button [matMenuTriggerFor]="notificationMenu"><i class="fas fa-bell" aria-hidden="true"></i> Notifications</button>
|
||||
<mat-menu #notificationMenu="matMenu">
|
||||
<button mat-menu-item [routerLink]="['/Settings/CloudMobile']">Mobile</button>
|
||||
<button mat-menu-item [routerLink]="['/Settings/Mobile']">Legacy Mobile</button>
|
||||
|
@ -55,7 +55,7 @@
|
|||
<button mat-menu-item [routerLink]="['/Settings/Webhook']">Webhook</button>
|
||||
</mat-menu>
|
||||
|
||||
<button mat-button [matMenuTriggerFor]="systemMenu"><i class="fa fa-tachometer" aria-hidden="true"></i> System</button>
|
||||
<button mat-button [matMenuTriggerFor]="systemMenu"><i class="fas fa-sliders-h" aria-hidden="true"></i> System</button>
|
||||
<mat-menu #systemMenu="matMenu">
|
||||
<button mat-menu-item [routerLink]="['/Settings/About']">About</button>
|
||||
<button mat-menu-item [routerLink]="['/Settings/FailedRequests']">Failed Requests</button>
|
||||
|
|
|
@ -61,7 +61,7 @@
|
|||
<div id="profiles">
|
||||
<div class="md-form-field" style="display:inline;">
|
||||
<button mat-raised-button id="profiles" (click)="getProfiles(form)" class="mat-stroked-button">
|
||||
Load Qualities <span *ngIf="profilesRunning" class="fa fa-spinner fa-spin"></span></button>
|
||||
Load Qualities <span *ngIf="profilesRunning" class="fas fa-spinner fa-spin"></span></button>
|
||||
<div class="md-form-field" style="margin-top:1em;"></div>
|
||||
</div>
|
||||
<div class="md-form-field" style="display:contents;">
|
||||
|
@ -93,7 +93,7 @@
|
|||
<div id="rootFolders">
|
||||
<div class="md-form-field" style="display:inline">
|
||||
<button mat-raised-button id="rootFolder" (click)="getRootFolders(form)" class="mat-stroked-button">
|
||||
Load Folders <span *ngIf="rootFoldersRunning" class="fa fa-spinner fa-spin"></span></button><div class="md-form-field" style="margin-top:1em;"></div>
|
||||
Load Folders <span *ngIf="rootFoldersRunning" class="fas fa-spinner fa-spin"></span></button><div class="md-form-field" style="margin-top:1em;"></div>
|
||||
</div>
|
||||
<div class="md-form-field" style="display:contents;">
|
||||
<mat-form-field appearance="outline">
|
||||
|
@ -122,12 +122,12 @@
|
|||
|
||||
<div class="form-group col-md-12" *ngIf="form.controls.v3.value">
|
||||
<label for="select" class="control-label">Language Profiles
|
||||
<i *ngIf="form.get('languageProfile').hasError('required')" class="fa fa-exclamation-circle error-text" pTooltip="A Language Profile is required"></i>
|
||||
<i *ngIf="form.get('languageProfile').hasError('required')" class="fas fa-exclamation-circle error-text" pTooltip="A Language Profile is required"></i>
|
||||
</label>
|
||||
<div id="langaugeProfile">
|
||||
<div class="md-form-field" style="display:inline">
|
||||
<button type="button" mat-raised-button (click)="getLanguageProfiles(form)" class="mat-stroked-button">Load
|
||||
Languages <span *ngIf="langRunning" class="fa fa-spinner fa-spin"> </span></button><div class="md-form-field" style="margin-top:1em;"></div>
|
||||
Languages <span *ngIf="langRunning" class="fas fa-spinner fa-spin"> </span></button><div class="md-form-field" style="margin-top:1em;"></div>
|
||||
</div>
|
||||
<div class="md-form-field" style="display:contents;">
|
||||
<mat-form-field appearance="outline">
|
||||
|
|
|
@ -6,12 +6,12 @@
|
|||
|
||||
<li role="presentation" class="active">
|
||||
<a id="currentVotes" href="#currentVotes" aria-controls="home" role="tab" data-toggle="tab" (click)="selectCurrentTab()"><i
|
||||
class="fa fa-meh-o"></i> {{ 'Votes.VotesTab' | translate }}</a>
|
||||
class="far fa-meh"></i> {{ 'Votes.VotesTab' | translate }}</a>
|
||||
</li>
|
||||
|
||||
<li role="presentation">
|
||||
<a id="completedVotes" href="#completedVotes" aria-controls="profile" role="tab" data-toggle="tab" (click)="selectCompletedVotesTab()"><i
|
||||
class="fa fa-smile-o"></i> {{ 'Votes.CompletedVotesTab' | translate }}</a>
|
||||
class="far fa-smile"></i> {{ 'Votes.CompletedVotesTab' | translate }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
@ -32,9 +32,9 @@
|
|||
<tbody>
|
||||
<tr *ngFor="let vm of currentVotes">
|
||||
<td class="vcenter">
|
||||
<button id="{{vm.requestId}}upvote" class="btn btn-info-outline col-md-6" (click)="upvote(vm)"><i class="fa fa-thumbs-o-up"
|
||||
<button id="{{vm.requestId}}upvote" class="btn btn-info-outline col-md-6" (click)="upvote(vm)"><i class="far fa-thumbs-up"
|
||||
aria-hidden="true"></i></button>
|
||||
<button id="{{vm.requestId}}downvote" class="btn btn-info-outline col-md-6" (click)="downvote(vm)" ><i class="fa fa-thumbs-o-down"
|
||||
<button id="{{vm.requestId}}downvote" class="btn btn-info-outline col-md-6" (click)="downvote(vm)" ><i class="far fa-thumbs-down"
|
||||
aria-hidden="true"></i></button>
|
||||
</td>
|
||||
<td style="width: 10%"> <img *ngIf="vm.image" class="img-responsive poster" style="max-width: 100%;
|
||||
|
@ -66,10 +66,10 @@
|
|||
<tr *ngFor="let vm of completedVotes">
|
||||
<td class="vcenter">
|
||||
<button id="{{vm.requestId}}upvote" class="btn btn-info-outline col-md-6" [ngClass]="{'btn-success-outline': vm.myVote == VoteType.Upvote, 'btn-info-outline': vm.myVote != VoteType.Upvote}"
|
||||
(click)="upvote(vm)" [disabled]="vm.myVote == VoteType.Upvote"><i class="fa fa-thumbs-o-up"
|
||||
(click)="upvote(vm)" [disabled]="vm.myVote == VoteType.Upvote"><i class="far fa-thumbs-up"
|
||||
aria-hidden="true"></i></button>
|
||||
<button id="{{vm.requestId}}downvote" class="btn btn-info-outline col-md-6" [ngClass]="{'btn-danger-outline': vm.myVote == VoteType.Downvote, 'btn-info-outline': vm.myVote != VoteType.Downvote}"
|
||||
(click)="downvote(vm)" [disabled]="vm.myVote == VoteType.Downvote"><i class="fa fa-thumbs-o-down"
|
||||
(click)="downvote(vm)" [disabled]="vm.myVote == VoteType.Downvote"><i class="far fa-thumbs-down"
|
||||
aria-hidden="true"></i></button>
|
||||
</td>
|
||||
<td style="width: 10%"> <img *ngIf="vm.image" class="img-responsive poster" style="max-width: 100%;
|
||||
|
|
|
@ -1,12 +1,22 @@
|
|||
|
||||
<small>This account will be used to configure your settings and also manage all of the requests.</small>
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input matInput type="text" id="adminUsername" name="Username" [(ngModel)]="user.username" placeholder="Username">
|
||||
</mat-form-field>
|
||||
</div> <div>
|
||||
<mat-form-field>
|
||||
<input type="password" matInput id="adminPassword" name="Password" [(ngModel)]="user.password" placeholder="Password">
|
||||
</mat-form-field>
|
||||
<div class="mediaserver-container">
|
||||
<div class="left-container mediaserver">
|
||||
<i class="fas fa-user-shield text-logo"></i>
|
||||
</div>
|
||||
<div class="right-container mediaserver">
|
||||
<div class="right-container-content mediaserver">
|
||||
<h1>Protect your Ombi</h1>
|
||||
<small>Create an Admin account to make sure you are always able to access your Ombi.</small>
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input matInput type="text" id="adminUsername" name="Username" [(ngModel)]="user.username" placeholder="Username">
|
||||
</mat-form-field>
|
||||
</div> <div>
|
||||
<mat-form-field>
|
||||
<input type="password" matInput id="adminPassword" name="Password" [(ngModel)]="user.password" placeholder="Password">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<small class="important">You'll need to configure e-mail to reset your password!</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import { ICreateWizardUser } from "../../interfaces";
|
|||
@Component({
|
||||
selector: "wizard-local-admin",
|
||||
templateUrl: "./createadmin.component.html",
|
||||
styleUrls: ["../welcome/welcome.component.scss"]
|
||||
})
|
||||
export class CreateAdminComponent {
|
||||
|
||||
|
|
|
@ -1,31 +1,40 @@
|
|||
|
||||
<div *ngIf="embySettings">
|
||||
<div *ngIf="embySettings.servers">
|
||||
<div *ngFor="let server of embySettings.servers">
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input type="text" matInput [(ngModel)]="server.ip" id="Ip" name="Ip" placeholder="Emby Hostname or IP Address">
|
||||
</mat-form-field>
|
||||
<div class="mediaserver-container">
|
||||
<div class="left-container mediaserver">
|
||||
<img src="https://emby.media/resources/logowhite_1881.png">
|
||||
</div>
|
||||
<div class="right-container mediaserver">
|
||||
<div class="right-container-content mediaserver">
|
||||
<H1 class="wizard-title">Emby Configuration</H1>
|
||||
<div *ngIf="embySettings">
|
||||
<div *ngIf="embySettings.servers">
|
||||
<div *ngFor="let server of embySettings.servers">
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input type="text" matInput [(ngModel)]="server.ip" id="Ip" name="Ip" placeholder="Emby Hostname or IP Address">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
<mat-form-field>
|
||||
<input type="text" matInput [(ngModel)]="server.port" id="portNumber" name="Port" value="{{server.port}}">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-slide-toggle [(ngModel)]="server.ssl">Enable SSL</mat-slide-toggle>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<mat-form-field>
|
||||
<input type="text" matInput [(ngModel)]="server.apiKey" id="apiKey" name="ApiKey" placeholder="Emby API Key">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div style="text-align: center; margin-top: 20px">
|
||||
<button (click)="save()" id="embyApiKeySave" mat-raised-button color="accent" type="button" class="viewon-btn emby">Save</button><div id="spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
<mat-form-field>
|
||||
<input type="text" matInput [(ngModel)]="server.port" id="portNumber" name="Port" value="{{server.port}}">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-slide-toggle [(ngModel)]="server.ssl">Enable SSL</mat-slide-toggle>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<mat-form-field>
|
||||
<input type="text" matInput [(ngModel)]="server.apiKey" id="apiKey" name="ApiKey" placeholder="Emby API Key">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div style="text-align: center; margin-top: 20px">
|
||||
<a (click)="save()" id="embyApiKeySave" mat-raised-button color="primary">Save <div id="spinner"></div></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -8,6 +8,7 @@ import { IEmbySettings } from "../../interfaces";
|
|||
@Component({
|
||||
selector: "wizard-emby",
|
||||
templateUrl: "./emby.component.html",
|
||||
styleUrls: ["../welcome/welcome.component.scss"],
|
||||
})
|
||||
export class EmbyComponent implements OnInit {
|
||||
|
||||
|
|
|
@ -1,31 +1,40 @@
|
|||
|
||||
<div *ngIf="jellyfinSettings">
|
||||
<div *ngIf="jellyfinSettings.servers">
|
||||
<div *ngFor="let server of jellyfinSettings.servers">
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input type="text" matInput [(ngModel)]="server.ip" id="Ip" name="Ip" placeholder="Jellyfin Hostname or IP Address">
|
||||
</mat-form-field>
|
||||
<div class="mediaserver-container">
|
||||
<div class="left-container mediaserver">
|
||||
<img src="https://jellyfin.org/images/banner-dark.svg">
|
||||
</div>
|
||||
<div class="right-container mediaserver">
|
||||
<div class="right-container-content mediaserver">
|
||||
<H1 class="wizard-title">Jellyfin Configuration</H1>
|
||||
<div *ngIf="jellyfinSettings">
|
||||
<div *ngIf="jellyfinSettings.servers">
|
||||
<div *ngFor="let server of jellyfinSettings.servers">
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input type="text" matInput [(ngModel)]="server.ip" id="Ip" name="Ip" placeholder="Jellyfin Hostname or IP Address">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
<mat-form-field>
|
||||
<input type="text" matInput [(ngModel)]="server.port" id="portNumber" name="Port" value="{{server.port}}">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-slide-toggle [(ngModel)]="server.ssl">Enable SSL</mat-slide-toggle>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<mat-form-field>
|
||||
<input type="text" matInput [(ngModel)]="server.apiKey" id="apiKey" name="ApiKey" placeholder="Jellyfin API Key">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div style="text-align: center; margin-top: 20px">
|
||||
<button (click)="save()" id="jellyfinApiKeySave" mat-raised-button color="accent" type="button" class="viewon-btn jellyfin">Save</button><div id="spinner"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
||||
<mat-form-field>
|
||||
<input type="text" matInput [(ngModel)]="server.port" id="portNumber" name="Port" value="{{server.port}}">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-slide-toggle [(ngModel)]="server.ssl">Enable SSL</mat-slide-toggle>
|
||||
</div>
|
||||
<div>
|
||||
|
||||
<mat-form-field>
|
||||
<input type="text" matInput [(ngModel)]="server.apiKey" id="apiKey" name="ApiKey" placeholder="Jellyfin API Key">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div style="text-align: center; margin-top: 20px">
|
||||
<a (click)="save()" id="jellyfinApiKeySave" mat-raised-button color="primary">Save <div id="spinner"></div></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -8,6 +8,7 @@ import { IJellyfinSettings } from "../../interfaces";
|
|||
@Component({
|
||||
selector: "wizard-jellyfin",
|
||||
templateUrl: "./jellyfin.component.html",
|
||||
styleUrls: ["../welcome/welcome.component.scss"]
|
||||
})
|
||||
export class JellyfinComponent implements OnInit {
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
export interface IOmbiConfigModel {
|
||||
applicationName: string;
|
||||
applicationUrl: string;
|
||||
logo: string;
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
<div class="mediaserver-container">
|
||||
<div class="left-container mediaserver">
|
||||
<i class="fas fa-user-astronaut text-logo"></i>
|
||||
</div>
|
||||
<div class="right-container mediaserver">
|
||||
<div class="right-container-content mediaserver">
|
||||
<h1 *ngIf="!config.applicationName">Customize your Ombi</h1>
|
||||
<h1 *ngIf="config.applicationName">Customize your {{config.applicationName}}</h1>
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input type="text" matInput id="applicationname" name="Application Name" [(ngModel)]="config.applicationName" placeholder="Application Name">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input matInput type="text" id="applicationurl" name="Application URL" [(ngModel)]="config.applicationUrl" placeholder="Application URL">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<mat-label>Custom Logo</mat-label>
|
||||
<input matInput type="url" id="customlogo" name="Custom Logo" [(ngModel)]="config.logo" placeholder="Input the URL of your custom logo">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
import { Component, Input } from "@angular/core";
|
||||
import { IOmbiConfigModel } from "../models/OmbiConfigModel";
|
||||
import { WizardService } from "../services/wizard.service";
|
||||
|
||||
@Component({
|
||||
selector: "wizard-ombi",
|
||||
templateUrl: "./ombiconfig.component.html",
|
||||
styleUrls: ["../welcome/welcome.component.scss"]
|
||||
})
|
||||
export class OmbiConfigComponent {
|
||||
|
||||
@Input() public config: IOmbiConfigModel;
|
||||
}
|
|
@ -1,24 +1,38 @@
|
|||
<div class="form-group">
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input matInput type="text" [(ngModel)]="login" id="username" placeholder="Username">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input matInput type="password" [(ngModel)]="password" placeholder="Password">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<small>Please note we do not store this information, we only store your Plex Authorization Token that will allow Ombi to view your media and users</small>
|
||||
<div class="form-group">
|
||||
<div style="text-align: center; margin-top: 20px">
|
||||
<button (click)="requestAuthToken()" mat-raised-button color="primary" >Request Token <i class="fa fa-key"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-center">OR</p>
|
||||
<div class="form-group">
|
||||
<div style="text-align: center; margin-top: 20px">
|
||||
<button (click)="oauth()" mat-raised-button color="accent" type="button">Continue With Plex</button>
|
||||
<div class="mediaserver-container" >
|
||||
<div class="left-container mediaserver">
|
||||
<img src="https://www.plex.tv/wp-content/themes/plex/assets/img/plex-logo.svg">
|
||||
</div>
|
||||
<div class="right-container mediaserver">
|
||||
<div class="right-container-content mediaserver">
|
||||
<H1 class="wizard-title">Plex Configuration</H1>
|
||||
<div class="form-group">
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input matInput type="text" [(ngModel)]="login" id="username" placeholder="Username" [disabled]="completed">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
<div>
|
||||
<mat-form-field>
|
||||
<input matInput type="password" [(ngModel)]="password" placeholder="Password" [disabled]="completed">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
</div>
|
||||
<small>Please note we do not store this information, we only store your Plex Authorization Token that will allow Ombi to view your media and users</small>
|
||||
<div class="plex-buttons">
|
||||
<div class="form-group">
|
||||
<div style="text-align: center; margin-top: 20px">
|
||||
<button (click)="requestAuthToken()" mat-raised-button color="primary" class="viewon-btn standard" [disabled]="completed">Request Token <i class="fas fa-key"></i></button>
|
||||
</div>
|
||||
</div>
|
||||
<p class="text-center space-or">OR</p>
|
||||
<div class="form-group">
|
||||
<div style="text-align: center; margin-top: 20px">
|
||||
<button (click)="oauth()" mat-raised-button color="accent" type="button" class="viewon-btn plex" [disabled]="completed">
|
||||
<i *ngIf="oauthLoading" class="fas fa-circle-notch fa-spin fa-fw"></i>
|
||||
Login With Plex</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -9,12 +9,15 @@ import { StorageService } from "../../shared/storage/storage-service";
|
|||
@Component({
|
||||
selector: "wizard-plex",
|
||||
templateUrl: "./plex.component.html",
|
||||
styleUrls: ["../welcome/welcome.component.scss"],
|
||||
})
|
||||
export class PlexComponent implements OnInit, OnDestroy {
|
||||
|
||||
public login: string;
|
||||
public password: string;
|
||||
public pinTimer: any;
|
||||
public completed: boolean;
|
||||
public oauthLoading: boolean;
|
||||
|
||||
private clientId: string;
|
||||
|
||||
|
@ -42,7 +45,7 @@ export class PlexComponent implements OnInit, OnDestroy {
|
|||
usePlexAdminAccount: true,
|
||||
}).subscribe(y => {
|
||||
if (y.result) {
|
||||
this.router.navigate(["login"]);
|
||||
this.notificationService.success("Created your Plex User!");
|
||||
} else {
|
||||
this.notificationService.error("Could not get the Plex Admin Information");
|
||||
if (y.errors.length > 0) {
|
||||
|
@ -56,6 +59,7 @@ export class PlexComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
public oauth() {
|
||||
this.oauthLoading = true;
|
||||
const oAuthWindow = window.open(window.location.toString(), "_blank", `toolbar=0,
|
||||
location=0,
|
||||
status=0,
|
||||
|
@ -68,20 +72,24 @@ export class PlexComponent implements OnInit, OnDestroy {
|
|||
|
||||
this.authService.login({ usePlexOAuth: true, password: "", rememberMe: true, username: "", plexTvPin: pin }).subscribe(x => {
|
||||
oAuthWindow!.location.replace(x.url);
|
||||
|
||||
this.pinTimer = setInterval(() => {
|
||||
// this.notify.info("Authenticating", "Loading... Please Wait");
|
||||
this.getPinResult(x.pinId);
|
||||
}, 10000);
|
||||
}, 3000);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public getPinResult(pinId: number) {
|
||||
this.plexOauth.oAuth(pinId).subscribe(x => {
|
||||
|
||||
if (!x.accessToken) {
|
||||
if(!x.success) {
|
||||
this.oauthLoading = false;
|
||||
clearInterval(this.pinTimer);
|
||||
this.notificationService.error(`Error From Plex: ${x.error}`)
|
||||
}
|
||||
return;
|
||||
// RETURN
|
||||
}
|
||||
|
||||
this.identityService.createWizardUser({
|
||||
|
@ -92,10 +100,14 @@ export class PlexComponent implements OnInit, OnDestroy {
|
|||
if (u.result) {
|
||||
this.authService.oAuth(pinId).subscribe(c => {
|
||||
this.store.save("id_token", c.access_token);
|
||||
this.router.navigate(["login"]);
|
||||
this.completed = true;
|
||||
this.notificationService.success("Created your Plex User!");
|
||||
this.oauthLoading = false;
|
||||
clearInterval(this.pinTimer);
|
||||
});
|
||||
} else {
|
||||
|
||||
this.oauthLoading = false;
|
||||
if (u.errors.length > 0) {
|
||||
console.log(u.errors[0]);
|
||||
}
|
||||
|
|
19
src/Ombi/ClientApp/src/app/wizard/services/wizard.service.ts
Normal file
19
src/Ombi/ClientApp/src/app/wizard/services/wizard.service.ts
Normal file
|
@ -0,0 +1,19 @@
|
|||
import { PlatformLocation, APP_BASE_HREF } from "@angular/common";
|
||||
import { HttpClient } from "@angular/common/http";
|
||||
import { Injectable, Inject } from "@angular/core";
|
||||
import { Observable } from "rxjs";
|
||||
import { ICustomizationSettings } from "../../interfaces";
|
||||
import { ServiceHelpers } from "../../services";
|
||||
import { IOmbiConfigModel } from "../models/OmbiConfigModel";
|
||||
|
||||
|
||||
@Injectable()
|
||||
export class WizardService extends ServiceHelpers {
|
||||
constructor(public http: HttpClient, @Inject(APP_BASE_HREF) href:string) {
|
||||
super(http, "/api/v2/wizard/", href);
|
||||
}
|
||||
|
||||
public addOmbiConfig(config: IOmbiConfigModel): Observable<ICustomizationSettings> {
|
||||
return this.http.post<ICustomizationSettings>(`${this.url}config`, config, {headers: this.headers});
|
||||
}
|
||||
}
|
|
@ -1,67 +1,87 @@
|
|||
<div class="container">
|
||||
<div class="wizard-background">
|
||||
<div class="container wizard-inner">
|
||||
|
||||
<mat-horizontal-stepper linear #stepper>
|
||||
<mat-step >
|
||||
<form >
|
||||
<ng-template matStepLabel>Welcome</ng-template>
|
||||
<p>Welcome to Ombi, this wizard will quickly take you through the inital setup!</p>
|
||||
<div>
|
||||
<button mat-button matStepperNext>Next</button>
|
||||
<div class="welcome-container">
|
||||
<div class="left-container logo">
|
||||
OMBI
|
||||
</div>
|
||||
<div class="right-container">
|
||||
<div class="right-container-content">
|
||||
<h1>Welcome to Ombi!</h1>
|
||||
<p>This wizard will quickly take you through the inital setup!</p>
|
||||
<p>If you encounter any problems, please reach out on the following platforms:</p>
|
||||
<br />
|
||||
<div class="social-media">
|
||||
<ul class="fa-ul">
|
||||
<li><a href="https://discord.gg/Sa7wNWb" target="_blank"><span class="fa-li"><i class="fab fa-discord"></i></span>Ombi Discord</a>
|
||||
<li><a href="https://github.com/Ombi-app/Ombi" target="_blank"><span class="fa-li"><i class="fab fa-github"></i></span>Ombi Github</a>
|
||||
<li><a href="https://docs.ombi.app/" target="_blank"><span class="fa-li"><i class="fas fa-book"></i></span>Ombi Documentation</a>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="welcome-buttons">
|
||||
<button mat-button matStepperNext class="mat-raised-button mat-accent">Next</button>
|
||||
</div>
|
||||
</form>
|
||||
</mat-step>
|
||||
|
||||
<mat-step [optional]="true">
|
||||
<form >
|
||||
<ng-template matStepLabel>Plex</ng-template>
|
||||
<wizard-plex></wizard-plex>
|
||||
<div>
|
||||
<button mat-button matStepperPrevious>Back</button>
|
||||
<button mat-button matStepperNext>Next</button>
|
||||
</div>
|
||||
</form>
|
||||
</mat-step>
|
||||
|
||||
<mat-step [optional]="true">
|
||||
<form >
|
||||
<ng-template matStepLabel>Emby</ng-template>
|
||||
<wizard-emby></wizard-emby>
|
||||
<div>
|
||||
<button mat-button matStepperPrevious>Back</button>
|
||||
<button mat-button matStepperNext>Next</button>
|
||||
</div>
|
||||
</form>
|
||||
</mat-step>
|
||||
|
||||
<mat-step [optional]="true">
|
||||
<form >
|
||||
<ng-template matStepLabel>Jellyfin</ng-template>
|
||||
<wizard-jellyfin></wizard-jellyfin>
|
||||
<div>
|
||||
<button mat-button matStepperPrevious>Back</button>
|
||||
<button mat-button matStepperNext>Next</button>
|
||||
</div>
|
||||
</form>
|
||||
</mat-step>
|
||||
|
||||
<mat-step>
|
||||
<form >
|
||||
<ng-template matStepLabel>Create a local admin</ng-template>
|
||||
<wizard-local-admin [user]="localUser"></wizard-local-admin>
|
||||
<div>
|
||||
<button mat-button matStepperPrevious>Back</button>
|
||||
<button mat-button matStepperNext>Next</button>
|
||||
</div>
|
||||
</form>
|
||||
</mat-step>
|
||||
<form >
|
||||
<ng-template matStepLabel>Media Server</ng-template>
|
||||
<mat-tab-group>
|
||||
<mat-tab label="Plex"><wizard-plex></wizard-plex></mat-tab>
|
||||
<mat-tab label="Emby"><wizard-emby></wizard-emby></mat-tab>
|
||||
<mat-tab label="Jellyfin"><wizard-jellyfin></wizard-jellyfin></mat-tab>
|
||||
</mat-tab-group>
|
||||
<button mat-button matStepperPrevious class="mat-raised-button mat-error left">Back</button>
|
||||
<button mat-button matStepperNext class="mat-raised-button mat-accent right">Next</button>
|
||||
</form>
|
||||
</mat-step>
|
||||
<mat-step>
|
||||
<form>
|
||||
<ng-template matStepLabel>Create a local admin</ng-template>
|
||||
<wizard-local-admin [user]="localUser"></wizard-local-admin>
|
||||
<div>
|
||||
<button mat-button matStepperPrevious class="mat-raised-button mat-error left">Back</button>
|
||||
<button mat-button matStepperNext class="mat-raised-button mat-accent right">Next</button>
|
||||
</div>
|
||||
</form>
|
||||
</mat-step>
|
||||
<mat-step [optional]="true">
|
||||
<form >
|
||||
<ng-template matStepLabel>Ombi config</ng-template>
|
||||
<wizard-ombi [config]="config"></wizard-ombi>
|
||||
<div>
|
||||
<button mat-button matStepperPrevious class="mat-raised-button mat-error left">Back</button>
|
||||
<button mat-button matStepperNext class="mat-raised-button mat-accent right">Next</button>
|
||||
</div>
|
||||
</form>
|
||||
</mat-step>
|
||||
|
||||
<mat-step>
|
||||
<ng-template matStepLabel>Done</ng-template>
|
||||
All setup! Press Finish to continue and login to Ombi!
|
||||
<div class="mediaserver-container">
|
||||
<div class="left-container mediaserver">
|
||||
<i class="fas fa-check text-logo"></i>
|
||||
</div>
|
||||
<div class="right-container mediaserver">
|
||||
<div class="right-container-content mediaserver">
|
||||
<h1>All setup!</h1>
|
||||
Press Finish to continue and login to Ombi!
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<button mat-button matStepperPrevious (click)="createUser()">Finish</button>
|
||||
<button mat-button (click)="stepper.reset()">Reset</button>
|
||||
<button mat-button matStepperPrevious (click)="createUser()" class="mat-raised-button mat-accent right">Finish</button>
|
||||
<button mat-button (click)="stepper.reset()" class="mat-raised-button mat-error left">Reset</button>
|
||||
</div>
|
||||
</mat-step>
|
||||
</mat-horizontal-stepper>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
172
src/Ombi/ClientApp/src/app/wizard/welcome/welcome.component.scss
Normal file
172
src/Ombi/ClientApp/src/app/wizard/welcome/welcome.component.scss
Normal file
|
@ -0,0 +1,172 @@
|
|||
@import "~styles/variables.scss";
|
||||
.welcome-container{
|
||||
display:flex;
|
||||
height:100%;
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.welcome-container .logo{
|
||||
font-family: Montserrat,sans-serif;
|
||||
text-transform: uppercase;
|
||||
color: #62d2fa;
|
||||
font-weight: 700;
|
||||
font-size: 5em;
|
||||
display:flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height:300px;
|
||||
}
|
||||
|
||||
.left-container{
|
||||
width:30%;
|
||||
}
|
||||
|
||||
.right-container{
|
||||
width:60%;
|
||||
float:right;
|
||||
}
|
||||
|
||||
.right-container-content{
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.welcome-container .right-container{
|
||||
display:flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.welcome-buttons{
|
||||
float:right;
|
||||
}
|
||||
|
||||
.fab:before {
|
||||
font-family: 'Font Awesome 5 Brands';
|
||||
}
|
||||
|
||||
.social-media .fab{
|
||||
font-family: Roboto, "Helvetica Neue", sans-serif;
|
||||
}
|
||||
|
||||
.fas:before {
|
||||
font-family:"Font Awesome 5 Free";
|
||||
font-weight:800;
|
||||
}
|
||||
|
||||
.social-media .fas{
|
||||
font-family: Roboto, "Helvetica Neue", sans-serif;
|
||||
font-weight:400;
|
||||
}
|
||||
|
||||
.social-media a{
|
||||
color: #FFF;
|
||||
}
|
||||
|
||||
.social-media{
|
||||
display:grid;
|
||||
}
|
||||
|
||||
.fa-ul {
|
||||
list-style-type: none;
|
||||
margin-left: 2.5em;
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
.fa-li {
|
||||
left: -2em;
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
width: 2em;
|
||||
line-height: inherit;
|
||||
}
|
||||
|
||||
.social-media ul li{
|
||||
font-size:16px;
|
||||
padding:5px;
|
||||
}
|
||||
|
||||
|
||||
.left-container.mediaserver img{
|
||||
object-fit: contain;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.left-container.mediaserver{
|
||||
display:flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height:300px;
|
||||
padding:20px;
|
||||
}
|
||||
|
||||
.right-container.mediaserver{
|
||||
display:flex;
|
||||
justify-content: center;
|
||||
align-items:center;
|
||||
}
|
||||
|
||||
.right-container-content .mediaserver{
|
||||
display:block;
|
||||
}
|
||||
|
||||
.mediaserver-container{
|
||||
display:flex;
|
||||
height:100%;
|
||||
width:100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.plex-buttons{
|
||||
display:flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
p.space-or{
|
||||
padding:20px;
|
||||
margin-top:20px;
|
||||
}
|
||||
|
||||
.viewon-btn.plex {
|
||||
border: 1px solid #e5a00d;
|
||||
color: #e5a00d;
|
||||
}
|
||||
|
||||
.viewon-btn {
|
||||
background-color: transparent;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.viewon-btn.standard {
|
||||
border: 1px solid #FFF;
|
||||
}
|
||||
|
||||
.viewon-btn.emby {
|
||||
border: 1px solid #52B54B;
|
||||
color: #52B54B;
|
||||
}
|
||||
|
||||
.viewon-btn.jellyfin {
|
||||
border: 1px solid #A45FC4;
|
||||
color: #A45FC4;
|
||||
}
|
||||
|
||||
.text-logo{
|
||||
font-size:12em;
|
||||
}
|
||||
|
||||
.left{
|
||||
float:left;
|
||||
}
|
||||
|
||||
.right{
|
||||
float:right;
|
||||
}
|
||||
|
||||
small.important{
|
||||
color:red;
|
||||
}
|
||||
|
||||
h1.wizard-title{
|
||||
margin-top:30px;
|
||||
}
|
|
@ -1,35 +1,53 @@
|
|||
import { Component, OnInit } from "@angular/core";
|
||||
import { AfterViewInit, Component, OnInit, ViewChild } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
import { ICreateWizardUser } from "../../interfaces";
|
||||
import { IdentityService, NotificationService } from "../../services";
|
||||
import { IOmbiConfigModel } from "../models/OmbiConfigModel";
|
||||
import { WizardService } from "../services/wizard.service";
|
||||
import { MatHorizontalStepper } from'@angular/material/stepper';
|
||||
import { StepperSelectionEvent } from "@angular/cdk/stepper";
|
||||
|
||||
@Component({
|
||||
templateUrl: "./welcome.component.html",
|
||||
styleUrls: ["./welcome.component.scss"],
|
||||
})
|
||||
export class WelcomeComponent implements OnInit {
|
||||
|
||||
public localUser: ICreateWizardUser;
|
||||
|
||||
constructor(private router: Router,
|
||||
private identityService: IdentityService, private notificationService: NotificationService) { }
|
||||
|
||||
public ngOnInit(): void {
|
||||
@ViewChild('stepper', {static: false}) public stepper: MatHorizontalStepper;
|
||||
public localUser: ICreateWizardUser;
|
||||
public config: IOmbiConfigModel;
|
||||
|
||||
constructor(private router: Router, private identityService: IdentityService,
|
||||
private notificationService: NotificationService, private WizardService: WizardService) { }
|
||||
|
||||
public ngOnInit(): void {
|
||||
this.localUser = {
|
||||
password:"",
|
||||
username:"",
|
||||
usePlexAdminAccount:false
|
||||
}
|
||||
this.config = {
|
||||
applicationName: null,
|
||||
applicationUrl: null,
|
||||
logo: null
|
||||
};
|
||||
}
|
||||
|
||||
public createUser() {
|
||||
this.identityService.createWizardUser(this.localUser).subscribe(x => {
|
||||
if (x.result) {
|
||||
this.WizardService.addOmbiConfig(this.config).subscribe(config => {
|
||||
if(config != null) {
|
||||
this.identityService.createWizardUser(this.localUser).subscribe(x => {
|
||||
if (x.result) {
|
||||
// save the config
|
||||
this.router.navigate(["login"]);
|
||||
} else {
|
||||
if (x.errors.length > 0) {
|
||||
this.notificationService.error(x.errors[0]);
|
||||
this.stepper.previous();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}, configErr => this.notificationService.error(configErr));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,12 +11,14 @@ import { JellyfinComponent } from "./jellyfin/jellyfin.component";
|
|||
import { MediaServerComponent } from "./mediaserver/mediaserver.component";
|
||||
import { PlexComponent } from "./plex/plex.component";
|
||||
import { WelcomeComponent } from "./welcome/welcome.component";
|
||||
import { OmbiConfigComponent } from "./ombiconfig/ombiconfig.component";
|
||||
|
||||
import { EmbyService } from "../services";
|
||||
import { JellyfinService } from "../services";
|
||||
import { PlexService } from "../services";
|
||||
import { IdentityService } from "../services";
|
||||
import { PlexOAuthService } from "../services";
|
||||
import { WizardService } from "./services/wizard.service";
|
||||
|
||||
import { SharedModule } from "../shared/shared.module";
|
||||
|
||||
|
@ -27,6 +29,7 @@ const routes: Routes = [
|
|||
{ path: "Emby", component: EmbyComponent},
|
||||
{ path: "Jellyfin", component: JellyfinComponent},
|
||||
{ path: "CreateAdmin", component: CreateAdminComponent},
|
||||
{ path: "OmbiConfig", component: OmbiConfigComponent},
|
||||
];
|
||||
@NgModule({
|
||||
imports: [
|
||||
|
@ -44,6 +47,7 @@ const routes: Routes = [
|
|||
CreateAdminComponent,
|
||||
EmbyComponent,
|
||||
JellyfinComponent,
|
||||
OmbiConfigComponent,
|
||||
],
|
||||
exports: [
|
||||
RouterModule,
|
||||
|
@ -54,6 +58,7 @@ const routes: Routes = [
|
|||
EmbyService,
|
||||
JellyfinService,
|
||||
PlexOAuthService,
|
||||
WizardService,
|
||||
],
|
||||
|
||||
})
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
.mat-flat-button.mat-accent, .mat-raised-button.mat-accent, .mat-fab.mat-accent, .mat-mini-fab.mat-accent{
|
||||
color: $ombi-active-text;
|
||||
background-color: $ombi-active;
|
||||
}
|
||||
|
||||
.mat-menu-panel{
|
||||
|
@ -100,3 +101,43 @@
|
|||
background: $ombi-background-accent;
|
||||
}
|
||||
}
|
||||
|
||||
.mat-tooltip{
|
||||
background: $ombi-background-accent;
|
||||
}
|
||||
|
||||
//Wizard CSS
|
||||
.mat-stepper-horizontal, .mat-stepper-vertical{
|
||||
background: $ombi-background-accent;
|
||||
}
|
||||
|
||||
.wizard-background{
|
||||
background-color: $ombi-background-primary;
|
||||
width:100%;
|
||||
height:100vh;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.wizard-inner{
|
||||
color:#FFF;
|
||||
min-height: 450px;
|
||||
}
|
||||
|
||||
.wizard-inner .mat-stepper-horizontal {
|
||||
min-height: 450px;
|
||||
}
|
||||
|
||||
.mat-step-header .mat-step-icon{
|
||||
background-color:$ombi-active;
|
||||
color: $ombi-active-text;
|
||||
}
|
||||
|
||||
.mat-tab-group.mat-primary .mat-ink-bar, .mat-tab-nav-bar.mat-primary .mat-ink-bar{
|
||||
background-color: $ombi-active;
|
||||
}
|
||||
|
||||
.mat-flat-button, .mat-raised-button, .mat-fab, .mat-mini-fab{
|
||||
background-color: $ombi-active;
|
||||
}
|
||||
|
|
|
@ -9,10 +9,10 @@
|
|||
|
||||
.ui-carousel-viewport {
|
||||
border:0 !important;
|
||||
background-color:transparent !important;
|
||||
background-color:transparent !important;
|
||||
}
|
||||
|
||||
.ui-carousel .ui-carousel-header {
|
||||
background-color:transparent !important;
|
||||
border: 0 !important;
|
||||
}
|
||||
border: 0 !important;
|
||||
}
|
||||
|
|
|
@ -1126,6 +1126,11 @@
|
|||
lodash "^4.17.13"
|
||||
to-fast-properties "^2.0.0"
|
||||
|
||||
"@fortawesome/fontawesome-free@^5.15.2":
|
||||
version "5.15.2"
|
||||
resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.2.tgz#218cd7276ab4f9ab57cc3d2efa2697e6a579f25d"
|
||||
integrity sha512-7l/AX41m609L/EXI9EKH3Vs3v0iA8tKlIOGtw+kgcoanI7p+e4I4GYLqW3UXWiTnjSFymKSmTTPKYrivzbxxqA==
|
||||
|
||||
"@fullcalendar/core@^4.2.0":
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@fullcalendar/core/-/core-4.4.0.tgz#79dbc0cca836ce628a07e739a456da11ff141373"
|
||||
|
@ -3841,10 +3846,6 @@ follow-redirects@^1.0.0:
|
|||
dependencies:
|
||||
debug "=3.1.0"
|
||||
|
||||
font-awesome@^4.7.0:
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/font-awesome/-/font-awesome-4.7.0.tgz#8fa8cf0411a1a31afd07b06d2902bb9fc815a133"
|
||||
|
||||
for-in@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
|
||||
|
|
|
@ -139,7 +139,7 @@ namespace Ombi.Controllers.V1
|
|||
public async Task<SaveWizardResult> CreateWizardUser([FromBody] CreateUserWizardModel user)
|
||||
{
|
||||
var users = UserManager.Users;
|
||||
if (users.Any(x => x.NormalizedUserName != "API"))
|
||||
if (users.Any(x => x.UserType == UserType.LocalUser))
|
||||
{
|
||||
// No one should be calling this. Only the wizard
|
||||
return new SaveWizardResult { Result = false, Errors = new List<string> { "Looks like there is an existing user!" } };
|
||||
|
@ -169,7 +169,7 @@ namespace Ombi.Controllers.V1
|
|||
ImportPlexAdmin = true
|
||||
});
|
||||
|
||||
return await SaveWizardUser(user, adminUser);
|
||||
return await SaveWizardUser(user, adminUser, false);
|
||||
}
|
||||
|
||||
var userToCreate = new OmbiUser
|
||||
|
@ -179,10 +179,10 @@ namespace Ombi.Controllers.V1
|
|||
StreamingCountry = "US"
|
||||
};
|
||||
|
||||
return await SaveWizardUser(user, userToCreate);
|
||||
return await SaveWizardUser(user, userToCreate, true);
|
||||
}
|
||||
|
||||
private async Task<SaveWizardResult> SaveWizardUser(CreateUserWizardModel user, OmbiUser userToCreate)
|
||||
private async Task<SaveWizardResult> SaveWizardUser(CreateUserWizardModel user, OmbiUser userToCreate, bool completeWizard)
|
||||
{
|
||||
IdentityResult result;
|
||||
var retVal = new SaveWizardResult();
|
||||
|
@ -210,10 +210,13 @@ namespace Ombi.Controllers.V1
|
|||
_log.LogInformation("Added the Admin role");
|
||||
}
|
||||
|
||||
// Update the wizard flag
|
||||
var settings = await OmbiSettings.GetSettingsAsync();
|
||||
settings.Wizard = true;
|
||||
await OmbiSettings.SaveSettingsAsync(settings);
|
||||
if (completeWizard)
|
||||
{
|
||||
// Update the wizard flag
|
||||
var settings = await OmbiSettings.GetSettingsAsync();
|
||||
settings.Wizard = true;
|
||||
await OmbiSettings.SaveSettingsAsync(settings);
|
||||
}
|
||||
}
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
|
|
54
src/Ombi/Controllers/V2/WizardController.cs
Normal file
54
src/Ombi/Controllers/V2/WizardController.cs
Normal file
|
@ -0,0 +1,54 @@
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Ombi.Attributes;
|
||||
using Ombi.Core.Settings;
|
||||
using Ombi.Helpers;
|
||||
using Ombi.Models.V2;
|
||||
using Ombi.Settings.Settings.Models;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Controllers.V2
|
||||
{
|
||||
[ServiceFilter(typeof(WizardActionFilter))]
|
||||
[AllowAnonymous]
|
||||
public class WizardController : V2Controller
|
||||
{
|
||||
private ISettingsService<CustomizationSettings> _customizationSettings { get; }
|
||||
|
||||
public WizardController(ISettingsService<CustomizationSettings> customizationSettings)
|
||||
{
|
||||
_customizationSettings = customizationSettings;
|
||||
}
|
||||
|
||||
[HttpPost("config")]
|
||||
[ApiExplorerSettings(IgnoreApi =true)]
|
||||
public async Task<IActionResult> OmbiConfig([FromBody] OmbiConfigModel config)
|
||||
{
|
||||
if (config == null)
|
||||
{
|
||||
return BadRequest();
|
||||
}
|
||||
|
||||
var settings = await _customizationSettings.GetSettingsAsync();
|
||||
|
||||
if (config.ApplicationName.HasValue())
|
||||
{
|
||||
settings.ApplicationName = config.ApplicationName;
|
||||
}
|
||||
|
||||
if(config.ApplicationUrl.HasValue())
|
||||
{
|
||||
settings.ApplicationUrl = config.ApplicationUrl;
|
||||
}
|
||||
|
||||
if(config.Logo.HasValue())
|
||||
{
|
||||
settings.Logo = config.Logo;
|
||||
}
|
||||
|
||||
await _customizationSettings.SaveSettingsAsync(settings);
|
||||
|
||||
return new OkObjectResult(settings);
|
||||
}
|
||||
}
|
||||
}
|
14
src/Ombi/Models/V2/OmbiConfigModel.cs
Normal file
14
src/Ombi/Models/V2/OmbiConfigModel.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Ombi.Models.V2
|
||||
{
|
||||
public class OmbiConfigModel
|
||||
{
|
||||
public string ApplicationName { get; set; }
|
||||
public string ApplicationUrl { get; set; }
|
||||
public string Logo { get; set; }
|
||||
}
|
||||
}
|
|
@ -30,6 +30,7 @@ using Newtonsoft.Json;
|
|||
using ILogger = Serilog.ILogger;
|
||||
using Microsoft.AspNetCore.Diagnostics.HealthChecks;
|
||||
using Ombi.HealthChecks;
|
||||
using Ombi.Attributes;
|
||||
|
||||
namespace Ombi
|
||||
{
|
||||
|
@ -97,6 +98,7 @@ namespace Ombi
|
|||
services.RegisterApplicationDependencies(); // Ioc and EF
|
||||
services.AddSwagger();
|
||||
services.AddAppSettingsValues(Configuration);
|
||||
services.AddScoped<WizardActionFilter>();
|
||||
|
||||
services.AddCors(o => o.AddPolicy("MyPolicy", builder =>
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue