mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-20 21:33:15 -07:00
feat: ✨ moved the background image out into a standalone component
This commit is contained in:
parent
c08156ca32
commit
f6c1cd1236
14 changed files with 84 additions and 88 deletions
|
@ -68,6 +68,7 @@ import { TooltipModule } from "primeng/tooltip";
|
||||||
import { TranslateHttpLoader } from "@ngx-translate/http-loader";
|
import { TranslateHttpLoader } from "@ngx-translate/http-loader";
|
||||||
import { TranslateService } from "@ngx-translate/core";
|
import { TranslateService } from "@ngx-translate/core";
|
||||||
import { UnauthorizedInterceptor } from "./auth/unauthorized.interceptor";
|
import { UnauthorizedInterceptor } from "./auth/unauthorized.interceptor";
|
||||||
|
import { ImageBackgroundComponent } from "./components/";
|
||||||
import { environment } from "../environments/environment";
|
import { environment } from "../environments/environment";
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
|
@ -166,7 +167,8 @@ export function JwtTokenGetter() {
|
||||||
...environment.production ? [] :
|
...environment.production ? [] :
|
||||||
[
|
[
|
||||||
NgxsReduxDevtoolsPluginModule.forRoot(),
|
NgxsReduxDevtoolsPluginModule.forRoot(),
|
||||||
]
|
],
|
||||||
|
ImageBackgroundComponent
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<div @fadeInOut class="bg" [style.background-image]="background">
|
||||||
|
<div class="login-gradient-bar">
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,16 @@
|
||||||
|
.login-gradient-bar{
|
||||||
|
background: linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.6) 20.0%, rgba(0,0,0,0.6) 80.0%, transparent 60%),transparent;
|
||||||
|
height:100%;
|
||||||
|
width:100%;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg {
|
||||||
|
background-position: center center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-attachment: fixed;
|
||||||
|
background-size: cover;
|
||||||
|
height: 100vh;
|
||||||
|
width: 100vw;
|
||||||
|
position: fixed;
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
import { OmbiCommonModules } from "../modules";
|
||||||
|
import { Component, OnDestroy, OnInit } from "@angular/core";
|
||||||
|
import { DomSanitizer, SafeStyle } from "@angular/platform-browser";
|
||||||
|
import { BrowserAnimationsModule } from "@angular/platform-browser/animations";
|
||||||
|
import { ImageService } from "../../services";
|
||||||
|
import { fadeInOutAnimation } from "app/animations/fadeinout";
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
standalone: true,
|
||||||
|
selector: 'ombi-image-background',
|
||||||
|
templateUrl: './image-background.component.html',
|
||||||
|
styleUrls: ['./image-background.component.scss'],
|
||||||
|
imports: [...OmbiCommonModules, BrowserAnimationsModule],
|
||||||
|
providers: [ ImageService ],
|
||||||
|
animations: [ fadeInOutAnimation ],
|
||||||
|
})
|
||||||
|
export class ImageBackgroundComponent implements OnInit, OnDestroy {
|
||||||
|
|
||||||
|
public background: any;
|
||||||
|
private timer: NodeJS.Timer;
|
||||||
|
|
||||||
|
constructor(private images: ImageService, private sanitizer: DomSanitizer) { }
|
||||||
|
|
||||||
|
public ngOnDestroy(): void {
|
||||||
|
clearTimeout(this.timer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ngOnInit(): void {
|
||||||
|
this.cycleBackground();
|
||||||
|
|
||||||
|
this.timer = setInterval(() => {
|
||||||
|
this.cycleBackground();
|
||||||
|
}, 30000);
|
||||||
|
}
|
||||||
|
|
||||||
|
private cycleBackground() {
|
||||||
|
this.images.getRandomBackground().subscribe((x) => {
|
||||||
|
this.background = this.sanitizer.bypassSecurityTrustStyle("url(" + x.url + ")");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
1
src/Ombi/ClientApp/src/app/components/index.ts
Normal file
1
src/Ombi/ClientApp/src/app/components/index.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * from "./image-background/image-background.component";
|
3
src/Ombi/ClientApp/src/app/components/modules.ts
Normal file
3
src/Ombi/ClientApp/src/app/components/modules.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import { CommonModule } from "@angular/common";
|
||||||
|
|
||||||
|
export const OmbiCommonModules = [ CommonModule ];
|
|
@ -1,7 +1,4 @@
|
||||||
<div *ngIf="background" @fadeInOut class="bg" [style.background-image]="background">
|
<ombi-image-background></ombi-image-background>
|
||||||
<div class="login-gradient-bar">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="small-middle-container">
|
<div class="small-middle-container">
|
||||||
<div *ngIf="form && customizationSettings && authenticationSettings">
|
<div *ngIf="form && customizationSettings && authenticationSettings">
|
||||||
|
|
||||||
|
|
|
@ -11,23 +11,6 @@ img.center {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-gradient-bar{
|
|
||||||
background: linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.6) 20.0%, rgba(0,0,0,0.6) 80.0%, transparent 60%),transparent;
|
|
||||||
height:100%;
|
|
||||||
width:100%;
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.bg {
|
|
||||||
background-position: center center;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-attachment: fixed;
|
|
||||||
background-size: cover;
|
|
||||||
height: 100vh;
|
|
||||||
width: 100vw;
|
|
||||||
position: fixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-container.card {
|
.card-container.card {
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
padding: 45px 45px;
|
padding: 45px 45px;
|
||||||
|
|
|
@ -10,17 +10,12 @@ import { PlexTvService } from "../services";
|
||||||
import { SettingsService } from "../services";
|
import { SettingsService } from "../services";
|
||||||
import { StatusService } from "../services";
|
import { StatusService } from "../services";
|
||||||
|
|
||||||
import { DomSanitizer } from "@angular/platform-browser";
|
|
||||||
import { ImageService } from "../services";
|
|
||||||
|
|
||||||
import { fadeInOutAnimation } from "../animations/fadeinout";
|
|
||||||
import { StorageService } from "../shared/storage/storage-service";
|
import { StorageService } from "../shared/storage/storage-service";
|
||||||
import { MatSnackBar } from "@angular/material/snack-bar";
|
import { MatSnackBar } from "@angular/material/snack-bar";
|
||||||
import { CustomizationFacade } from "../state/customization";
|
import { CustomizationFacade } from "../state/customization";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./login.component.html",
|
templateUrl: "./login.component.html",
|
||||||
animations: [fadeInOutAnimation],
|
|
||||||
styleUrls: ["./login.component.scss"],
|
styleUrls: ["./login.component.scss"],
|
||||||
})
|
})
|
||||||
export class LoginComponent implements OnDestroy, OnInit {
|
export class LoginComponent implements OnDestroy, OnInit {
|
||||||
|
@ -28,7 +23,6 @@ export class LoginComponent implements OnDestroy, OnInit {
|
||||||
public customizationSettings: ICustomizationSettings;
|
public customizationSettings: ICustomizationSettings;
|
||||||
public authenticationSettings: IAuthenticationSettings;
|
public authenticationSettings: IAuthenticationSettings;
|
||||||
public plexEnabled: boolean;
|
public plexEnabled: boolean;
|
||||||
public background: any;
|
|
||||||
public landingFlag: boolean;
|
public landingFlag: boolean;
|
||||||
public baseUrl: string;
|
public baseUrl: string;
|
||||||
public loginWithOmbi: boolean;
|
public loginWithOmbi: boolean;
|
||||||
|
@ -46,7 +40,6 @@ export class LoginComponent implements OnDestroy, OnInit {
|
||||||
public get appNameTranslate(): object {
|
public get appNameTranslate(): object {
|
||||||
return { appName: this.appName };
|
return { appName: this.appName };
|
||||||
}
|
}
|
||||||
private timer: any;
|
|
||||||
private clientId: string;
|
private clientId: string;
|
||||||
|
|
||||||
private errorBody: string;
|
private errorBody: string;
|
||||||
|
@ -62,8 +55,6 @@ export class LoginComponent implements OnDestroy, OnInit {
|
||||||
private fb: UntypedFormBuilder,
|
private fb: UntypedFormBuilder,
|
||||||
private settingsService: SettingsService,
|
private settingsService: SettingsService,
|
||||||
private customziationFacade: CustomizationFacade,
|
private customziationFacade: CustomizationFacade,
|
||||||
private images: ImageService,
|
|
||||||
private sanitizer: DomSanitizer,
|
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
@Inject(APP_BASE_HREF) href: string,
|
@Inject(APP_BASE_HREF) href: string,
|
||||||
private translate: TranslateService,
|
private translate: TranslateService,
|
||||||
|
@ -111,14 +102,6 @@ export class LoginComponent implements OnDestroy, OnInit {
|
||||||
this.headerAuth();
|
this.headerAuth();
|
||||||
});
|
});
|
||||||
this.settingsService.getClientId().subscribe((x) => (this.clientId = x));
|
this.settingsService.getClientId().subscribe((x) => (this.clientId = x));
|
||||||
this.images.getRandomBackground().subscribe((x) => {
|
|
||||||
this.background = this.sanitizer.bypassSecurityTrustStyle(
|
|
||||||
"url(" + x.url + ")"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
this.timer = setInterval(() => {
|
|
||||||
this.cycleBackground();
|
|
||||||
}, 30000);
|
|
||||||
|
|
||||||
const base = this.href;
|
const base = this.href;
|
||||||
if (base.length > 1) {
|
if (base.length > 1) {
|
||||||
|
@ -284,18 +267,6 @@ export class LoginComponent implements OnDestroy, OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnDestroy() {
|
public ngOnDestroy() {
|
||||||
clearInterval(this.timer);
|
|
||||||
clearInterval(this.pinTimer);
|
clearInterval(this.pinTimer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private cycleBackground() {
|
|
||||||
this.images.getRandomBackground().subscribe((x) => {
|
|
||||||
this.background = "";
|
|
||||||
});
|
|
||||||
this.images.getRandomBackground().subscribe((x) => {
|
|
||||||
this.background = this.sanitizer.bypassSecurityTrustStyle(
|
|
||||||
"url(" + x.url + ")"
|
|
||||||
);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
|
|
||||||
<div *ngIf="background" @fadeInOut class="bg" [style.background-image]="background">
|
<ombi-image-background></ombi-image-background>
|
||||||
<div class="login-gradient-bar">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="small-middle-container">
|
<div class="small-middle-container">
|
||||||
<div *ngIf="form && customizationSettings">
|
<div *ngIf="form && customizationSettings">
|
||||||
|
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
import { PlatformLocation, APP_BASE_HREF } from "@angular/common";
|
import { APP_BASE_HREF } from "@angular/common";
|
||||||
import { Component, OnInit, Inject } from "@angular/core";
|
import { Component, OnInit, Inject } from "@angular/core";
|
||||||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
|
import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
|
||||||
import { DomSanitizer } from "@angular/platform-browser";
|
|
||||||
import { fadeInOutAnimation } from "../animations/fadeinout";
|
import { fadeInOutAnimation } from "../animations/fadeinout";
|
||||||
|
|
||||||
import { ICustomizationSettings } from "../interfaces";
|
import { ICustomizationSettings } from "../interfaces";
|
||||||
import { IdentityService, ImageService, NotificationService, SettingsService } from "../services";
|
import { IdentityService, NotificationService, SettingsService } from "../services";
|
||||||
import { CustomizationFacade } from "../state/customization";
|
import { CustomizationFacade } from "../state/customization";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
templateUrl: "./resetpassword.component.html",
|
templateUrl: "./resetpassword.component.html",
|
||||||
animations: [fadeInOutAnimation],
|
|
||||||
styleUrls: ["./login.component.scss"],
|
styleUrls: ["./login.component.scss"],
|
||||||
})
|
})
|
||||||
export class ResetPasswordComponent implements OnInit {
|
export class ResetPasswordComponent implements OnInit {
|
||||||
|
@ -19,12 +17,11 @@ export class ResetPasswordComponent implements OnInit {
|
||||||
public customizationSettings: ICustomizationSettings;
|
public customizationSettings: ICustomizationSettings;
|
||||||
public emailSettingsEnabled: boolean;
|
public emailSettingsEnabled: boolean;
|
||||||
public baseUrl: string;
|
public baseUrl: string;
|
||||||
public background: any;
|
|
||||||
private href: string;
|
private href: string;
|
||||||
|
|
||||||
constructor(private identityService: IdentityService, private notify: NotificationService,
|
constructor(private identityService: IdentityService, private notify: NotificationService,
|
||||||
private fb: UntypedFormBuilder, private settingsService: SettingsService, @Inject(APP_BASE_HREF) href:string,
|
private fb: UntypedFormBuilder, private settingsService: SettingsService, @Inject(APP_BASE_HREF) href:string,
|
||||||
private images: ImageService, private sanitizer: DomSanitizer, private customizationFacade: CustomizationFacade) {
|
private customizationFacade: CustomizationFacade) {
|
||||||
this.href = href;
|
this.href = href;
|
||||||
this.form = this.fb.group({
|
this.form = this.fb.group({
|
||||||
email: ["", [Validators.required]],
|
email: ["", [Validators.required]],
|
||||||
|
@ -32,9 +29,7 @@ export class ResetPasswordComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
this.images.getRandomBackground().subscribe(x => {
|
|
||||||
this.background = this.sanitizer.bypassSecurityTrustStyle("linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.7) 20.0%, rgba(0,0,0,0.7) 80.0%, transparent 80%),url(" + x.url + ")");
|
|
||||||
});
|
|
||||||
const base = this.href;
|
const base = this.href;
|
||||||
if (base.length > 1) {
|
if (base.length > 1) {
|
||||||
this.baseUrl = base;
|
this.baseUrl = base;
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
|
<ombi-image-background></ombi-image-background>
|
||||||
<div *ngIf="background" @fadeInOut class="bg" [style.background-image]="background">
|
|
||||||
<div class="login-gradient-bar">
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="small-middle-container">
|
<div class="small-middle-container">
|
||||||
<div *ngIf="form && customizationSettings">
|
<div *ngIf="form && customizationSettings">
|
||||||
|
|
||||||
|
@ -41,8 +37,6 @@
|
||||||
Password is <strong>required</strong></mat-error>
|
Password is <strong>required</strong></mat-error>
|
||||||
</mat-form-field>
|
</mat-form-field>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<button id="reset" mat-raised-button color="accent" [disabled]="form.invalid" type="submit">{{'Reset Password' | translate}}</button>
|
<button id="reset" mat-raised-button color="accent" [disabled]="form.invalid" type="submit">{{'Reset Password' | translate}}</button>
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
import { ActivatedRoute, Params } from "@angular/router";
|
import { ActivatedRoute, Params } from "@angular/router";
|
||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
|
import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms";
|
||||||
import { IdentityService, ImageService } from "../services";
|
import { IdentityService } from "../services";
|
||||||
|
|
||||||
import { CustomizationFacade } from "../state/customization";
|
import { CustomizationFacade } from "../state/customization";
|
||||||
import { DomSanitizer } from "@angular/platform-browser";
|
|
||||||
import { ICustomizationSettings } from "../interfaces";
|
import { ICustomizationSettings } from "../interfaces";
|
||||||
import { IResetPasswordToken } from "../interfaces";
|
import { IResetPasswordToken } from "../interfaces";
|
||||||
import { NotificationService } from "../services";
|
import { NotificationService } from "../services";
|
||||||
|
@ -19,13 +18,10 @@ export class TokenResetPasswordComponent implements OnInit {
|
||||||
|
|
||||||
public form: UntypedFormGroup;
|
public form: UntypedFormGroup;
|
||||||
public customizationSettings: ICustomizationSettings;
|
public customizationSettings: ICustomizationSettings;
|
||||||
public background: any;
|
|
||||||
public baseUrl: string;
|
public baseUrl: string;
|
||||||
|
|
||||||
constructor(private identityService: IdentityService, private router: Router, private route: ActivatedRoute, private notify: NotificationService,
|
constructor(private identityService: IdentityService, private router: Router, private route: ActivatedRoute, private notify: NotificationService,
|
||||||
private fb: UntypedFormBuilder, private location: PlatformLocation, private images: ImageService,
|
private fb: UntypedFormBuilder, private location: PlatformLocation, private customizationFacade: CustomizationFacade) {
|
||||||
private sanitizer: DomSanitizer, private customizationFacade: CustomizationFacade,
|
|
||||||
) {
|
|
||||||
|
|
||||||
this.route.queryParams
|
this.route.queryParams
|
||||||
.subscribe((params: Params) => {
|
.subscribe((params: Params) => {
|
||||||
|
@ -39,9 +35,6 @@ export class TokenResetPasswordComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ngOnInit() {
|
public ngOnInit() {
|
||||||
this.images.getRandomBackground().subscribe(x => {
|
|
||||||
this.background = this.sanitizer.bypassSecurityTrustStyle("linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.7) 20.0%, rgba(0,0,0,0.7) 80.0%, transparent 80%),url(" + x.url + ")");
|
|
||||||
});
|
|
||||||
const base = this.location.getBaseHrefFromDOM();
|
const base = this.location.getBaseHrefFromDOM();
|
||||||
if (base.length > 1) {
|
if (base.length > 1) {
|
||||||
this.baseUrl = base;
|
this.baseUrl = base;
|
||||||
|
@ -65,6 +58,5 @@ export class TokenResetPasswordComponent implements OnInit {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { PlatformLocation, APP_BASE_HREF } from "@angular/common";
|
import { APP_BASE_HREF } from "@angular/common";
|
||||||
import { Injectable, Inject } from "@angular/core";
|
import { Injectable, Inject } from "@angular/core";
|
||||||
import { Observable } from "rxjs";
|
import { Observable } from "rxjs";
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue