mirror of
https://github.com/Ombi-app/Ombi.git
synced 2025-08-22 06:13:22 -07:00
started component
This commit is contained in:
parent
32cbff19b0
commit
5b55135256
18 changed files with 998 additions and 65 deletions
|
@ -16,5 +16,6 @@ namespace Ombi.Core.Models.Requests
|
|||
public string Overview { get; set; }
|
||||
public DateTime ReleaseDate { get; set; }
|
||||
public bool Approved { get; set; }
|
||||
public string MediaId { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,8 @@ namespace Ombi.Core.Services
|
|||
Type = RequestType.Movie,
|
||||
Approved = item.Approved,
|
||||
UserId = item.RequestedUserId,
|
||||
Username = item.RequestedUser.UserAlias
|
||||
Username = item.RequestedUser.UserAlias,
|
||||
MediaId = item.TheMovieDbId.ToString(),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -82,7 +83,8 @@ namespace Ombi.Core.Services
|
|||
Title = item.Title,
|
||||
Type = RequestType.Album,
|
||||
UserId = item.RequestedUserId,
|
||||
Username = item.RequestedUser.UserAlias
|
||||
Username = item.RequestedUser.UserAlias,
|
||||
MediaId = item.ForeignAlbumId,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -101,7 +103,8 @@ namespace Ombi.Core.Services
|
|||
Title = item.ParentRequest.Title,
|
||||
Type = RequestType.TvShow,
|
||||
UserId = item.RequestedUserId,
|
||||
Username = item.RequestedUser.UserAlias
|
||||
Username = item.RequestedUser.UserAlias,
|
||||
MediaId = item.ParentRequest.ExternalProviderId.ToString()
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -6,11 +6,16 @@ module.exports = {
|
|||
"addons": [
|
||||
"@storybook/addon-links",
|
||||
"@storybook/addon-essentials",
|
||||
"@storybook/addon-interactions"
|
||||
"@storybook/addon-interactions",
|
||||
"@storybook/preset-scss",
|
||||
],
|
||||
"framework": "@storybook/angular",
|
||||
"core": {
|
||||
"builder": "@storybook/builder-webpack5"
|
||||
},
|
||||
"staticDirs": ['../../wwwroot/images']
|
||||
"staticDirs": [
|
||||
'../../wwwroot/images',
|
||||
'../../wwwroot/translations',
|
||||
"./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
|
||||
]
|
||||
}
|
|
@ -1,5 +1,8 @@
|
|||
import { setCompodocJson } from "@storybook/addon-docs/angular";
|
||||
import docJson from "../documentation.json";
|
||||
// import '../src/styles/Styles.scss';
|
||||
import '../src/styles/_imports.scss';
|
||||
|
||||
setCompodocJson(docJson);
|
||||
|
||||
export const parameters = {
|
||||
|
|
|
@ -26,12 +26,12 @@
|
|||
"@angular/platform-server": "^14.0.0",
|
||||
"@angular/router": "^14.0.0",
|
||||
"@angularclass/hmr": "^3.0.0",
|
||||
"@microsoft/signalr": "^6.0.7",
|
||||
"@auth0/angular-jwt": "^5.0.2",
|
||||
"@fortawesome/fontawesome-free": "^6.0.0",
|
||||
"@fullcalendar/core": "^4.2.0",
|
||||
"@fullcalendar/daygrid": "^4.4.0",
|
||||
"@fullcalendar/interaction": "^4.2.0",
|
||||
"@microsoft/signalr": "^6.0.7",
|
||||
"@ngx-translate/core": "^14.0.0",
|
||||
"@ngx-translate/http-loader": "^7.0.0",
|
||||
"@ngxs/devtools-plugin": "^3.7.3",
|
||||
|
@ -57,16 +57,16 @@
|
|||
"popper.js": "^1.14.3",
|
||||
"primeicons": "^5.0.0",
|
||||
"primeng": "^13.2.0",
|
||||
"protractor": "~5.4.0",
|
||||
"rxjs": "^7.5.4",
|
||||
"sass-recursive-map-merge": "^1.0.1",
|
||||
"store": "^2.0.12",
|
||||
"ts-md5": "^1.2.7",
|
||||
"tslib": "^1.10.0",
|
||||
"tslint-angular": "^1.1.2",
|
||||
"zone.js": "~0.11.4",
|
||||
"protractor": "~5.4.0",
|
||||
"ts-node": "~5.0.1",
|
||||
"tslint": "^5.12.0"
|
||||
"tslib": "^1.10.0",
|
||||
"tslint": "^5.12.0",
|
||||
"tslint-angular": "^1.1.2",
|
||||
"zone.js": "~0.11.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular-devkit/build-angular": "^14.0.0",
|
||||
|
@ -75,17 +75,19 @@
|
|||
"@angular/language-service": "^14.0.0",
|
||||
"@babel/core": "^7.18.9",
|
||||
"@compodoc/compodoc": "^1.1.19",
|
||||
"@types/node": "^16.11.45",
|
||||
"@storybook/addon-actions": "^6.5.9",
|
||||
"@storybook/addon-essentials": "^6.5.9",
|
||||
"@storybook/addon-interactions": "^6.5.9",
|
||||
"@storybook/addon-links": "^6.5.9",
|
||||
"@storybook/angular": "^6.5.9",
|
||||
"@storybook/builder-webpack5": "^6.5.9",
|
||||
"@storybook/cli": "^6.5.9",
|
||||
"@storybook/manager-webpack5": "^6.5.9",
|
||||
"@storybook/testing-library": "^0.0.13",
|
||||
"@storybook/preset-scss": "^1.0.3",
|
||||
"@types/jasmine": "~3.6.7",
|
||||
"@types/jasminewd2": "~2.0.8",
|
||||
"@types/node": "^16.11.45",
|
||||
"babel-loader": "^8.2.5",
|
||||
"chromatic": "^6.7.1",
|
||||
"codelyzer": "^6.0.1",
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
.detailed-container {
|
||||
width: 400px;
|
||||
|
||||
|
||||
|
||||
|
||||
::ng-deep .poster {
|
||||
border-radius: 10px;
|
||||
opacity: 1;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
transition: .5s ease;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
// also exported from '@storybook/angular' if you can deal with breaking changes in 6.1
|
||||
import { APP_BASE_HREF } from '@angular/common';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { Story, Meta, moduleMetadata } from '@storybook/angular';
|
||||
import { ButtonComponent } from './button.component';
|
||||
|
||||
// More on default export: https://storybook.js.org/docs/angular/writing-stories/introduction#default-export
|
||||
export default {
|
||||
title: 'Button Component',
|
||||
component: ButtonComponent,
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
providers: [
|
||||
{
|
||||
provide: APP_BASE_HREF,
|
||||
useValue: {}
|
||||
},
|
||||
MatButtonModule
|
||||
]
|
||||
})
|
||||
]
|
||||
} as Meta;
|
||||
|
||||
// More on component templates: https://storybook.js.org/docs/angular/writing-stories/introduction#using-args
|
||||
const Template: Story<ButtonComponent> = (args: ButtonComponent) => ({
|
||||
props: args,
|
||||
});
|
||||
|
||||
export const Primary = Template.bind({});
|
||||
// More on args: https://storybook.js.org/docs/angular/writing-stories/args
|
||||
Primary.args = {
|
||||
type: 'primary',
|
||||
text: 'Primary',
|
||||
};
|
||||
|
||||
export const Secondary = Template.bind({});
|
||||
// More on args: https://storybook.js.org/docs/angular/writing-stories/args
|
||||
Secondary.args = {
|
||||
type: 'accent',
|
||||
text: 'Secondary',
|
||||
};
|
|
@ -0,0 +1,25 @@
|
|||
import { OmbiCommonModules } from "../modules";
|
||||
import { ChangeDetectionStrategy, Component, Input } from "@angular/core";
|
||||
import { MatButtonModule } from "@angular/material/button";
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'ombi-button',
|
||||
imports: [...OmbiCommonModules, MatButtonModule],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
styleUrls: ['./button.component.scss'],
|
||||
template: `
|
||||
<button [id]="id" [type]="type" [class]="class" [data-toggle]="dataToggle" mat-raised-button [data-target]="dataTarget">{{text}}</button>
|
||||
`
|
||||
})
|
||||
export class ButtonComponent {
|
||||
|
||||
@Input() public text: string;
|
||||
|
||||
@Input() public id: string;
|
||||
@Input() public type: string;
|
||||
@Input() public class: string;
|
||||
@Input('data-toggle') public dataToggle: string;
|
||||
@Input('data-target') public dataTarget: string;
|
||||
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
<!-- <div *ngIf="!request">Nothing</div>
|
||||
|
||||
<div id="request{{request.requestId}}" class="ombi-card dark-card c" [style.display]="hide ? 'none' : 'block'">
|
||||
<div class="card-top-info">
|
||||
<div class="top-left" id="type{{request.requestId}}-{{RequestType[request.requestType]}}">
|
||||
{{ 'Common.' + RequestType[request.requestType] }}
|
||||
</div>
|
||||
</div>
|
||||
<ombi-image [src]="request.posterPath" [type]="request.requestType" id="cardImage" class="image" alt="{{request.title}}"></ombi-image>
|
||||
<div [ngClass]="request.posterPath.includes('images/') ? 'middle-show' : 'middle'">
|
||||
<a class="poster-overlay">
|
||||
<div class="summary">
|
||||
<div class="title" id="title{{request.requestId}}">{{request.title}}</div>
|
||||
<div class="small-text ellipsis" id="overview{{request.requestId}}">{{request.overview}}</div>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div [ngClass]="request.posterPath.includes('images/') ? 'button-request-container-show' : 'button-request-container'" class="row" *ngIf="!request.available && !request.approved && !request.requested">
|
||||
|
||||
<div *ngIf="is4kEnabled && request.requestType === RequestType.movie;then show4K else regular"></div>
|
||||
<ng-template #show4K>
|
||||
<div class="button-request poster-overlay">
|
||||
<button [matMenuTriggerFor]="menu" id="requestButton{{request.requestId}}{{request.requestType}}" mat-raised-button class="btn-ombi full-width poster-request-btn">
|
||||
<i *ngIf="!loading" class="fa-lg fas fa-cloud-download-alt"></i>
|
||||
<i *ngIf="loading" class="fas fa-spinner fa-pulse fa-2x fa-fw" aria-hidden="true"></i>
|
||||
{{'Common.Request' }}
|
||||
</button>
|
||||
<mat-menu #menu="matMenu">
|
||||
<button mat-menu-item class="btn-ombi full-width poster-request-btn" (click)="submitRequest(false)">{{'Common.Request' }}</button>
|
||||
<button mat-menu-item class="btn-ombi full-width poster-request-btn" (click)="submitRequest(true)">{{'Common.Request4K' }}</button>
|
||||
</mat-menu>
|
||||
</div>
|
||||
</ng-template>
|
||||
<ng-template #regular>
|
||||
<div class="button-request poster-overlay">
|
||||
<button id="requestButton{{request.requestId}}{{request.requestType}}" *ngIf="requestable" mat-raised-button class="btn-ombi full-width poster-request-btn" (click)="submitRequest(false)">
|
||||
<i *ngIf="!loading" class="fa-lg fas fa-cloud-download-alt"></i>
|
||||
<i *ngIf="loading" class="fas fa-spinner fa-pulse fa-2x fa-fw" aria-hidden="true"></i>
|
||||
{{'Common.Request' }}
|
||||
</button>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
<div class="detailed-container">
|
||||
<div class="row">
|
||||
<div class="col-5">
|
||||
<ombi-image [src]="request.posterPath" [type]="request.requestType" class="poster" alt="{{request.title}}">
|
||||
</ombi-image>
|
||||
</div>
|
||||
<div class="col-7">
|
||||
<div class="row">
|
||||
<div class="col-12 title">
|
||||
<h3>{{request.title}}</h3>
|
||||
</div>
|
||||
<div class="col-12 overview">
|
||||
<p>{{request.overview}}</p>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<span>Requested By: {{request.userName}}</span>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<span>On: {{request.requestDate | amFromUtc | amLocal | amUserLocale | amDateFormat: 'l LT'}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-4">
|
||||
<button>Request</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,18 @@
|
|||
.detailed-container {
|
||||
width: 400px;
|
||||
|
||||
|
||||
|
||||
|
||||
::ng-deep .poster {
|
||||
border-radius: 10px;
|
||||
opacity: 1;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
transition: .5s ease;
|
||||
backface-visibility: hidden;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
// also exported from '@storybook/angular' if you can deal with breaking changes in 6.1
|
||||
import { APP_BASE_HREF } from '@angular/common';
|
||||
import { Story, Meta, moduleMetadata } from '@storybook/angular';
|
||||
import { IRecentlyRequested, RequestType } from '../../interfaces';
|
||||
import { DetailedCardComponent } from './detailed-card.component';
|
||||
import { TranslateModule } from "@ngx-translate/core";
|
||||
import { ImageService } from '../../services/image.service';
|
||||
|
||||
// More on default export: https://storybook.js.org/docs/angular/writing-stories/introduction#default-export
|
||||
export default {
|
||||
title: 'Detailed Card Component',
|
||||
component: DetailedCardComponent,
|
||||
decorators: [
|
||||
moduleMetadata({
|
||||
providers: [
|
||||
{
|
||||
provide: APP_BASE_HREF,
|
||||
useValue: {}
|
||||
},
|
||||
],
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
]
|
||||
})
|
||||
]
|
||||
} as Meta;
|
||||
|
||||
// More on component templates: https://storybook.js.org/docs/angular/writing-stories/introduction#using-args
|
||||
const Template: Story<DetailedCardComponent> = (args: DetailedCardComponent) => ({
|
||||
props: args,
|
||||
});
|
||||
|
||||
export const NewMovieRequest = Template.bind({});
|
||||
// More on args: https://storybook.js.org/docs/angular/writing-stories/args
|
||||
NewMovieRequest.args = {
|
||||
request: {
|
||||
title: 'The Matrix',
|
||||
approved: false,
|
||||
available: false,
|
||||
tvPartiallyAvailable: false,
|
||||
requestDate: new Date(2022, 1, 1),
|
||||
userName: 'John Doe',
|
||||
userId: '12345',
|
||||
requestType: RequestType.movie,
|
||||
mediaId: '603',
|
||||
overview: 'The Matrix is a movie about a group of people who are forced to fight against a powerful computer system that controls them.',
|
||||
releaseDate: new Date(2020, 1, 1),
|
||||
posterPath: "https://assets.fanart.tv/fanart/movies/603/movieposter/the-matrix-52256ae1021be.jpg"
|
||||
} as IRecentlyRequested,
|
||||
is4kEnabled: false,
|
||||
};
|
|
@ -0,0 +1,48 @@
|
|||
import { OmbiCommonModules } from "../modules";
|
||||
import { ChangeDetectionStrategy, Component, EventEmitter, Input, OnDestroy, OnInit, Output, ViewEncapsulation } from "@angular/core";
|
||||
import { IRecentlyRequested, RequestType } from "../../interfaces";
|
||||
import { ImageComponent } from "../image/image.component";
|
||||
import { ImageService } from "app/services";
|
||||
import { Subject, takeUntil } from "rxjs";
|
||||
import { PipeModule } from "app/pipes/pipe.module";
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'ombi-detailed-card',
|
||||
imports: [...OmbiCommonModules, ImageComponent, PipeModule],
|
||||
providers: [ImageService],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
templateUrl: './detailed-card.component.html',
|
||||
styleUrls: ['./detailed-card.component.scss']
|
||||
})
|
||||
export class DetailedCardComponent implements OnInit, OnDestroy {
|
||||
@Input() public request: IRecentlyRequested;
|
||||
@Input() public is4kEnabled: boolean = false;
|
||||
|
||||
@Output() public onRequest: EventEmitter<boolean> = new EventEmitter<boolean>();
|
||||
|
||||
public RequestType = RequestType;
|
||||
public loading: false;
|
||||
|
||||
private $imageSub = new Subject<void>();
|
||||
|
||||
constructor(private imageService: ImageService) { }
|
||||
|
||||
ngOnInit(): void {
|
||||
if (!this.request.posterPath) {
|
||||
this.imageService.getMoviePoster(this.request.mediaId).pipe(takeUntil(this.$imageSub)).subscribe(x => this.request.posterPath = x);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public submitRequest(is4k: boolean) {
|
||||
this.onRequest.emit(is4k);
|
||||
}
|
||||
|
||||
|
||||
public ngOnDestroy() {
|
||||
this.$imageSub.next();
|
||||
this.$imageSub.complete();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,2 +1,3 @@
|
|||
export * from "./image-background/image-background.component";
|
||||
export * from "./image/image.component";
|
||||
export * from "./image/image.component";
|
||||
export * from "./detailed-card/detailed-card.component";
|
|
@ -1,3 +1,5 @@
|
|||
import { CommonModule } from "@angular/common";
|
||||
import { HttpClientModule } from "@angular/common/http";
|
||||
import { MomentModule } from "ngx-moment";
|
||||
|
||||
export const OmbiCommonModules = [ CommonModule ];
|
||||
export const OmbiCommonModules = [ CommonModule, HttpClientModule, MomentModule ];
|
18
src/Ombi/ClientApp/src/app/interfaces/IRecentlyRequested.ts
Normal file
18
src/Ombi/ClientApp/src/app/interfaces/IRecentlyRequested.ts
Normal file
|
@ -0,0 +1,18 @@
|
|||
import { RequestType } from "./IRequestModel";
|
||||
|
||||
export interface IRecentlyRequested {
|
||||
requestId: number;
|
||||
requestType: RequestType;
|
||||
userId: string;
|
||||
userName: string;
|
||||
available: boolean;
|
||||
tvPartiallyAvailable: boolean;
|
||||
requestDate: Date;
|
||||
title: string;
|
||||
overview: string;
|
||||
releaseDate: Date;
|
||||
approved: boolean;
|
||||
mediaId: string;
|
||||
|
||||
posterPath: string;
|
||||
}
|
|
@ -21,3 +21,4 @@ export * from "./IVote";
|
|||
export * from "./IFailedRequests";
|
||||
export * from "./IHub";
|
||||
export * from "./ITester";
|
||||
export * from "./IRecentlyRequested";
|
||||
|
|
|
@ -44,5 +44,4 @@ export class ImageService extends ServiceHelpers {
|
|||
public getTvBackground(tvdbid: number): Observable<string> {
|
||||
return this.http.get<string>(`${this.url}background/tv/${tvdbid}`, { headers: this.headers });
|
||||
}
|
||||
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue