commencement de la page watching
This commit is contained in:
parent
fd7322a7bc
commit
ccb33d8aeb
27 changed files with 691 additions and 59 deletions
|
|
@ -15,7 +15,7 @@
|
|||
<!-- email -->
|
||||
<div class="row myRow">
|
||||
<div class="col-6 myLabel">Mail:</div>
|
||||
<div class="col-6 myValue"> {{user.mail}} </div>
|
||||
<div class="col-6 myValue"> {{user.email}} </div>
|
||||
</div>
|
||||
|
||||
<div *ngIf="user.role.name === 'user'">
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import {PageProfilAdvertiserComponent} from "./advertiser/myProfil/page-profil-a
|
|||
import {PageProfilAdminComponent} from "./admin/myProfil/page-profil-admin/page-profil-admin.component";
|
||||
import {PageAdListAdminComponent} from "./admin/adList/page-ad-list-admin/page-ad-list-admin.component";
|
||||
import {PageUserListComponent} from "./admin/userList/page-user-list/page-user-list.component";
|
||||
import {PageWatchingVideoComponent} from "./user/watching/page-watching-video/page-watching-video.component";
|
||||
|
||||
|
||||
const routes: Routes = [
|
||||
|
|
@ -27,6 +28,10 @@ const routes: Routes = [
|
|||
{ path: 'user/history', component: PageHistoryUserComponent },
|
||||
{ path: 'user/myProfil', component: PageProfilUserComponent },
|
||||
|
||||
{ path: 'user/watching/fromSearch/:videoId/:source/:search', component: PageWatchingVideoComponent },
|
||||
{ path: 'user/watching/fromMyPlaylists/:videoId/:_idPlaylist', component: PageWatchingVideoComponent },
|
||||
{ path: 'user/watching/fromHistory/:videoId/:source', component: PageWatchingVideoComponent },
|
||||
|
||||
// Advertiser
|
||||
{ path: 'advertiser', component: PageAdListAdvertiserComponent },
|
||||
{ path: 'advertiser/adList', component: PageAdListAdvertiserComponent },
|
||||
|
|
|
|||
|
|
@ -68,6 +68,9 @@ import { PopupVisualizeUserComponent } from './admin/userList/popup-visualize-us
|
|||
import { PopupDeleteUserComponent } from './admin/userList/popup-delete-user/popup-delete-user.component';
|
||||
import { PopupCreateUserComponent } from './admin/userList/popup-create-user/popup-create-user.component';
|
||||
import { InputInterestsAdminComponent } from './admin/userList/input-interests-admin/input-interests-admin.component';
|
||||
import { PageWatchingVideoComponent } from './user/watching/page-watching-video/page-watching-video.component';
|
||||
import { RectangleWatchingVideoComponent } from './user/watching/rectangle-watching-video/rectangle-watching-video.component';
|
||||
import {MatExpansionModule} from "@angular/material/expansion";
|
||||
|
||||
|
||||
@NgModule({
|
||||
|
|
@ -116,6 +119,8 @@ import { InputInterestsAdminComponent } from './admin/userList/input-interests-a
|
|||
PopupDeleteUserComponent,
|
||||
PopupCreateUserComponent,
|
||||
InputInterestsAdminComponent,
|
||||
PageWatchingVideoComponent,
|
||||
RectangleWatchingVideoComponent,
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
|
@ -143,7 +148,8 @@ import { InputInterestsAdminComponent } from './admin/userList/input-interests-a
|
|||
IvyCarouselModule,
|
||||
MatRadioModule,
|
||||
MatStepperModule,
|
||||
MatPaginatorModule
|
||||
MatPaginatorModule,
|
||||
MatExpansionModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
|
|
|
|||
|
|
@ -18,13 +18,10 @@
|
|||
<ng-container matColumnDef="aperçu">
|
||||
<th mat-header-cell *matHeaderCellDef> Aperçu </th>
|
||||
<td mat-cell *matCellDef="let video">
|
||||
<img [src]="video.imageUrl" width="200px" height="100px">
|
||||
<!--
|
||||
<iframe appIframeTracker
|
||||
[src]=videoUrlService.safeUrl(video.videoId)
|
||||
(iframeClick)="onIframeClick(video)"
|
||||
allowfullscreen></iframe>
|
||||
-->
|
||||
<div class="imgsContainer" (click)="onVideo(video)">
|
||||
<img class="imgPlay" src="/assets/play.png">
|
||||
<img class="imgVideo" [src]="video.imageUrl">
|
||||
</div>
|
||||
</td>
|
||||
</ng-container>
|
||||
|
||||
|
|
|
|||
|
|
@ -19,3 +19,27 @@ input {
|
|||
width: 35%;
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
|
||||
.imgsContainer {
|
||||
position: relative;
|
||||
width: 20vw;
|
||||
height: 15vh;
|
||||
}
|
||||
|
||||
.imgPlay {
|
||||
position: absolute;
|
||||
margin-left: 9vw;
|
||||
width: 3vw;
|
||||
margin-top: 5vh;
|
||||
height: 6vh;
|
||||
padding: 0px 0px 0px 0px;
|
||||
}
|
||||
|
||||
.imgVideo {
|
||||
border: solid 1px black;
|
||||
width: 20vw;
|
||||
height: 15vh;
|
||||
padding: 0px 0px 0px 0px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import {UserHistoryService} from "../../utils/services/userHistory/userHistory.s
|
|||
import {MatPaginator} from "@angular/material/paginator";
|
||||
import {FictitiousVideosService} from "../../../utils/services/fictitiousDatas/fictitiousVideos/fictitious-videos.service";
|
||||
import {VideoAll} from "../../../utils/interfaces/video";
|
||||
import {Router} from "@angular/router";
|
||||
|
||||
|
||||
|
||||
|
|
@ -28,7 +29,8 @@ export class PageHistoryUserComponent implements AfterViewInit
|
|||
private messageService: MessageService,
|
||||
private fictitiousVideosService: FictitiousVideosService,
|
||||
public videoUrlService: VideoUrlService,
|
||||
private userHistoryService: UserHistoryService ) { }
|
||||
private userHistoryService: UserHistoryService,
|
||||
private router: Router ) { }
|
||||
|
||||
|
||||
// charge la page
|
||||
|
|
@ -102,12 +104,11 @@ export class PageHistoryUserComponent implements AfterViewInit
|
|||
*/
|
||||
}
|
||||
|
||||
|
||||
// Ajoute la date actuelle dans watchedDates.video
|
||||
onIframeClick(video: VideoAll): void
|
||||
|
||||
onVideo(video: VideoAll): void
|
||||
{
|
||||
console.log("onIframeClick: " + video.title);
|
||||
//this.userHistoryService.addVideoToHistoque(video);
|
||||
const url = '/user/watching/fromHistory/'+video.videoId+'/'+video.source ;
|
||||
this.router.navigateByUrl(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ export class PlaylistListComponent implements OnInit
|
|||
|
||||
ngOnInit(): void
|
||||
{
|
||||
this.allPlaylists = this.fictitiousVideosService.getTabPlaylistDB(10, 10);
|
||||
//this.allPlaylists = this.fictitiousVideosService.getRandomTabPlaylistDB(10, 10);
|
||||
this.allPlaylists = this.fictitiousVideosService.getNoRandomTabPlaylistDB(10);
|
||||
this.tabPlaylist = [].concat(this.allPlaylists);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@
|
|||
<mat-grid-tile [colspan]="10" [rowspan]="1">
|
||||
<div class="col-8">
|
||||
<div style="margin: auto; width: 20vw; height: 15vh;">
|
||||
<div class="imgsContainer">
|
||||
<div class="imgsContainer" (click)="onVideo(video)">
|
||||
<img class="imgPlay" src="/assets/play.png">
|
||||
<img class="imgVideo" [src]="video.imageUrl">
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import {MatSnackBar} from "@angular/material/snack-bar";
|
|||
import {UserHistoryService} from "../../utils/services/userHistory/userHistory.service";
|
||||
import {FictitiousUtilsService} from "../../../utils/services/fictitiousDatas/fictitiousUtils/fictitious-utils.service";
|
||||
import {FictitiousVideosService} from "../../../utils/services/fictitiousDatas/fictitiousVideos/fictitious-videos.service";
|
||||
import {Router} from "@angular/router";
|
||||
|
||||
|
||||
|
||||
|
|
@ -29,7 +30,8 @@ export class VideoListComponent implements OnChanges
|
|||
private addVideoToPlaylistService: AddVideoToPlaylistsService,
|
||||
private snackBar: MatSnackBar,
|
||||
public fictitiousVideosService: FictitiousVideosService,
|
||||
private historiqueService: UserHistoryService ) { }
|
||||
private historiqueService: UserHistoryService,
|
||||
private router: Router ) { }
|
||||
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void
|
||||
|
|
@ -83,4 +85,11 @@ export class VideoListComponent implements OnChanges
|
|||
// Mais en vrai, ça serai plus facile pour moi si on mettait plutot un attribut "videoIds" dans "Playlists"
|
||||
}
|
||||
|
||||
|
||||
onVideo(video: VideoDB): void
|
||||
{
|
||||
const url = "user/watching/fromMyPlaylists/" + video.videoId + '/' + this.playlist._id;
|
||||
this.router.navigateByUrl(url);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
<!-- Grilles des videos -->
|
||||
<mat-grid-tile colspan="7" rowspan="1" class="celluleGrilleVideo">
|
||||
<div class="conteneurVideosGrid">
|
||||
<app-video-grid [tabVideo]="tabVideo"></app-video-grid>
|
||||
<app-video-grid [tabVideo]="tabVideo" [search]="search"></app-video-grid>
|
||||
</div>
|
||||
</mat-grid-tile>
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------
|
||||
|
||||
.inputSearchBar {
|
||||
width: 50%;
|
||||
|
|
@ -25,6 +26,7 @@
|
|||
font-size: large;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------
|
||||
|
||||
.celluleGrilleVideo {
|
||||
border: solid 2px;
|
||||
|
|
@ -40,12 +42,13 @@
|
|||
background-color: #646464;
|
||||
}
|
||||
|
||||
|
||||
.conteneurVideosGrid {
|
||||
height: 75vh;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------
|
||||
|
||||
.cellulePub {
|
||||
padding: 0px 10px 0px 10px;
|
||||
width: 100%;
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
<!-- Image video -->
|
||||
<div class="imgsContainer">
|
||||
<img class="imgPlay" src="/assets/play.png">
|
||||
<img class="imgVideo" [src]="tabVideo[indexPage+k].imageUrl">
|
||||
<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>
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ import {Component, Input, OnChanges } from '@angular/core';
|
|||
import {VideoAll} from "../../../utils/interfaces/video";
|
||||
import {UserHistoryService} from "../../utils/services/userHistory/userHistory.service";
|
||||
import {AddVideoToPlaylistsService} from "../../utils/services/addVideoToPlaylists/add-video-to-playlists.service";
|
||||
import {VideoUrlService} from "../../utils/services/videoUrl/video-url.service";
|
||||
import {Router} from "@angular/router";
|
||||
|
||||
|
||||
|
||||
@Component({
|
||||
|
|
@ -13,11 +14,12 @@ import {VideoUrlService} from "../../utils/services/videoUrl/video-url.service";
|
|||
export class VideoGridComponent implements OnChanges
|
||||
{
|
||||
@Input() tabVideo: VideoAll[] = [];
|
||||
@Input() search: string = '';
|
||||
indexPage: number = 0;
|
||||
|
||||
constructor( private historiqueService: UserHistoryService,
|
||||
private addVideoToPlaylistsService: AddVideoToPlaylistsService,
|
||||
private videoUrlService: VideoUrlService ) {}
|
||||
private router: Router) {}
|
||||
|
||||
|
||||
ngOnChanges(): void
|
||||
|
|
@ -36,4 +38,9 @@ export class VideoGridComponent implements OnChanges
|
|||
else return str.substring(0, 37) + "..." ;
|
||||
}
|
||||
|
||||
onVideo(video: VideoAll): void
|
||||
{
|
||||
const url = '/user/watching/fromSearch/'+video.videoId+'/'+video.source+'/'+this.search;
|
||||
this.router.navigateByUrl(url);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,20 @@
|
|||
<div [class]="themeService.getClassTheme()">
|
||||
<div class="myContainer">
|
||||
<span class="helper"></span>
|
||||
<img [src]="'assets/pub/'+ad.images[idxImage].url" [alt]="ad.images[idxImage].url">
|
||||
</div>
|
||||
<div *ngIf="from==='search' || from==='myPlaylists'" class="myContainer">
|
||||
<span class="helper"></span>
|
||||
<img [src]="'assets/pub/'+ad.images[idxImage].url"
|
||||
[alt]="ad.images[idxImage].url"
|
||||
id="imgFromSearchOrMyPlaylists">
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------- -->
|
||||
|
||||
<img *ngIf="from === 'watchingLeft'"
|
||||
[src]="'assets/pub/'+ad.images[idxImage].url"
|
||||
[alt]="ad.images[idxImage].url"
|
||||
id="imgFromWatchingLeft">
|
||||
|
||||
<!-- --------------------------------------------------------------------- -->
|
||||
|
||||
<img *ngIf="from === 'watchingRight'"
|
||||
[src]="'assets/pub/'+ad.images[idxImage].url"
|
||||
[alt]="ad.images[idxImage].url"
|
||||
id="imgFromWatchingRight">
|
||||
|
|
|
|||
|
|
@ -6,23 +6,33 @@
|
|||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
|
||||
img {
|
||||
#imgFromSearchOrMyPlaylists {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
border: solid 3px;
|
||||
border: solid 3px black;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.lightTheme img {
|
||||
border-color: black;
|
||||
}
|
||||
.darkTheme img {
|
||||
border-color: white;
|
||||
}
|
||||
|
||||
|
||||
.helper {
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
#imgFromWatchingLeft {
|
||||
width: 14vw;
|
||||
height: 70vh;
|
||||
border: solid 3px black;
|
||||
position: fixed;
|
||||
left: 1vw;
|
||||
}
|
||||
|
||||
#imgFromWatchingRight {
|
||||
width: 15vw;
|
||||
height: 70vh;
|
||||
border: solid 3px black;
|
||||
position: fixed;
|
||||
right: 1vw;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import {ThemeService} from "../../../../utils/services/theme/theme.service";
|
|||
export class AdvertComponent implements OnInit
|
||||
{
|
||||
@Input() ad: Advert;
|
||||
@Input() from: string = "search";
|
||||
idxImage: number = 0;
|
||||
|
||||
|
||||
|
|
@ -22,6 +23,8 @@ export class AdvertComponent implements OnInit
|
|||
{
|
||||
const nbImages = this.ad.images.length;
|
||||
this.idxImage = Math.floor(Math.random() * nbImages);
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
|
|||
import {MessageService} from "../../../../utils/services/message/message.service";
|
||||
import {MatDialog} from "@angular/material/dialog";
|
||||
import {PopupAddVideoToPlaylistsComponent} from "../../components/popup-add-video-to-playlists/popup-add-video-to-playlists.component";
|
||||
import {VideoDB} from "../../../../utils/interfaces/video";
|
||||
import {VideoAll, VideoDB} from "../../../../utils/interfaces/video";
|
||||
import {MatSnackBar} from "@angular/material/snack-bar";
|
||||
import {FictitiousVideosService} from "../../../../utils/services/fictitiousDatas/fictitiousVideos/fictitious-videos.service";
|
||||
|
||||
|
|
@ -13,7 +13,7 @@ import {FictitiousVideosService} from "../../../../utils/services/fictitiousData
|
|||
})
|
||||
export class AddVideoToPlaylistsService
|
||||
{
|
||||
private _video: VideoDB;
|
||||
private _video: VideoDB | VideoAll;
|
||||
|
||||
|
||||
constructor( private messageService: MessageService,
|
||||
|
|
@ -23,12 +23,12 @@ export class AddVideoToPlaylistsService
|
|||
|
||||
|
||||
// --- FAUX CODE ---
|
||||
run(video0: VideoDB): void
|
||||
run(video0: VideoDB | VideoAll): void
|
||||
{
|
||||
this._video = video0;
|
||||
const retour = {
|
||||
status: "success",
|
||||
data: this.fictitiousVideosService.getTabPlaylistDB(4, 5),
|
||||
data: this.fictitiousVideosService.getRandomTabPlaylistDB(4, 5),
|
||||
}
|
||||
this.afterReceivingPlaylists(retour)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,15 @@ export class VideoUrlService
|
|||
constructor(private _sanitizer: DomSanitizer) { }
|
||||
|
||||
|
||||
safeUrl(videoId: string, source: string): SafeResourceUrl
|
||||
{
|
||||
let videoUrl = "" ;
|
||||
if(source === 'youtube') videoUrl = "https://www.youtube.com/embed/" + videoId;
|
||||
else if(source === 'dailymotion') videoUrl = "https://www.dailymotion.com/embed/video/" + videoId;
|
||||
return this._sanitizer.bypassSecurityTrustResourceUrl(videoUrl);
|
||||
}
|
||||
|
||||
/*
|
||||
safeUrl(videoUrl: string): SafeResourceUrl
|
||||
{
|
||||
if(videoUrl.includes("youtu")) videoUrl = this.youtubeSafeUrl(videoUrl);
|
||||
|
|
@ -42,4 +51,6 @@ export class VideoUrlService
|
|||
const n = "https://www.dailymotion.com/".length;
|
||||
return videoUrl.slice(0, n) + "embed/" + videoUrl.slice(n);
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,219 @@
|
|||
<!-- ----------------------------------------------------------------------------------------------------------------- -->
|
||||
<!-- NIVEAU 1 -->
|
||||
|
||||
<div [class]="themeService.getClassTheme()">
|
||||
<div class="myContainer">
|
||||
|
||||
<!-- Navbar -->
|
||||
<div style="margin-bottom: 30px">
|
||||
<app-navbar-user></app-navbar-user>
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------- -->
|
||||
|
||||
<!-- [Search bar] + [Site de streaming] -->
|
||||
<div class="row">
|
||||
<div class="col-2"></div>
|
||||
<div class="col-8" style="margin-bottom: 10px">
|
||||
|
||||
<!-- Search bar -->
|
||||
<div class="row" style="margin-bottom: 10px">
|
||||
<div>
|
||||
<input type="search" placeholder="recherche..." class="inputSearchBar" [(ngModel)]="search">
|
||||
<button class="btnRechercher" (click)="onSearch()"> Rechercher </button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Site de streaming -->
|
||||
<div class="row" style="margin-bottom: 10px">
|
||||
<div>
|
||||
<span *ngFor="let plateforme of tabPlateform">
|
||||
|
||||
<input type="checkbox" [id]="plateforme.name" [name]="plateforme.name" style="margin-left: 5px" [(ngModel)]="plateforme.isSelected">
|
||||
<img [src]="'/assets/logo_plateforms/'+plateforme.name+'.png'" alt="image" width="25px" height="25px" style="margin-left: 5px">
|
||||
<label [for]="plateforme.name" style="margin-left: 5px"> {{plateforme.name}}</label>
|
||||
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="col-2"></div>
|
||||
</div>
|
||||
|
||||
<!-- --------------------------------------------------------------------- -->
|
||||
|
||||
<!-- [pub gauche] + [video] + [pub droite] -->
|
||||
<div *ngIf="from==='search' || from==='history'; then videoFromSearchOrHistory"></div>
|
||||
|
||||
<!-- [pub gauche] + [video] + [playlist] -->
|
||||
<div *ngIf="from==='myPlaylists'; then videoFromMyPlaylists"></div>
|
||||
|
||||
<!-- --------------------------------------------------------------------- -->
|
||||
|
||||
<br><br>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- ----------------------------------------------------------------------------------------------------------------- -->
|
||||
<!-- NIVEAU 2: videoFromSearchOrHistory -->
|
||||
|
||||
<ng-template #videoFromSearchOrHistory>
|
||||
<div class="row">
|
||||
|
||||
<!-- pub gauche -->
|
||||
<div class="col-2">
|
||||
<app-advert [ad]="ad1" from="watchingLeft"></app-advert>
|
||||
</div>
|
||||
|
||||
<!-- video -->
|
||||
<div class="col-8" style="background-color: white; border: solid 1px black;">
|
||||
<div *ngIf="true then rectangleCentral"></div>
|
||||
</div>
|
||||
|
||||
<!-- pub droite -->
|
||||
<div class="col-2">
|
||||
<app-advert [ad]="ad2" from="watchingRight"></app-advert>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
|
||||
|
||||
<!-- ----------------------------------------------------------------------------------------------------------------- -->
|
||||
<!-- NIVEAU 2: videoFromMyPlaylists -->
|
||||
|
||||
<ng-template #videoFromMyPlaylists>
|
||||
<div class="row">
|
||||
|
||||
<!-- pub gauche -->
|
||||
<div class="col-2">
|
||||
<app-advert [ad]="ad1" from="watchingLeft"></app-advert>
|
||||
</div>
|
||||
|
||||
<!-- rectangle central -->
|
||||
<div class="col-6" style="background-color: white; border: solid 1px black;">
|
||||
<div *ngIf="true then rectangleCentral"></div>
|
||||
</div>
|
||||
|
||||
<!-- playlist -->
|
||||
<div class="col-4">
|
||||
<div *ngIf="true; then playlistHTML"></div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
|
||||
|
||||
<!-- ----------------------------------------------------------------------------------------------------------------- -->
|
||||
<!-- NIVEAU 3: rectangleCentral -->
|
||||
|
||||
<ng-template #rectangleCentral>
|
||||
|
||||
<!-- btnRetour + btnAdd -->
|
||||
<div class="row" style="margin: 10px 0px 40px 0px">
|
||||
|
||||
<!-- btnRetour -->
|
||||
<div class="col-6" style="text-align: left;">
|
||||
<button mat-button style="border: solid 1px black" (click)="onRetour()">
|
||||
<mat-icon>arrow_back_ios</mat-icon> Retour
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- btnAdd -->
|
||||
<div class="col-6" style="text-align: right;">
|
||||
<button mat-button style="border: solid 1px black" (click)="onAdd()">
|
||||
Ajouter à une playlist <mat-icon>add_circle</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
<!-- logo + title + video + views + publishedAt + description -->
|
||||
<div [style]=containerStyle>
|
||||
|
||||
<!-- logo + title -->
|
||||
<div style="text-align: left">
|
||||
<img *ngIf="video.source==='youtube'" src="/assets/logo_plateforms/youtube.png" alt="ytb" width="50px" height="30px" style="float: left">
|
||||
<img *ngIf="video.source==='dailymotion'" src="/assets/logo_plateforms/dailymotion.png" alt="dlm" width="30px" height="30px" style="float: left">
|
||||
<h5> {{video.title}}</h5>
|
||||
</div>
|
||||
|
||||
<!-- video -->
|
||||
<div style="width: 100%">
|
||||
<iframe [src]="videoUrlService.safeUrl(video.videoId,video.source)"
|
||||
[style]="iframeStyle"
|
||||
allowfullscreen></iframe>
|
||||
</div>
|
||||
|
||||
<!-- views -->
|
||||
<div style="text-align: left; margin: 5px 0px 0px 1px">
|
||||
<span style="font-weight: bold"> Vues: </span>
|
||||
{{video.views | number: '1.0-0'}}
|
||||
</div>
|
||||
|
||||
<!-- publishedAt -->
|
||||
<div style="text-align: left; margin: 5px 0px 0px 1px">
|
||||
<span style="font-weight: bold"> Date de publication: </span>
|
||||
{{ video.publishedAt | date:'dd/LL/YYYY à HH:mm:ss' }}
|
||||
</div>
|
||||
|
||||
<!-- description -->
|
||||
<div style="text-align: left; margin: 5px 0px 20px 1px">
|
||||
<div style="font-weight: bold; display: flex; align-items: center; cursor: pointer" (click)="hiddenDescription = !hiddenDescription">
|
||||
Description
|
||||
<mat-icon *ngIf="hiddenDescription">expand_more</mat-icon>
|
||||
<mat-icon *ngIf="!hiddenDescription">expand_less</mat-icon>
|
||||
</div>
|
||||
<div style="margin-left: 25px; padding-left: 5px; border-left: solid 1px #e6e6e6" [hidden]="hiddenDescription">
|
||||
{{video.description}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</ng-template>
|
||||
|
||||
|
||||
|
||||
<!-- ----------------------------------------------------------------------------------------------------------------- -->
|
||||
<!-- NIVEAU 3: playlist -->
|
||||
|
||||
<ng-template #playlistHTML>
|
||||
<div class="playlistContainer">
|
||||
|
||||
<!-- Bordure haute -->
|
||||
<div class="topBorder">
|
||||
<span style="font-weight: bold"> {{playlist.name}} </span>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Liste des videos -->
|
||||
<div class="listVideoContainer">
|
||||
<div *ngFor="let video0 of videosInPlaylist; let i = index;">
|
||||
<div class="videoCell">
|
||||
<div class="imgsContainer" (click)="this.video = video0">
|
||||
<img class="imgPlay" src="/assets/play.png">
|
||||
<img class="imgVideo" [src]="video0.imageUrl">
|
||||
</div>
|
||||
<div class="titleContainer">
|
||||
{{video0.title}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Bordure basse -->
|
||||
<div class="bottomBorder">
|
||||
<div style="visibility: hidden">a</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</ng-template>
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
.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: 50%;
|
||||
font-size: large;
|
||||
}
|
||||
.btnRechercher {
|
||||
border: solid black 1px;
|
||||
border-radius: 5px;
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------
|
||||
// --- Playlist ---
|
||||
|
||||
.playlistContainer {
|
||||
border: solid 1px black;
|
||||
width: 98%;
|
||||
}
|
||||
|
||||
.topBorder {
|
||||
margin: 0px 0px 0px 0px;
|
||||
background-color: #dcdcdc;
|
||||
text-align: left;
|
||||
padding: 5px 0px 5px 5px;
|
||||
border-bottom: solid 1px black;
|
||||
}
|
||||
|
||||
.listVideoContainer {
|
||||
height: 70vh;
|
||||
background-color: white;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
.videoCell {
|
||||
margin: 0px 0px 0px 0px;
|
||||
padding: 10px 0px 10px 10px;
|
||||
border-bottom: solid 1px black;
|
||||
}
|
||||
|
||||
// ----
|
||||
|
||||
.imgsContainer {
|
||||
position: relative;
|
||||
width: 13vw;
|
||||
height: 10vh;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.imgVideo {
|
||||
border: solid 1px black;
|
||||
width: 13vw;
|
||||
height: 10vh;
|
||||
padding: 0px 0px 0px 0px;
|
||||
}
|
||||
|
||||
.imgPlay {
|
||||
position: absolute;
|
||||
margin-left: 6vw;
|
||||
width: 2vw;
|
||||
margin-top: 3vh;
|
||||
height: 4vh;
|
||||
padding: 0px 0px 0px 0px;
|
||||
}
|
||||
|
||||
.titleContainer {
|
||||
display: table-cell;
|
||||
margin-left: 13vw;
|
||||
height: 10vh;
|
||||
padding-left: 2px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
// ----
|
||||
|
||||
.bottomBorder {
|
||||
margin: 0px 0px 0px 0px;
|
||||
background-color: #dcdcdc;
|
||||
border-top: solid 1px black;
|
||||
border-bottom: solid 1px black;
|
||||
font-size: large;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { PageWatchingVideoComponent } from './page-watching-video.component';
|
||||
|
||||
describe('PageWatchingVideoComponent', () => {
|
||||
let component: PageWatchingVideoComponent;
|
||||
let fixture: ComponentFixture<PageWatchingVideoComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ PageWatchingVideoComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(PageWatchingVideoComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
import {VideoAll} from "../../../utils/interfaces/video";
|
||||
import {Advert} from "../../../utils/interfaces/advert";
|
||||
import {MessageService} from "../../../utils/services/message/message.service";
|
||||
import {FictitiousVideosService} from "../../../utils/services/fictitiousDatas/fictitiousVideos/fictitious-videos.service";
|
||||
import {FictitiousAdvertsService} from "../../../utils/services/fictitiousDatas/fictitiousAdverts/fictitious-adverts.service";
|
||||
import {ThemeService} from "../../../utils/services/theme/theme.service";
|
||||
import {ActivatedRoute, Router} from "@angular/router";
|
||||
import {VideoUrlService} from "../../utils/services/videoUrl/video-url.service";
|
||||
import {AddVideoToPlaylistsService} from "../../utils/services/addVideoToPlaylists/add-video-to-playlists.service";
|
||||
import {PlaylistDB} from "../../../utils/interfaces/playlist";
|
||||
|
||||
|
||||
|
||||
let TAB_PLATEFORM = [
|
||||
{ name: "youtube", isSelected: false },
|
||||
{ name: "dailymotion", isSelected: false }
|
||||
];
|
||||
|
||||
|
||||
|
||||
@Component({
|
||||
selector: 'app-page-watching-video',
|
||||
templateUrl: './page-watching-video.component.html',
|
||||
styleUrls: ['./page-watching-video.component.scss']
|
||||
})
|
||||
export class PageWatchingVideoComponent implements OnInit
|
||||
{
|
||||
tabPlateform = TAB_PLATEFORM;
|
||||
video: VideoAll;
|
||||
search: string = "";
|
||||
ad1: Advert;
|
||||
ad2: Advert;
|
||||
from: string = "";
|
||||
|
||||
playlist: PlaylistDB;
|
||||
videosInPlaylist: VideoAll[] = [];
|
||||
|
||||
hiddenDescription: boolean = true;
|
||||
iframeStyle: string = "";
|
||||
containerStyle: string = "";
|
||||
|
||||
|
||||
constructor( private messageService: MessageService,
|
||||
private fictitiousVideosService: FictitiousVideosService,
|
||||
private fictitiousAdvertsService: FictitiousAdvertsService,
|
||||
public themeService: ThemeService,
|
||||
private activatedRoute: ActivatedRoute,
|
||||
private router: Router,
|
||||
public videoUrlService: VideoUrlService,
|
||||
private addVideoToPlaylistsService: AddVideoToPlaylistsService ) { }
|
||||
|
||||
|
||||
ngOnInit(): void
|
||||
{
|
||||
// --- FAUX CODE ---
|
||||
const videoId = this.activatedRoute.snapshot.paramMap.get('videoId');
|
||||
this.video = this.fictitiousVideosService.getVideoByVideoId(videoId);
|
||||
this.ad1 = this.fictitiousAdvertsService.getAdvert();
|
||||
this.ad2 = this.fictitiousAdvertsService.getAdvert();
|
||||
|
||||
if(this.router.url.includes("fromSearch")) this.from = "search" ;
|
||||
else if(this.router.url.includes("fromHistory")) this.from = "history";
|
||||
else if(this.router.url.includes("fromMyPlaylists"))
|
||||
{
|
||||
this.from = "myPlaylists";
|
||||
const _idPlaylist = this.activatedRoute.snapshot.paramMap.get('_idPlaylist');
|
||||
this.playlist = this.fictitiousVideosService.getPlaylistBy_id(_idPlaylist);
|
||||
const allVideo = this.fictitiousVideosService.getAllVideoAll();
|
||||
this.videosInPlaylist = [];
|
||||
for(let _idVideo of this.playlist.videoIds)
|
||||
{
|
||||
const video = allVideo.find(video => video._id === _idVideo);
|
||||
this.videosInPlaylist.push(video);
|
||||
}
|
||||
}
|
||||
|
||||
if(this.from === 'search' || this.from === 'history')
|
||||
{
|
||||
this.containerStyle = "margin: 0 auto; width: 64vw;"
|
||||
this.iframeStyle = "width: 64vw; height: 60vh;" ;
|
||||
}
|
||||
else {
|
||||
this.containerStyle = "margin: 0 auto; width: 48vw;"
|
||||
this.iframeStyle = "width: 48vw; height: 45vh;" ;
|
||||
}
|
||||
|
||||
// --- VRAI CODE ---
|
||||
// ...
|
||||
}
|
||||
|
||||
|
||||
onSearch()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
onAdd(): void
|
||||
{
|
||||
this.addVideoToPlaylistsService.run(this.video);
|
||||
}
|
||||
|
||||
|
||||
onRetour(): void
|
||||
{
|
||||
if(this.from === 'search') this.router.navigateByUrl("/user/search");
|
||||
else if(this.from === 'myPlaylists') this.router.navigateByUrl("/user/myPlaylists");
|
||||
else if(this.from === 'history') this.router.navigateByUrl("/user/history");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
<p>rectangle-watching-video works!</p>
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { RectangleWatchingVideoComponent } from './rectangle-watching-video.component';
|
||||
|
||||
describe('RectangleWatchingVideoComponent', () => {
|
||||
let component: RectangleWatchingVideoComponent;
|
||||
let fixture: ComponentFixture<RectangleWatchingVideoComponent>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
declarations: [ RectangleWatchingVideoComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(RectangleWatchingVideoComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-rectangle-watching-video',
|
||||
templateUrl: './rectangle-watching-video.component.html',
|
||||
styleUrls: ['./rectangle-watching-video.component.scss']
|
||||
})
|
||||
export class RectangleWatchingVideoComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit(): void {
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -8,7 +8,8 @@ import {FictitiousUtilsService} from "../fictitiousUtils/fictitious-utils.servic
|
|||
const TAB_VIDEO: VideoAll[] = [
|
||||
{
|
||||
_id: "Mowgli",
|
||||
videoId: "https://www.youtube.com/watch?v=medPORJ8KO0",
|
||||
//videoId: "https://www.youtube.com/watch?v=medPORJ8KO0",
|
||||
videoId: "medPORJ8KO0",
|
||||
userId: "userId",
|
||||
source: "youtube",
|
||||
tags: [ "rap", "musique" ],
|
||||
|
|
@ -24,7 +25,8 @@ const TAB_VIDEO: VideoAll[] = [
|
|||
},
|
||||
{
|
||||
_id: "Mexico",
|
||||
videoId: "https://www.youtube.com/watch?v=LZx6oeNeoWM",
|
||||
//videoId: "https://www.youtube.com/watch?v=LZx6oeNeoWM",
|
||||
videoId: "LZx6oeNeoWM",
|
||||
userId: "userId",
|
||||
source: "youtube",
|
||||
tags: [ "rap", "musique" ],
|
||||
|
|
@ -40,7 +42,8 @@ const TAB_VIDEO: VideoAll[] = [
|
|||
},
|
||||
{
|
||||
_id: "Luz de luna",
|
||||
videoId: "https://www.youtube.com/watch?v=fGoPhSV2Jic",
|
||||
//videoId: "https://www.youtube.com/watch?v=fGoPhSV2Jic",
|
||||
videoId: "fGoPhSV2Jic",
|
||||
userId: "userId",
|
||||
source: "youtube",
|
||||
tags: [ "rap", "musique" ],
|
||||
|
|
@ -56,7 +59,8 @@ const TAB_VIDEO: VideoAll[] = [
|
|||
},
|
||||
{
|
||||
_id: "Blanka",
|
||||
videoId: "https://www.youtube.com/watch?v=u8bHjdljyLw",
|
||||
//videoId: "https://www.youtube.com/watch?v=u8bHjdljyLw",
|
||||
videoId: "u8bHjdljyLw",
|
||||
userId: "userId",
|
||||
source: "youtube",
|
||||
tags: [ "rap", "musique" ],
|
||||
|
|
@ -72,7 +76,8 @@ const TAB_VIDEO: VideoAll[] = [
|
|||
},
|
||||
{
|
||||
_id: "Mowgli 2",
|
||||
videoId: "https://www.dailymotion.com/video/x7ahxdn",
|
||||
//videoId: "https://www.dailymotion.com/video/x7ahxdn",
|
||||
videoId: "x7ahxdn",
|
||||
userId: "userId",
|
||||
source: "dailymotion",
|
||||
tags: [ "rap", "musique" ],
|
||||
|
|
@ -88,7 +93,8 @@ const TAB_VIDEO: VideoAll[] = [
|
|||
},
|
||||
{
|
||||
_id: "Etre humain",
|
||||
videoId: "https://www.youtube.com/watch?v=gfVo39B92Ow",
|
||||
//videoId: "https://www.youtube.com/watch?v=gfVo39B92Ow",
|
||||
videoId: "gfVo39B92Ow",
|
||||
userId: "userId",
|
||||
source: "youtube",
|
||||
tags: [ "rap", "musique" ],
|
||||
|
|
@ -104,7 +110,8 @@ const TAB_VIDEO: VideoAll[] = [
|
|||
},
|
||||
{
|
||||
_id: "Humanoide",
|
||||
videoId: "https://www.youtube.com/watch?v=MiyIg__WNOw",
|
||||
//videoId: "https://www.youtube.com/watch?v=MiyIg__WNOw",
|
||||
videoId: "MiyIg__WNOw",
|
||||
userId: "userId",
|
||||
source: "youtube",
|
||||
tags: [ "rap", "musique" ],
|
||||
|
|
@ -120,7 +127,8 @@ const TAB_VIDEO: VideoAll[] = [
|
|||
},
|
||||
{
|
||||
_id: "Dernier soupir",
|
||||
videoId: "https://youtu.be/0GqjIF-4QQM?list=PLqeKQSn3LuAmpF-uIu39RIQRQkUzVol5l",
|
||||
//videoId: "https://youtu.be/0GqjIF-4QQM?list=PLqeKQSn3LuAmpF-uIu39RIQRQkUzVol5l",
|
||||
videoId: "0GqjIF-4QQM",
|
||||
userId: "userId",
|
||||
source: "youtube",
|
||||
tags: [ "rap", "musique" ],
|
||||
|
|
@ -136,9 +144,10 @@ const TAB_VIDEO: VideoAll[] = [
|
|||
},
|
||||
{
|
||||
_id: "Les prélis",
|
||||
videoId: "https://www.dailymotion.com/video/x4trtkd",
|
||||
//videoId: "https://www.dailymotion.com/video/x4trtkd",
|
||||
videoId: "x4trtkd",
|
||||
userId: "userId",
|
||||
source: "youtube",
|
||||
source: "dailymotion",
|
||||
tags: [ "rap", "musique" ],
|
||||
watchedDates: [new Date()],
|
||||
createdAt: new Date(),
|
||||
|
|
@ -147,12 +156,13 @@ const TAB_VIDEO: VideoAll[] = [
|
|||
title: "Columbine - Les prélis",
|
||||
views: 999999,
|
||||
publishedAt: new Date(),
|
||||
imageUrl: "https://i.ytimg.com/an_webp/LfFI3bzMLU0/mqdefault_6s.webp?du=3000&sqp=CKq33owG&rs=AOn4CLDZmaPGWwcuo9yUWJ-xOzA69r2Qrw",
|
||||
imageUrl: "https://s2.dmcdn.net/v/HPPjj1NtysAaAttYk/x240",
|
||||
description: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. ",
|
||||
},
|
||||
{
|
||||
_id: "Pierre feuille ciseau",
|
||||
videoId: "https://www.dailymotion.com/video/x6agl6i",
|
||||
//videoId: "https://www.dailymotion.com/video/x6agl6i",
|
||||
videoId: "x6agl6i",
|
||||
userId: "userId",
|
||||
source: "dailymotion",
|
||||
tags: [ "rap", "musique" ],
|
||||
|
|
@ -183,7 +193,12 @@ export class FictitiousVideosService
|
|||
{
|
||||
const index = Math.floor(Math.random() * TAB_VIDEO.length);
|
||||
return TAB_VIDEO[index];
|
||||
//return Object.assign({}, TAB_VIDEO[index]);
|
||||
}
|
||||
|
||||
|
||||
getVideoByVideoId(videoId: string): VideoAll
|
||||
{
|
||||
return TAB_VIDEO.find(video => video.videoId === videoId);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -195,7 +210,14 @@ export class FictitiousVideosService
|
|||
}
|
||||
|
||||
|
||||
getTabPlaylistDB(nbPlaylist: number, nbVideoMax: number): PlaylistDB[]
|
||||
getAllVideoAll(): VideoAll[]
|
||||
{
|
||||
return TAB_VIDEO;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------
|
||||
|
||||
getRandomTabPlaylistDB(nbPlaylist: number, nbVideoMax: number): PlaylistDB[]
|
||||
{
|
||||
let tabPlaylist: PlaylistDB[] = [];
|
||||
|
||||
|
|
@ -218,9 +240,33 @@ export class FictitiousVideosService
|
|||
}
|
||||
|
||||
|
||||
getAllVideoAll(): VideoAll[]
|
||||
getNoRandomTabPlaylistDB(nbPlaylist: number): PlaylistDB[]
|
||||
{
|
||||
return TAB_VIDEO;
|
||||
let tabPlaylist: PlaylistDB[] = [];
|
||||
|
||||
for(let i = 0; i < nbPlaylist; i++)
|
||||
{
|
||||
const videoIds = [];
|
||||
for(let j=0 ; j<i*2 ; j++) videoIds.push(TAB_VIDEO[j%TAB_VIDEO.length]._id);
|
||||
tabPlaylist.push({
|
||||
_id: i.toString(),
|
||||
userId: "userId",
|
||||
name: "playlist_"+i.toString(),
|
||||
videoIds: videoIds,
|
||||
isActive: true,
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date()
|
||||
});
|
||||
}
|
||||
|
||||
return tabPlaylist;
|
||||
}
|
||||
|
||||
|
||||
getPlaylistBy_id(_id: string): PlaylistDB
|
||||
{
|
||||
const n = parseInt(_id)
|
||||
return this.getNoRandomTabPlaylistDB(n+1)[n];
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Reference in a new issue