Update: Environment for Heroku Production

This commit is contained in:
Yûki VACHOT 2021-12-22 13:39:06 +01:00
parent 5fbdb7098e
commit 13daf10ca8
201 changed files with 34 additions and 2736 deletions

View file

@ -0,0 +1,80 @@
<div [class]="themeService.getClassTheme()">
<div class="myContainer">
<!-- Navbar -->
<div style="margin-bottom: 30px">
<app-navbar-user></app-navbar-user>
</div>
<!-- --------------------------------------------------------------------- -->
<!-- [Search bar] + [Sites de streaming] -->
<div style="width: 100%; margin: 0 auto;">
<!-- Search bar -->
<div class="input-group" style="width: 100%; margin: 0 auto;">
<div class="form-outline" style="width: 100%; margin: 0 auto;">
<input type="search" placeholder="Rechercher..." class="inputSearchBar" [(ngModel)]="search" (keydown)="onEnterOnSearchBar($event)"/>
<button mat-icon-button (click)="onSearch()">
<mat-icon>search</mat-icon>
</button>
</div>
</div>
<!-- Sites de streaming -->
<div style="margin-bottom: 20px">
<!-- youtube -->
<span>
&nbsp;
<mat-checkbox id="youtube" name="youtube" style="margin-left: 5px" [(ngModel)]="tabPlateform[0].isSelected"></mat-checkbox>
<img src="/assets/logo_plateforms/youtube.png" alt="logo" width="30px" height="25px" style="margin-left: 5px">
<label for="youtube" style="margin-left: 5px">Youtube</label>
&nbsp;
</span>
<!-- dailymotion -->
<span>
&nbsp;
<mat-checkbox id="dailymotion" name="dailymotion" style="margin-left: 5px" [(ngModel)]="tabPlateform[1].isSelected"></mat-checkbox>
<img src="/assets/logo_plateforms/dailymotion.png" alt="logo" width="25px" height="25px" style="margin-left: 5px">
<label for="dailymotion" style="margin-left: 5px">Dailymotion</label>
&nbsp;
</span>
</div>
</div>
<!-- --------------------------------------------------------------------- -->
<!-- [pub gauche] + [Grilles des videos] + [pub droite] -->
<mat-grid-list cols="11" rowHeight="75vh">
<!-- pub gauche -->
<mat-grid-tile colspan="2" rowspan="1" class="cellulePub">
<div class="conteneurPub">
<app-advert [ad]="ad1"></app-advert>
</div>
</mat-grid-tile>
<!-- Grilles des videos -->
<mat-grid-tile colspan="7" rowspan="1" class="celluleGrilleVideo">
<div class="conteneurVideosGrid">
<app-video-grid [tabVideo]="tabVideo" [search]="search" [sources]="sources" [indexPage]="indexPage"></app-video-grid>
</div>
</mat-grid-tile>
<!-- pub droite -->
<mat-grid-tile colspan="2" rowspan="1" class="cellulePub">
<div class="conteneurPub">
<app-advert [ad]="ad1"></app-advert>
</div>
</mat-grid-tile>
</mat-grid-list>
<br><br>
</div>
</div>

View file

@ -0,0 +1,90 @@
.lightTheme {
color: black;
border-color: black;
}
.darkTheme {
color: white;
border-color: white;
}
.myContainer {
text-align: center;
max-width: 100vw;
height: 100vh;
overflow-x: hidden;
overflow-y: scroll;
}
//--------------------------------------------------------------------------------------------
.inputSearchBar {
width: 40%;
font-size: large;
border-bottom: 10px;
border-radius: 5px;
}
//--------------------------------------------------------------------------------------------
.celluleGrilleVideo {
border: solid 2px;
border-radius: 5px;
width: 100%;
}
.lightTheme .celluleGrilleVideo{
border-color: black;
background-color: #f0f0f0;
}
.darkTheme .celluleGrilleVideo{
border-color: white;
background-color: #646464;
}
.conteneurVideosGrid {
height: 75vh;
width: 100%;
}
//--------------------------------------------------------------------------------------------
.cellulePub {
padding: 0px 10px 0px 10px;
width: 100%;
text-align: center;
justify-content: center;
}
.conteneurPub {
height: 75vh;
text-align: center;
justify-content: center;
vertical-align: middle;
display: block;
width: 75%;
margin-left: auto;
margin-right: auto;
position: absolute;
top: 50%;
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
// -------------------------------------------------------------------------
// aura
::ng-deep .mat-checkbox-ripple .mat-ripple-element {
background-color: grey !important;
}
// contenu coche
::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background {
background-color: black !important;
}
// indeterminate
::ng-deep .mat-checkbox .mat-checkbox-frame {
border: solid 1px black !important;
background-color: white !important;
}

View file

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PageSearchComponent } from './page-search.component';
describe('PageSearchComponent', () => {
let component: PageSearchComponent;
let fixture: ComponentFixture<PageSearchComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ PageSearchComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(PageSearchComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,118 @@
import { Component, OnInit } from '@angular/core';
import {HttpParams} from "@angular/common/http";
import {ActivatedRoute} from "@angular/router";
import {MessageService} from "../../../utils/message/message.service";
import {ThemeService} from "../../../utils/theme/theme.service";
let TAB_PLATEFORM = [
{ name: "Youtube", isSelected: true },
{ name: "Dailymotion", isSelected: true }
];
@Component({
selector: 'app-page-search',
templateUrl: './page-search.component.html',
styleUrls: ['./page-search.component.scss']
})
export class PageSearchComponent implements OnInit
{
tabPlateform = TAB_PLATEFORM;
tabVideo: any[] = [];
search: string = "";
ad1: any;
ad2: any;
sources: string = "" ;
indexPage: number = 0;
constructor( private messageService: MessageService,
public themeService: ThemeService,
private activatedRoute: ActivatedRoute ) { }
ngOnInit(): void
{
// parametre de la route
this.activatedRoute
.queryParams
.subscribe(paramsFromOldPage => {
if(paramsFromOldPage.hasOwnProperty("search")) this.search = paramsFromOldPage.search;
if(paramsFromOldPage.hasOwnProperty("sources"))
{
this.sources = paramsFromOldPage.sources;
if(this.sources === "yt") {
this.tabPlateform[0].isSelected = true;
this.tabPlateform[1].isSelected = false;
}
else if(this.sources === "dm") {
this.tabPlateform[0].isSelected = false;
this.tabPlateform[1].isSelected = true;
}
else if(this.sources === "yt,dm") {
this.tabPlateform[0].isSelected = true;
this.tabPlateform[1].isSelected = true;
}
}
if(paramsFromOldPage.hasOwnProperty("indexPage")) this.indexPage = parseInt(paramsFromOldPage.indexPage, 10);
this.onSearch();
});
// Ask for ads
let params = new HttpParams();
params = params.append("quantity", 2);
this.messageService
.get("user/ad", params)
.subscribe(ret => this.adCallback(ret), err => this.adCallback(err));
}
adCallback(retour: any): void
{
if(retour.status !== "success") {
console.log(retour);
}
else {
this.ad1 = retour.data[0];
this.ad2 = retour.data[1];
}
}
onSearch()
{
let params = new HttpParams();
params = params.append('q', this.search);
if(this.tabPlateform[0].isSelected && this.tabPlateform[1].isSelected) this.sources = "yt,dm" ;
else if((!this.tabPlateform[0].isSelected) && this.tabPlateform[1].isSelected) this.sources = "dm" ;
else if(this.tabPlateform[0].isSelected && (!this.tabPlateform[1].isSelected)) this.sources = "yt" ;
else this.sources = "" ;
params = params.append('sources', this.sources);
this.messageService
.get("video/search", params)
.subscribe(ret => this.onSearchCallback(ret), err => this.onSearchCallback(err));
}
onSearchCallback(retour: any): void
{
if(retour.status !== "success") {
console.log(retour);
}
else {
this.tabVideo = retour.data;
}
}
onEnterOnSearchBar(event)
{
if(event.key === 'Enter') this.onSearch();
}
}

View file

@ -0,0 +1,76 @@
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Grille -->
<div style="height: 93%; background-color: white; padding-top: 7px;" *ngIf="tabVideoExists()">
<mat-grid-list cols="3" rowHeight="33%">
<mat-grid-tile colspan="1" rowspan="1" *ngFor="let k of [0,1,2,3,4,5,6,7,8]">
<div class="myCell" *ngIf="indexPage+k < tabVideo.length" [title]="tabVideo[indexPage+k].title">
<!-- Image video -->
<div class="imgsContainer">
<img class="imgPlay" src="/assets/play.png" (click)="onVideo(tabVideo[indexPage+k])">
<img class="imgVideo" [src]="tabVideo[indexPage+k].imageUrl" (click)="onVideo(tabVideo[indexPage+k])">
</div>
<!-- Info video -->
<mat-grid-list cols="12" class="mat-grid-list-info-video">
<!-- logo -->
<mat-grid-tile [colspan]="2" [rowspan]="2" class="mat-grid-tile-info-video" (click)="onVideo(tabVideo[indexPage+k])">
<img *ngIf="tabVideo[indexPage+k].source==='Youtube'" src="/assets/logo_plateforms/youtube.png" alt="ytb" width="20px" height="15px">
<img *ngIf="tabVideo[indexPage+k].source==='Dailymotion'" src="/assets/logo_plateforms/dailymotion.png" alt="dlm" width="20px" height="20px">
</mat-grid-tile>
<!-- title + views + publishedAt -->
<mat-grid-tile [colspan]="8" [rowspan]="2" class="mat-grid-tile-info-video" (click)="onVideo(tabVideo[indexPage+k])">
<div style="position: absolute; left: 1px; text-align: left">
{{tronquage(tabVideo[indexPage+k].title)}}
<br>
<span style="color: gray">
{{tabVideo[indexPage+k].views | number: '1.0-0'}} vues.
Il y a {{dateToElapsedTime(tabVideo[indexPage+k].publishedAt)}}.
</span>
</div>
</mat-grid-tile>
<!-- addButton -->
<mat-grid-tile [colspan]="2" [rowspan]="2" class="mat-grid-tile-info-video">
<button mat-icon-button (click)="onAddToPlaylist(tabVideo[indexPage+k])">
<mat-icon>add_circle</mat-icon>
</button>
</mat-grid-tile>
</mat-grid-list>
</div>
</mat-grid-tile>
</mat-grid-list>
</div>
<!-- Paginator -->
<div class="paginatorContainer" *ngIf="tabVideoExists()">
<!-- btn précédent -->
<button mat-button class="btnPaginator" [disabled]="indexPage<=0" (click)="indexPage=indexPage-9"> < Précédent </button> &nbsp;
<!-- numeros de page -->
<span *ngFor="let page of tabPage" (click)="indexPage=(page-1)*9">
<span *ngIf="page===((indexPage/9)+1)">
<span style="text-decoration: underline; cursor: pointer;font-weight: bold;">{{page}}</span>&nbsp;
</span>
<span *ngIf="page!==((indexPage/9)+1)">
<span style="text-decoration: underline; cursor: pointer;">{{page}}</span>&nbsp;
</span>
</span> &nbsp;
<!-- btn suivant -->
<button mat-button class="btnPaginator" [disabled]="indexPage+9>=tabVideo.length" (click)="indexPage=indexPage+9"> Suivant > </button>
</div>

View file

@ -0,0 +1,84 @@
mat-grid-list {
margin: 0px 0px 0px 0px;
padding: 0px 0px 0px 0px;
border: none;
}
mat-grid-tile {
margin: 0px 0px 0px 0px;
padding: 0px 0px 0px 0px;
}
.myCell {
margin: 7px 0px 0px 0px;
padding: 0px 0px 0px 0px;
background-color: white;
border: solid 1px black;
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
cursor: pointer;
}
.myCell:hover {
background-color: #d2d2d2;
}
// ---------------------------------------------------------------------------------------------
.imgsContainer {
//width: 20vw;
width: 18vw;
height: 15vh;
}
.imgPlay {
position: absolute;
margin-left: 8vw;
width: 2.5vw;
margin-top: 5vh;
height: 5vh;
padding: 0px 0px 0px 0px;
}
.imgVideo {
width: 18vw;
height: 15vh;
padding: 0px 0px 0px 0px;
}
// ---------------------------------------------------------------------------------------------
.mat-grid-list-info-video {
margin: 0px 0px 0px 0px;
font-size: small;
}
.mat-grid-tile-info-video {
border: none;
font-size: x-small;
//background: linear-gradient(top, rgba(38,38,38,0.8), #e6e6e6 25%, #fff 38%, #c5c5c5 87%, rgba(38,38,38,0.8));
//background: -webkit-linear-gradient(top, #c5c5c5, #e6e6e6 25%, #fff 38%, #c5c5c5 87%, #c5c5c5);
}
mat-icon {
text-align: right;
}
// ---------------------------------------------------------------------------------------------
.paginatorContainer {
margin: 0px 0px 0px 0px;
padding: 5px 0px 0px 0px;
text-align: center;
background-color: white;
}
.btnPaginator {
margin: 0px 0px 0px 0px;
padding: 0px 0px 0px 0px;
}

View file

@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { VideoGridComponent } from './video-grid.component';
describe('VideoGridComponent', () => {
let component: VideoGridComponent;
let fixture: ComponentFixture<VideoGridComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ VideoGridComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(VideoGridComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,128 @@
import {Component, Input, OnChanges, SimpleChanges} from '@angular/core';
import {AddVideoToPlaylistsService} from "../../utils/services/addVideoToPlaylists/add-video-to-playlists.service";
import {Router} from "@angular/router";
import {MessageService} from "../../../utils/message/message.service";
@Component({
selector: 'app-video-grid',
templateUrl: './video-grid.component.html',
styleUrls: ['./video-grid.component.scss']
})
export class VideoGridComponent implements OnChanges
{
@Input() tabVideo: any[] = [];
@Input() search: string = "";
@Input() sources: string = "";
@Input() indexPage: number = 0;
tabPage: number[] = [];
constructor( private addVideoToPlaylistsService: AddVideoToPlaylistsService,
private router: Router,
private messageService: MessageService ) {}
ngOnChanges(changes: SimpleChanges): void
{
if(this.tabVideoExists())
{
const nbVideo = this.tabVideo.length;
let nbPage = Math.floor(nbVideo/9);
if((nbVideo%9) !== 0) nbPage += 1;
this.tabPage = [];
for(let i=1 ; i<=nbPage ; i++) this.tabPage.push(i);
}
}
onAddToPlaylist(video): void
{
this.addVideoToPlaylistsService.run(video.videoId, video.source, video.interest);
}
tronquage(str: string)
{
if(str.length < 30) return str;
else return str.substring(0, 27) + "..." ;
}
onVideo(video): void
{
const data = { source: video.source, interest: video.interest };
this.messageService
.post("video/create/"+video.videoId, data)
.subscribe(ret => this.onVideoCallback(ret,video), err => this.onVideoCallback(err,video));
}
onVideoCallback(retour: any, video): void
{
if(retour.status !== "success") {
console.log(retour);
}
else {
const params = {
videoId: video.videoId,
source: video.source,
from: "search",
search: this.search,
sources: this.sources,
indexPage: this.indexPage
};
this.router.navigate(['/user/watching'], { queryParams: params });
}
}
dateToElapsedTime(date0): string
{
const ellapsedTimeInMilliSeconds = (new Date()).getTime() - (new Date(date0)).getTime();
// seconde
const ellapsedTimeInSeconds = Math.trunc(ellapsedTimeInMilliSeconds / 1000);
if(ellapsedTimeInSeconds < 60) {
if(ellapsedTimeInSeconds <= 1)return ellapsedTimeInSeconds + " seconde" ;
else return ellapsedTimeInSeconds + " secondes" ;
}
// minute
const ellapsedTimeInMinutes = Math.trunc(ellapsedTimeInSeconds / 60);
if(ellapsedTimeInMinutes < 60) {
if(ellapsedTimeInMinutes <= 1) return ellapsedTimeInMinutes + " minute" ;
else return ellapsedTimeInMinutes + " minutes" ;
}
// heure
const ellapsedTimeInHours = Math.trunc(ellapsedTimeInMinutes / 60);
if(ellapsedTimeInHours < 24) {
if(ellapsedTimeInHours <= 1) return ellapsedTimeInHours + " heure" ;
else return ellapsedTimeInHours + " heures" ;
}
// jour
const ellapsedTimeInDays = Math.trunc(ellapsedTimeInHours / 24);
if(ellapsedTimeInDays < 31) {
if(ellapsedTimeInDays <= 1) return ellapsedTimeInDays + " jour" ;
else return ellapsedTimeInDays + " jours" ;
}
// mois
const ellapsedTimeInMonths = Math.trunc(ellapsedTimeInDays / 31);
if(ellapsedTimeInMonths < 12) {
return ellapsedTimeInMonths + " mois" ;
}
// an
const ellapsedTimeInYears = Math.trunc(ellapsedTimeInMonths / 12);
if(ellapsedTimeInYears <= 1) return ellapsedTimeInYears + " an" ;
else return ellapsedTimeInYears + " ans" ;
}
tabVideoExists(): boolean
{
if((this.tabVideo === null) || (this.tabVideo === undefined)) return false;
else if(this.tabVideo.length === 0) return false;
else return true;
}
}