Merge branch 'develop' of https://github.com/ombi-app/Ombi into develop

pull/4143/head
tidusjar 3 years ago
commit 8a9230730c

@ -3,7 +3,7 @@
<div id="result{{result.id}}" *ngIf="fullyLoaded" class="ombi-card dark-card c" [style.display]="hide ? 'none' : 'block'">
<div class="card-top-info">
<div class="top-left" id="type{{result.id}}">
{{RequestType[result.type] | humanize}}
{{ 'Common.' + RequestType[result.type] | translate }}
</div>
<div class="{{getStatusClass()}} top-right" id="status{{result.id}}">
<span class="indicator"></span><span class="indicator-text" id="availabilityStatus{{result.id}}">{{getAvailbilityStatus()}}</span>
@ -21,9 +21,10 @@
</div>
<div class="row button-request-container" *ngIf="!result.available && !result.approved && !result.requested">
<div class="button-request poster-overlay">
<button id="requestButton{{result.id}}{{result.type}}{{discoverType}}" mat-raised-button class="btn-green full-width poster-request-btn" (click)="request($event)">
<button id="requestButton{{result.id}}{{result.type}}{{discoverType}}" *ngIf="requestable" mat-raised-button class="btn-ombi full-width poster-request-btn" (click)="request($event)">
<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' | translate }}
</button>
</div>
</div>

@ -1,5 +1,4 @@
$ombi-primary:#3f3f3f;
$card-background: #2b2b2b;
@import "~styles/variables.scss";
#cardImage {
border-radius: 5px;
@ -141,19 +140,20 @@ small {
.card-top-info{
position: absolute;
text-transform: uppercase;
top: 0px;
width: 100%;
background-color: rgba(15,23,31,0.6);
background-color: rgba(15,23,31,0.7);
display:flex;
justify-content: space-between;
padding-top:0.6em;
padding-bottom:0.3em;
z-index:2;
letter-spacing: 0.2px;
}
.top-left {
font-size: 14px;
font-weight:200;
padding-left: 0.5em;
font-size: 14px;
}
@ -161,6 +161,7 @@ small {
/* common */
.top-right{
display:flex;
font-weight:200;
}
.top-right span.indicator, span.indicator-text {
@ -247,7 +248,7 @@ a.poster-overlay:hover{
width: 100%;
margin-left: 0;
margin-right: 0;
margin-top: -37px;
margin-top: -36px;
margin-bottom: 0px;
opacity:0;
transition: .5s ease;
@ -261,4 +262,8 @@ a.poster-overlay:hover{
.c:hover .button-request-container {
opacity:1;
}
.btn-ombi{
background-color:#293a4c;
}

@ -24,6 +24,8 @@ export class DiscoverCardComponent implements OnInit {
public fullyLoaded = false;
public loading: boolean;
public requestable: boolean;
// This data is needed to open the dialog
private tvSearchResult: ISearchTvResultV2;
@ -44,19 +46,10 @@ export class DiscoverCardComponent implements OnInit {
}
public async getExtraTvInfo() {
// if (this.result.tvMovieDb) {
this.tvSearchResult = await this.searchService.getTvInfoWithMovieDbId(+this.result.id);
// } else {
// this.tvSearchResult = await this.searchService.getTvInfo(+this.result.id);
// }
// if (!this.tvSearchResult || this.tvSearchResult?.status.length > 0 && this.tvSearchResult?.status === "404") {
// this.hide = true;
// return;
// }
this.tvSearchResult = await this.searchService.getTvInfoWithMovieDbId(+this.result.id);
this.requestable = true;
this.setTvDefaults(this.tvSearchResult);
this.updateTvItem(this.tvSearchResult);
}
public async getAlbumInformation() {
@ -69,12 +62,13 @@ export class DiscoverCardComponent implements OnInit {
if (art.image) {
this.result.posterPath = art.image;
this.fullyLoaded = true;
}
})
}
this.result.title = x.startYear ? `${x.name} (${x.startYear})` : x.name;
this.result.overview = x.overview;
this.fullyLoaded = true;
this.requestable = true;
});
}
@ -166,6 +160,7 @@ export class DiscoverCardComponent implements OnInit {
} else {
this.fullyLoaded = true;
}
this.requestable = true;
}
private updateMovieItem(updated: ISearchMovieResultV2) {

@ -71,7 +71,7 @@
.discover-filter-buttons-group {
background: $ombi-background-primary;
border: 1px solid $ombi-background-primary-accent;
border: 1px solid #293a4c;
border-radius: 30px;
color:#fff;
margin-bottom:10px;
@ -84,6 +84,7 @@
border-radius: 30px;
padding-left: 20px;
padding-right: 20px;
border-left:none;
}
::ng-deep .mat-button-toggle-appearance-standard .mat-button-toggle-label-content{
@ -91,7 +92,7 @@
}
.button-active{
background:$ombi-active;
background:#293a4c;
}

@ -221,7 +221,7 @@
.social-icons-container{
position:absolute;
top:84px;
top:0px;
right:0px;
width:100%;
background-color:rgba(15,23,31,.6);
@ -329,6 +329,10 @@
margin-left:10px;
}
.dark-theme{
position:relative;
}
@media (max-width:500px){
.row.justify-content-center.justify-content-sm-start.header-container{
flex-wrap:wrap;

@ -53,36 +53,33 @@
<i class="fa-lg fas fa-bars"></i>
</button>
<div class="col-8 col-lg-10 top-search-bar">
<span class="justify-content-center align-items-center">
<div class="top-search-block">
<!-- Search Bar -->
<div>
<div class="top-search-bar">
<app-nav-search></app-nav-search>
</div>
</span>
<button id="search-filter" mat-icon-button [matMenuTriggerFor]="filterMenu">
<i class="fa-lg fas fa-filter"></i>
</button>
<mat-menu #filterMenu="matMenu" yPosition="below" class="smaller-panel">
<mat-slide-toggle id="filterMovies" class="mat-menu-item slide-menu" [checked]="searchFilter.movies"
(click)="$event.stopPropagation()" (change)="changeFilter($event,SearchFilterType.Movie)">
{{ 'NavigationBar.Filter.Movies' | translate}}</mat-slide-toggle>
<mat-slide-toggle id="filterTv" class="mat-menu-item slide-menu" [checked]="searchFilter.tvShows"
(click)="$event.stopPropagation()" (change)="changeFilter($event,SearchFilterType.TvShow)">
{{ 'NavigationBar.Filter.TvShows' | translate}}</mat-slide-toggle>
<mat-slide-toggle id="filterMusic" class="mat-menu-item slide-menu" [checked]="searchFilter.music"
(click)="$event.stopPropagation()" (change)="changeFilter($event,SearchFilterType.Music)">
{{ 'NavigationBar.Filter.Music' | translate}}</mat-slide-toggle>
<!-- <mat-slide-toggle class="mat-menu-item slide-menu" [checked]="searchFilter.people"
(click)="$event.stopPropagation()" (change)="changeFilter($event,SearchFilterType.People)">
{{ 'NavigationBar.Filter.People' | translate}}</mat-slide-toggle> -->
</mat-menu>
</div>
<div class="col-1 top-filter">
<button id="search-filter" mat-icon-button [matMenuTriggerFor]="filterMenu">
<i class="fa-lg fas fa-filter"></i>
</button>
<mat-menu #filterMenu="matMenu" yPosition="below" class="smaller-panel">
<mat-slide-toggle id="filterMovies" class="mat-menu-item slide-menu" [checked]="searchFilter.movies"
(click)="$event.stopPropagation()" (change)="changeFilter($event,SearchFilterType.Movie)">
{{ 'NavigationBar.Filter.Movies' | translate}}</mat-slide-toggle>
<mat-slide-toggle id="filterTv" class="mat-menu-item slide-menu" [checked]="searchFilter.tvShows"
(click)="$event.stopPropagation()" (change)="changeFilter($event,SearchFilterType.TvShow)">
{{ 'NavigationBar.Filter.TvShows' | translate}}</mat-slide-toggle>
<mat-slide-toggle id="filterMusic" class="mat-menu-item slide-menu" [checked]="searchFilter.music"
(click)="$event.stopPropagation()" (change)="changeFilter($event,SearchFilterType.Music)">
{{ 'NavigationBar.Filter.Music' | translate}}</mat-slide-toggle>
<!-- <mat-slide-toggle class="mat-menu-item slide-menu" [checked]="searchFilter.people"
(click)="$event.stopPropagation()" (change)="changeFilter($event,SearchFilterType.People)">
{{ 'NavigationBar.Filter.People' | translate}}</mat-slide-toggle> -->
</mat-menu>
</div>
<div class="col-1">
<div class="profile-block">
<a routerLink="/user-preferences">
<img [matTooltip]="username" id="profile-image" class="profile-img" [src]="getUserImage()" />
<div class="profile-username" data-test="profile-username">{{username}}</div>
<div class="profile-img" data-test="profile-image"><img [src]="getUserImage()" /></div>
</a>
</div>

@ -24,7 +24,8 @@
}
.icon-spacing {
margin-right: 5%;
width:40px;
text-align: center;
}
.example-form {
@ -48,12 +49,6 @@
padding: 0px 5px;
}
::ng-deep .dark .active-list-item {
background: $accent-dark !important;
color:black !important;
font-weight:500;
}
.slide-menu {
width: 100%;
}
@ -62,6 +57,27 @@
max-width: 170px !important;
}
.top-bar-container{
width: 95%;
display: flex;
justify-content: center;
align-items: center;
margin: auto;
}
.top-search-block{
height:84px;
display:flex;
justify-content: center;
align-items: center;
flex:1;
margin-right:5%;
}
.top-search-bar{
width:100%;
}
.mat-drawer-content {
position: relative;
overflow: hidden;
@ -71,36 +87,34 @@
/* overflow: auto; */
}
.profile-img-container {
margin: 20px auto 10px;
overflow: hidden;
text-align: center;
width: 80%;
.profile-block a{
color: #FFF;
font-size: 0.8em;
font-weight: 100;
display:flex;
justify-content: flex-end;
align-items: flex-end;
text-transform: capitalize;
flex:0 0 250px;
}
.profile-img {
float: left;
width: 45px;
border-radius: 100%;
}
.profile-info {
overflow: hidden;
text-align: left;
}
.profile-info > h3 {
font-size: 15px;
text-transform: capitalize;
// color: #333;
margin-bottom: 2px;
.profile-username{
justify-content: center;
display:flex;
height:50px;
align-items: center;
margin-right:5px;
}
.profile-info > p {
// color: #333;
font-size: 11px;
margin-top: 5px;
@media (max-width: 600px) {
.profile-username{
display:none;
}
}
.profile-img img {
width: 45px;
width: 50px;
}
@ -125,7 +139,6 @@
text-transform: uppercase;
color: $ombi-active;
align-items:center;
justify-content: center;
font-weight: 700;
font-size:36px;
padding:40px 20px;
@ -133,7 +146,6 @@
max-width: 350px;
display: flex;
white-space: normal;
text-align: center;
}
.outer-profile {
@ -173,18 +185,11 @@
.top-bar-container{
background: $ombi-background-primary;
color:$ombi-background-primary-accent;
padding-top:1em;
}
}
.top-search-bar{
margin-left: 30px;
}
::ng-deep .mat-toolbar-row, .mat-toolbar-single-row{
height:auto;
}
.top-search-bar{
height:84px;
}

@ -39,7 +39,6 @@ $ombi-accent: #258a6d;
::ng-deep .top-search-bar .mat-form-field-flex{
border: 1px solid #35465c;
border-radius:30px;
margin-top:20px;
height:50px;
}

@ -1,30 +1,26 @@
<div class="small-middle-container" *ngIf="username">
<div class="row h-100">
<div class="col-1">
<img class="profile-img" [src]="getProfileImage()">
</div>
<div class="col-11 align-middle">
<h2 id="usernameTitle">{{username}} <small id="emailTitle" *ngIf="user.emailAddress">({{user.emailAddress}})</small></h2>
</div>
<div class="d-flex">
<img class="profile-img" [src]="getProfileImage()">
<h2 id="usernameTitle">{{username}}
<small id="emailTitle" *ngIf="user.emailAddress">({{user.emailAddress}})</small>
</h2>
</div>
<mat-tab-group>
<mat-tab label="Profile">
<div class="tab-content">
<div class="row">
<div class="col-1">
<div class="row user-type-row">
<div class="col-5 col-sm-3 col-md-2">
User Type:
</div>
<div class="col-11">
<div class="col-7 col-sm-9 col-md-10">
{{UserType[user.userType]}}
</div>
</div>
<div class="row">
<div class="col-4">
<div class="col-12 col-sm-6 col-xl-5">
<div>
<small>{{'UserPreferences.LanguageDescription' | translate}}</small>
<br>
@ -38,14 +34,9 @@
</mat-select>
</mat-form-field>
</div>
<div>
</div>
</div>
<div class="col-1"></div>
<div class="col-4">
<div class="col-12 col-sm-6 col-xl-5">
<div>
<small>{{'UserPreferences.StreamingCountryDescription' | translate}}</small>
<br>
@ -58,13 +49,8 @@
</mat-select>
</mat-form-field>
</div>
<div>
</div>
</div>
</div>
</div>
</mat-tab>

@ -5,9 +5,22 @@
}
.profile-img {
border-radius: 100%;
width: 75px;
height: 75px;
margin-right: 20px;
border-radius: 100%;
}
#usernameTitle {
margin: 0;
align-self: center;
overflow-wrap: anywhere;
}
.user-type-row {
padding-bottom: 1.25em;
}
.my-auto {
margin-top: auto;
margin-bottom: auto;
@ -19,5 +32,5 @@
}
.tab-content {
margin-top: 1%;
margin-top: 1.5em;
}

@ -31,7 +31,9 @@
"Validation": "Please check your entered values"
},
"Cancel": "Cancel",
"Submit": "Submit"
"Submit": "Submit",
"tvShow": "TV Show",
"movie": "Movie"
},
"PasswordReset": {
"EmailAddressPlaceholder": "Email Address",

@ -69,7 +69,11 @@ class NavBar {
}
get userPreferences(): Cypress.Chainable<any> {
return cy.get('#profile-image');
return cy.getByData('profile-image');
}
get username(): Cypress.Chainable<any> {
return cy.getByData('profile-username');
}
get logout(): Cypress.Chainable<any> {

@ -0,0 +1,85 @@
describe("TV Request V1 API tests", () => {
beforeEach(() => {
cy.login();
});
it("Request All of TV Show (Fear the Walking Dead)", () => {
const request = {
TvDbId: 290853,
RequestAll: true,
};
cy.api({
url: "/api/v1/request/tv",
body: JSON.stringify(request),
method: "POST",
headers: {
Authorization: "Bearer " + window.localStorage.getItem("id_token"),
"Content-Type": "application/json",
},
}).then((res) => {
expect(res.status).equal(200);
const body = res.body;
expect(body.result).to.be.true;
expect(body.requestId).not.to.be.null;
expect(body.isError).to.be.false;
expect(body.errorMessage).to.be.null;
});
});
it("Request First Season of TV Show (American Horror Story)", () => {
const request = {
TvDbId: 250487,
FirstSeason: true,
};
cy.api({
url: "/api/v1/request/tv",
body: JSON.stringify(request),
method: "POST",
headers: {
Authorization: "Bearer " + window.localStorage.getItem("id_token"),
"Content-Type": "application/json",
},
}).then((res) => {
expect(res.status).equal(200);
const body = res.body;
expect(body.result).to.be.true;
expect(body.requestId).not.to.be.null;
expect(body.isError).to.be.false;
expect(body.errorMessage).to.be.null;
});
});
it("Request Two Episode of First Season TV Show (The Sopranos)", () => {
const request = {
TvDbId: 75299,
Seasons: [
{
SeasonNumber: 1,
Episodes: [
{ EpisodeNumber: 1 },
{ EpisodeNumber: 2 },
],
},
],
};
cy.api({
url: "/api/v1/request/tv",
body: JSON.stringify(request),
method: "POST",
headers: {
Authorization: "Bearer " + window.localStorage.getItem("id_token"),
"Content-Type": "application/json",
},
}).then((res) => {
expect(res.status).equal(200);
const body = res.body;
expect(body.result).to.be.true;
expect(body.requestId).not.to.be.null;
expect(body.isError).to.be.false;
expect(body.errorMessage).to.be.null;
});
});
});

@ -197,7 +197,7 @@ describe("Discover Cards Requests Tests", () => {
});
});
it.only("Available TV does not allow us to request", () => {
it("Available TV does not allow us to request", () => {
cy.intercept("GET", "**/search/Tv/popular/**", (req) => {
req.reply((res) => {
const body = res.body;

@ -0,0 +1,29 @@
import { discoverPage as Page } from "@/integration/page-objects";
import { DiscoverType } from "@/integration/page-objects/shared/DiscoverCard";
const mobiles = ['samsung-s10', 'iphone-x', 'iphone-xr', 'iphone-8']
describe("Discover Responsive Tests", () => {
beforeEach(() => {
cy.login();
});
mobiles.forEach((size: any) => {
// make assertions on the logo using
// an array of different viewports
it(`Should display card on ${size} screen`, () => {
window.localStorage.setItem("DiscoverOptions2", "2");
cy.intercept("GET", "**/search/Movie/Popular/**").as("moviePopular");
cy.viewport(size);
Page.visit();
cy.wait("@moviePopular").then((intecept) => {
const id = intecept.response.body[0].id;
const card = Page.popularCarousel.getCard(id, true, DiscoverType.Popular);
card.title.realHover();
card.verifyTitle(intecept.response.body[0].title);
})
})
})
});

@ -11,6 +11,7 @@ describe("Navigation Bar Tests", () => {
Page.navbar.requests.should("be.visible");
Page.navbar.discover.should("be.visible");
Page.navbar.userPreferences.should("be.visible");
Page.navbar.username.contains("a");
Page.navbar.logout.should("be.visible");
});
@ -34,6 +35,7 @@ describe("Navigation Bar Tests", () => {
Page.navbar.requests.should("be.visible");
Page.navbar.discover.should("be.visible");
Page.navbar.userPreferences.should("be.visible");
Page.navbar.username.contains(id);
Page.navbar.logout.should("be.visible");
});
});

@ -16,7 +16,7 @@ describe("Search Tests", () => {
card.topLevelCard.realHover();
card.title.should('have.text', "Dexter's Laboratory");
card.overview.contains('Cartoon Network');
card.requestType.contains('Tv Show');
card.requestType.contains('TV Show');
card.requestButton.should('exist');
});
@ -115,7 +115,7 @@ describe("Search Tests", () => {
card.topLevelCard.realHover();
card.title.should('have.text', "It's Always Sunny in Philadelphia");
card.overview.contains('Irish pub');
card.requestType.contains('Tv Show');
card.requestType.contains('TV Show');
card.requestButton.should('exist');
});

Loading…
Cancel
Save