mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-21 05:43:19 -07:00
Added the remaining requests into the navbar, just need to dynamically update it now
This commit is contained in:
parent
19933f8186
commit
8d05dfc4c2
7 changed files with 128 additions and 25 deletions
|
@ -53,7 +53,7 @@ import { TokenResetPasswordComponent } from "./login/tokenresetpassword.componen
|
||||||
// Services
|
// Services
|
||||||
import { AuthGuard } from "./auth/auth.guard";
|
import { AuthGuard } from "./auth/auth.guard";
|
||||||
import { AuthService } from "./auth/auth.service";
|
import { AuthService } from "./auth/auth.service";
|
||||||
import { ImageService, SettingsService, CustomPageService } from "./services";
|
import { ImageService, SettingsService, CustomPageService, RequestService } from "./services";
|
||||||
import { LandingPageService } from "./services";
|
import { LandingPageService } from "./services";
|
||||||
import { NotificationService } from "./services";
|
import { NotificationService } from "./services";
|
||||||
import { IssuesService, JobService, PlexTvService, StatusService, SearchService, IdentityService, MessageService } from "./services";
|
import { IssuesService, JobService, PlexTvService, StatusService, SearchService, IdentityService, MessageService } from "./services";
|
||||||
|
@ -65,6 +65,8 @@ import { OverlayModule } from "@angular/cdk/overlay";
|
||||||
import { StorageService } from "./shared/storage/storage-service";
|
import { StorageService } from "./shared/storage/storage-service";
|
||||||
import { SignalRNotificationService } from "./services/signlarnotification.service";
|
import { SignalRNotificationService } from "./services/signlarnotification.service";
|
||||||
import { MatMenuModule } from "@angular/material/menu";
|
import { MatMenuModule } from "@angular/material/menu";
|
||||||
|
import { RemainingRequestsComponent } from "./shared/remaining-requests/remaining-requests.component";
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: "*", component: PageNotFoundComponent },
|
{ path: "*", component: PageNotFoundComponent },
|
||||||
{ path: "", redirectTo: "/discover", pathMatch: "full" },
|
{ path: "", redirectTo: "/discover", pathMatch: "full" },
|
||||||
|
@ -168,7 +170,9 @@ export function JwtTokenGetter() {
|
||||||
LoginOAuthComponent,
|
LoginOAuthComponent,
|
||||||
MyNavComponent,
|
MyNavComponent,
|
||||||
NavSearchComponent,
|
NavSearchComponent,
|
||||||
|
RemainingRequestsComponent,
|
||||||
],
|
],
|
||||||
|
|
||||||
providers: [
|
providers: [
|
||||||
NotificationService,
|
NotificationService,
|
||||||
AuthService,
|
AuthService,
|
||||||
|
@ -187,6 +191,7 @@ export function JwtTokenGetter() {
|
||||||
SearchV2Service,
|
SearchV2Service,
|
||||||
MessageService,
|
MessageService,
|
||||||
StorageService,
|
StorageService,
|
||||||
|
RequestService,
|
||||||
SignalRNotificationService,
|
SignalRNotificationService,
|
||||||
{
|
{
|
||||||
provide: APP_BASE_HREF,
|
provide: APP_BASE_HREF,
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
<mat-sidenav #drawer class="sidenav" fixedInViewport="true"
|
<mat-sidenav #drawer class="sidenav" fixedInViewport="true"
|
||||||
[attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'" [mode]="(isHandset$ | async) ? 'over' : 'side'"
|
[attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'" [mode]="(isHandset$ | async) ? 'over' : 'side'"
|
||||||
[opened]="!(isHandset$ | async)">
|
[opened]="!(isHandset$ | async)">
|
||||||
|
|
||||||
<mat-toolbar>{{applicationName}}</mat-toolbar>
|
<mat-toolbar>{{applicationName}}</mat-toolbar>
|
||||||
|
|
||||||
<div class="outer-profile">
|
<div class="outer-profile">
|
||||||
<div class="profile-img-container">
|
<div class="profile-img-container">
|
||||||
<div class="profile-img">
|
<div class="profile-img">
|
||||||
|
@ -45,7 +47,7 @@
|
||||||
<mat-icon *ngIf="theme === 'light'" aria-label="Side nav toggle icon">brightness_4</mat-icon>
|
<mat-icon *ngIf="theme === 'light'" aria-label="Side nav toggle icon">brightness_4</mat-icon>
|
||||||
{{ 'NavigationBar.ChangeTheme' | translate }}
|
{{ 'NavigationBar.ChangeTheme' | translate }}
|
||||||
</a>
|
</a>
|
||||||
<a id="nav-logout" class="bottom-nav-link" mat-list-item [routerLinkActive]="'active-list-item'"
|
<a id="nav-logout" mat-list-item [routerLinkActive]="'active-list-item'"
|
||||||
aria-label="Toggle sidenav" (click)="logOut();">
|
aria-label="Toggle sidenav" (click)="logOut();">
|
||||||
<mat-icon aria-label="Side nav toggle icon">exit_to_app</mat-icon>
|
<mat-icon aria-label="Side nav toggle icon">exit_to_app</mat-icon>
|
||||||
{{ 'NavigationBar.Logout' | translate }}
|
{{ 'NavigationBar.Logout' | translate }}
|
||||||
|
@ -53,7 +55,16 @@
|
||||||
|
|
||||||
|
|
||||||
</mat-nav-list>
|
</mat-nav-list>
|
||||||
|
|
||||||
|
<div class="bottom-nav full">
|
||||||
|
<div class="outer-profile">
|
||||||
|
<app-remaining-requests [type]="RequestType.movie"></app-remaining-requests>
|
||||||
|
<app-remaining-requests [type]="RequestType.tvShow"></app-remaining-requests>
|
||||||
|
<app-remaining-requests [type]="RequestType.album"></app-remaining-requests>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</mat-sidenav>
|
</mat-sidenav>
|
||||||
|
|
||||||
<mat-sidenav-content>
|
<mat-sidenav-content>
|
||||||
<mat-toolbar color="primary">
|
<mat-toolbar color="primary">
|
||||||
<button type="button" aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()"
|
<button type="button" aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()"
|
||||||
|
|
|
@ -71,23 +71,6 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
/* overflow: auto; */
|
/* overflow: auto; */
|
||||||
}
|
}
|
||||||
// Changed color with !important and changed the font weight
|
|
||||||
/*.active-list-item-dark {
|
|
||||||
background: $accent-dark !important;
|
|
||||||
color:black !important;
|
|
||||||
font-weight:500;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
// changed bottom to 10px so when you overlay a link it won't get blocked by URL
|
|
||||||
#bottom-nav-link {
|
|
||||||
bottom: 10px;
|
|
||||||
position: absolute !important;
|
|
||||||
//background-color:#E84C3D;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*bottom-nav-link:hover{
|
|
||||||
background-color:rgb(226, 52, 36) !important;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
.profile-img-container {
|
.profile-img-container {
|
||||||
margin: 20px auto 10px;
|
margin: 20px auto 10px;
|
||||||
|
@ -127,3 +110,13 @@
|
||||||
box-shadow: inset 0 0 3px #000000;
|
box-shadow: inset 0 0 3px #000000;
|
||||||
padding: 1px;
|
padding: 1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.full {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.bottom-nav {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
|
@ -8,7 +8,7 @@ import { SettingsService } from '../services';
|
||||||
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
|
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
|
||||||
import { SearchFilter } from './SearchFilter';
|
import { SearchFilter } from './SearchFilter';
|
||||||
import { Md5 } from 'ts-md5/dist/md5';
|
import { Md5 } from 'ts-md5/dist/md5';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { RequestType } from '../interfaces';
|
||||||
|
|
||||||
export enum SearchFilterType {
|
export enum SearchFilterType {
|
||||||
Movie = 1,
|
Movie = 1,
|
||||||
|
@ -43,11 +43,11 @@ export class MyNavComponent implements OnInit {
|
||||||
public SearchFilterType = SearchFilterType;
|
public SearchFilterType = SearchFilterType;
|
||||||
public emailHash: string | Int32Array;
|
public emailHash: string | Int32Array;
|
||||||
public welcomeText: string;
|
public welcomeText: string;
|
||||||
|
public RequestType = RequestType;
|
||||||
|
|
||||||
constructor(private breakpointObserver: BreakpointObserver,
|
constructor(private breakpointObserver: BreakpointObserver,
|
||||||
private settingsService: SettingsService,
|
private settingsService: SettingsService,
|
||||||
private store: StorageService,
|
private store: StorageService) {
|
||||||
private translate: TranslateService) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public async ngOnInit() {
|
public async ngOnInit() {
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
import { Component, Input, OnInit } from "@angular/core";
|
import { Component, Input, OnInit } from "@angular/core";
|
||||||
import { Observable } from "rxjs";
|
|
||||||
import {
|
import {
|
||||||
debounceTime,
|
debounceTime,
|
||||||
distinctUntilChanged,
|
|
||||||
switchMap,
|
switchMap,
|
||||||
tap,
|
tap,
|
||||||
finalize,
|
finalize,
|
||||||
} from "rxjs/operators";
|
} from "rxjs/operators";
|
||||||
|
|
||||||
import { empty, of } from "rxjs";
|
import { empty} from "rxjs";
|
||||||
import { SearchV2Service } from "../services/searchV2.service";
|
import { SearchV2Service } from "../services/searchV2.service";
|
||||||
import { IMultiSearchResult } from "../interfaces";
|
import { IMultiSearchResult } from "../interfaces";
|
||||||
import { Router } from "@angular/router";
|
import { Router } from "@angular/router";
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<div *ngIf="remaining?.hasLimit">
|
||||||
|
<small id="remainingRequests" class="text-center">
|
||||||
|
<mat-icon [matTooltip]="getTooltipContent()">{{matIcon}}</mat-icon> {{'Requests.Remaining.Quota' | translate: {remaining: remaining.remaining, total: remaining.limit} }}
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,89 @@
|
||||||
|
import { Component, Input, OnInit } from "@angular/core";
|
||||||
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
|
import { RequestType } from "../../interfaces";
|
||||||
|
import { IRemainingRequests } from "../../interfaces/IRemainingRequests";
|
||||||
|
import { RequestService } from "../../services";
|
||||||
|
@Component({
|
||||||
|
selector: "app-remaining-requests",
|
||||||
|
templateUrl: "remaining-requests.component.html",
|
||||||
|
styles: [`.mat-icon {
|
||||||
|
vertical-align: middle;
|
||||||
|
}`],
|
||||||
|
})
|
||||||
|
export class RemainingRequestsComponent implements OnInit {
|
||||||
|
|
||||||
|
@Input() type: RequestType;
|
||||||
|
public RequestType = RequestType;
|
||||||
|
public remaining: IRemainingRequests;
|
||||||
|
public daysUntil: number;
|
||||||
|
public hoursUntil: number;
|
||||||
|
public minutesUntil: number;
|
||||||
|
public matIcon: string;
|
||||||
|
|
||||||
|
constructor(private requestService: RequestService,
|
||||||
|
private translate: TranslateService) { }
|
||||||
|
|
||||||
|
public ngOnInit(): void {
|
||||||
|
this.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public getTooltipContent() : string {
|
||||||
|
if (this.daysUntil > 1) {
|
||||||
|
return this.translate.instant('Requests.Remaining.NextDays', { time: this.daysUntil});
|
||||||
|
}
|
||||||
|
if (this.hoursUntil > 1 && this.daysUntil <= 1) {
|
||||||
|
return this.translate.instant('Requests.Remaining.NextHours', { time: this.hoursUntil});
|
||||||
|
}
|
||||||
|
if (this.minutesUntil >= 1 && this.hoursUntil <= 1 && this.daysUntil <= 1) {
|
||||||
|
return this.minutesUntil == 1
|
||||||
|
? this.translate.instant('Requests.Remaining.NextMinute', { time: this.minutesUntil})
|
||||||
|
: this.translate.instant('Requests.Remaining.NextMinutes', { time: this.minutesUntil});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private start() {
|
||||||
|
|
||||||
|
const callback = (remaining => {
|
||||||
|
this.remaining = remaining;
|
||||||
|
if (this.remaining && this.remaining.hasLimit) {
|
||||||
|
this.calculateTime();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
switch (this.type) {
|
||||||
|
case RequestType.movie:
|
||||||
|
this.requestService.getRemainingMovieRequests().subscribe(callback);
|
||||||
|
this.matIcon = "movie";
|
||||||
|
|
||||||
|
break;
|
||||||
|
case RequestType.tvShow:
|
||||||
|
this.requestService.getRemainingTvRequests().subscribe(callback);
|
||||||
|
this.matIcon = "tv";
|
||||||
|
|
||||||
|
break;
|
||||||
|
case RequestType.album:
|
||||||
|
this.requestService.getRemainingMusicRequests().subscribe(callback);
|
||||||
|
this.matIcon = "library_music";
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private calculateTime(): void {
|
||||||
|
this.daysUntil = Math.ceil(this.daysUntilNextRequest());
|
||||||
|
this.hoursUntil = Math.ceil(this.hoursUntilNextRequest());
|
||||||
|
this.minutesUntil = Math.ceil(this.minutesUntilNextRequest());
|
||||||
|
}
|
||||||
|
|
||||||
|
private daysUntilNextRequest(): number {
|
||||||
|
return (new Date(this.remaining.nextRequest).getTime() - new Date().getTime()) / 1000 / 60 / 60 / 24;
|
||||||
|
}
|
||||||
|
|
||||||
|
private hoursUntilNextRequest(): number {
|
||||||
|
return (new Date(this.remaining.nextRequest).getTime() - new Date().getTime()) / 1000 / 60 / 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
private minutesUntilNextRequest(): number {
|
||||||
|
return (new Date(this.remaining.nextRequest).getTime() - new Date().getTime()) / 1000 / 60;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue