[DEV] add prototype of store of the playing position
This commit is contained in:
parent
9892e10312
commit
82cba33e99
@ -2,7 +2,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>kar</groupId>
|
<groupId>kar</groupId>
|
||||||
<artifactId>karideo</artifactId>
|
<artifactId>karideo</artifactId>
|
||||||
<version>0.1.0</version>
|
<version>0.2.0</version>
|
||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.version>3.1</maven.compiler.version>
|
<maven.compiler.version>3.1</maven.compiler.version>
|
||||||
<maven.compiler.source>17</maven.compiler.source>
|
<maven.compiler.source>17</maven.compiler.source>
|
||||||
@ -20,7 +20,7 @@
|
|||||||
<dependency>
|
<dependency>
|
||||||
<groupId>kangaroo-and-rabbit</groupId>
|
<groupId>kangaroo-and-rabbit</groupId>
|
||||||
<artifactId>archidata</artifactId>
|
<artifactId>archidata</artifactId>
|
||||||
<version>0.3.7</version>
|
<version>0.3.8</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
|
@ -8,6 +8,7 @@ import org.glassfish.jersey.server.ResourceConfig;
|
|||||||
import org.kar.karideo.api.*;
|
import org.kar.karideo.api.*;
|
||||||
import org.kar.karideo.filter.KarideoAuthenticationFilter;
|
import org.kar.karideo.filter.KarideoAuthenticationFilter;
|
||||||
import org.kar.karideo.migration.Initialization;
|
import org.kar.karideo.migration.Initialization;
|
||||||
|
import org.kar.karideo.migration.Migration20230810;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.kar.archidata.GlobalConfiguration;
|
import org.kar.archidata.GlobalConfiguration;
|
||||||
@ -45,7 +46,7 @@ public class WebLauncher {
|
|||||||
WebLauncher.LOGGER.info("Add initialization");
|
WebLauncher.LOGGER.info("Add initialization");
|
||||||
migrationEngine.setInit(new Initialization());
|
migrationEngine.setInit(new Initialization());
|
||||||
WebLauncher.LOGGER.info("Add migration since last version");
|
WebLauncher.LOGGER.info("Add migration since last version");
|
||||||
// NOTHING for now
|
migrationEngine.add(new Migration20230810());
|
||||||
WebLauncher.LOGGER.info("Migrate the DB [START]");
|
WebLauncher.LOGGER.info("Migrate the DB [START]");
|
||||||
migrationEngine.migrate(GlobalConfiguration.dbConfig);
|
migrationEngine.migrate(GlobalConfiguration.dbConfig);
|
||||||
WebLauncher.LOGGER.info("Migrate the DB [STOP]");
|
WebLauncher.LOGGER.info("Migrate the DB [STOP]");
|
||||||
@ -91,6 +92,7 @@ public class WebLauncher {
|
|||||||
rc.register(SeasonResource.class);
|
rc.register(SeasonResource.class);
|
||||||
rc.register(TypeResource.class);
|
rc.register(TypeResource.class);
|
||||||
rc.register(VideoResource.class);
|
rc.register(VideoResource.class);
|
||||||
|
rc.register(UserMediaAdvancementResource.class);
|
||||||
|
|
||||||
rc.register(HealthCheck.class);
|
rc.register(HealthCheck.class);
|
||||||
rc.register(Front.class);
|
rc.register(Front.class);
|
||||||
|
@ -1,15 +1,19 @@
|
|||||||
package org.kar.karideo.api;
|
package org.kar.karideo.api;
|
||||||
|
|
||||||
import org.kar.archidata.annotation.security.PermitAll;
|
import org.kar.archidata.annotation.security.PermitAll;
|
||||||
|
|
||||||
import jakarta.ws.rs.*;
|
import jakarta.ws.rs.*;
|
||||||
import jakarta.ws.rs.core.MediaType;
|
import jakarta.ws.rs.core.MediaType;
|
||||||
import jakarta.ws.rs.core.Response;
|
import jakarta.ws.rs.core.Response;
|
||||||
|
|
||||||
import org.kar.archidata.util.JWTWrapper;
|
import org.kar.archidata.util.JWTWrapper;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@Path("/health_check")
|
@Path("/health_check")
|
||||||
@Produces(MediaType.APPLICATION_JSON)
|
@Produces(MediaType.APPLICATION_JSON)
|
||||||
public class HealthCheck {
|
public class HealthCheck {
|
||||||
|
static final Logger LOGGER = LoggerFactory.getLogger(HealthCheck.class);
|
||||||
public class HealthResult {
|
public class HealthResult {
|
||||||
public String value;
|
public String value;
|
||||||
public HealthResult(String value) {
|
public HealthResult(String value) {
|
||||||
|
@ -3,6 +3,8 @@ package org.kar.karideo.api;
|
|||||||
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
||||||
import org.glassfish.jersey.media.multipart.FormDataParam;
|
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
import org.kar.karideo.model.Season;
|
import org.kar.karideo.model.Season;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.kar.archidata.SqlWrapper;
|
import org.kar.archidata.SqlWrapper;
|
||||||
import org.kar.archidata.annotation.security.RolesAllowed;
|
import org.kar.archidata.annotation.security.RolesAllowed;
|
||||||
import org.kar.archidata.util.DataTools;
|
import org.kar.archidata.util.DataTools;
|
||||||
@ -16,6 +18,7 @@ import java.util.List;
|
|||||||
@Path("/season")
|
@Path("/season")
|
||||||
@Produces({MediaType.APPLICATION_JSON})
|
@Produces({MediaType.APPLICATION_JSON})
|
||||||
public class SeasonResource {
|
public class SeasonResource {
|
||||||
|
static final Logger LOGGER = LoggerFactory.getLogger(SeasonResource.class);
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}")
|
@Path("{id}")
|
||||||
|
@ -4,6 +4,8 @@ import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
|||||||
import org.glassfish.jersey.media.multipart.FormDataParam;
|
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
import org.kar.karideo.model.Season;
|
import org.kar.karideo.model.Season;
|
||||||
import org.kar.karideo.model.Series;
|
import org.kar.karideo.model.Series;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.kar.archidata.SqlWrapper;
|
import org.kar.archidata.SqlWrapper;
|
||||||
import org.kar.archidata.annotation.security.RolesAllowed;
|
import org.kar.archidata.annotation.security.RolesAllowed;
|
||||||
import org.kar.archidata.util.DataTools;
|
import org.kar.archidata.util.DataTools;
|
||||||
@ -17,6 +19,7 @@ import java.util.List;
|
|||||||
@Path("/series")
|
@Path("/series")
|
||||||
@Produces({MediaType.APPLICATION_JSON})
|
@Produces({MediaType.APPLICATION_JSON})
|
||||||
public class SeriesResource {
|
public class SeriesResource {
|
||||||
|
static final Logger LOGGER = LoggerFactory.getLogger(SeriesResource.class);
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@Path("{id}")
|
@Path("{id}")
|
||||||
|
@ -3,6 +3,8 @@ package org.kar.karideo.api;
|
|||||||
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
|
||||||
import org.glassfish.jersey.media.multipart.FormDataParam;
|
import org.glassfish.jersey.media.multipart.FormDataParam;
|
||||||
import org.kar.karideo.model.Type;
|
import org.kar.karideo.model.Type;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.kar.archidata.SqlWrapper;
|
import org.kar.archidata.SqlWrapper;
|
||||||
import org.kar.archidata.annotation.security.RolesAllowed;
|
import org.kar.archidata.annotation.security.RolesAllowed;
|
||||||
import org.kar.archidata.util.DataTools;
|
import org.kar.archidata.util.DataTools;
|
||||||
@ -16,6 +18,7 @@ import java.util.List;
|
|||||||
@Path("/type")
|
@Path("/type")
|
||||||
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
|
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
|
||||||
public class TypeResource {
|
public class TypeResource {
|
||||||
|
static final Logger LOGGER = LoggerFactory.getLogger(TypeResource.class);
|
||||||
|
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
|
103
back/src/org/kar/karideo/api/UserMediaAdvancementResource.java
Normal file
103
back/src/org/kar/karideo/api/UserMediaAdvancementResource.java
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
package org.kar.karideo.api;
|
||||||
|
|
||||||
|
import org.kar.karideo.model.UserMediaAdvancement;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.kar.archidata.SqlWrapper;
|
||||||
|
import org.kar.archidata.WhereCondition;
|
||||||
|
import org.kar.archidata.annotation.security.RolesAllowed;
|
||||||
|
import org.kar.archidata.filter.GenericContext;
|
||||||
|
|
||||||
|
import jakarta.ws.rs.*;
|
||||||
|
import jakarta.ws.rs.core.Context;
|
||||||
|
import jakarta.ws.rs.core.MediaType;
|
||||||
|
import jakarta.ws.rs.core.Response;
|
||||||
|
import jakarta.ws.rs.core.SecurityContext;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Path("/advancement")
|
||||||
|
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
|
||||||
|
public class UserMediaAdvancementResource {
|
||||||
|
static final Logger LOGGER = LoggerFactory.getLogger(UserMediaAdvancementResource.class);
|
||||||
|
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{id}")
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
public UserMediaAdvancement getWithId(@Context SecurityContext sc, @PathParam("id") Long id) throws Exception {
|
||||||
|
GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||||
|
return SqlWrapper.getWhere(UserMediaAdvancement.class,
|
||||||
|
List.of(
|
||||||
|
new WhereCondition("mediaId", "=", id),
|
||||||
|
new WhereCondition("userId", "=", gc.userByToken.id),
|
||||||
|
new WhereCondition("deleted", "=", 0)
|
||||||
|
), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
public List<UserMediaAdvancement> gets(@Context SecurityContext sc ) throws Exception {
|
||||||
|
GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||||
|
return SqlWrapper.getsWhere(UserMediaAdvancement.class,
|
||||||
|
List.of(
|
||||||
|
new WhereCondition("userId", "=", gc.userByToken.id),
|
||||||
|
new WhereCondition("deleted", "=", 0)
|
||||||
|
), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* =============================================================================
|
||||||
|
* Modification SECTION:
|
||||||
|
* ============================================================================= */
|
||||||
|
|
||||||
|
public record MediaInformations(int time, float percent, int count) {};
|
||||||
|
|
||||||
|
//@POST
|
||||||
|
//@Path("{id}")
|
||||||
|
//@RolesAllowed("USER")
|
||||||
|
//@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public UserMediaAdvancement post(@Context SecurityContext sc, @PathParam("id") Long id, MediaInformations data) throws Exception {
|
||||||
|
GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||||
|
UserMediaAdvancement elem = new UserMediaAdvancement();
|
||||||
|
elem.userId = gc.userByToken.id;
|
||||||
|
elem.mediaId = id;
|
||||||
|
elem.time = data.time;
|
||||||
|
elem.percent = data.percent;
|
||||||
|
elem.count = data.count;
|
||||||
|
return SqlWrapper.insert(elem);
|
||||||
|
}
|
||||||
|
public record MediaInformationsDelta(int time, float percent, boolean addCount) {};
|
||||||
|
|
||||||
|
@PUT
|
||||||
|
@Path("{id}")
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
public UserMediaAdvancement put(@Context SecurityContext sc, @PathParam("id") Long id, MediaInformationsDelta data) throws Exception {
|
||||||
|
UserMediaAdvancement elem = this.getWithId(sc, id);
|
||||||
|
if (elem == null) {
|
||||||
|
// insert element
|
||||||
|
return this.post(sc, id, new MediaInformations(data.time(), data.percent(), 0));
|
||||||
|
}
|
||||||
|
elem.time = data.time;
|
||||||
|
elem.percent = data.percent;
|
||||||
|
if (data.addCount) {
|
||||||
|
elem.count++;
|
||||||
|
}
|
||||||
|
LOGGER.info("{},{},{}", elem.time, elem.percent, elem.count);
|
||||||
|
int nbAfected = SqlWrapper.update(elem, elem.id, List.of("time", "percent","count"));
|
||||||
|
// TODO: manage the fact that no element has been updated ...
|
||||||
|
UserMediaAdvancement ret = SqlWrapper.get(UserMediaAdvancement.class, elem.id);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
@DELETE
|
||||||
|
@Path("{id}")
|
||||||
|
@RolesAllowed("USER")
|
||||||
|
public Response delete(@Context SecurityContext sc, @PathParam("id") Long id) throws Exception {
|
||||||
|
UserMediaAdvancement elem = this.getWithId(sc, id);
|
||||||
|
SqlWrapper.setDelete(UserMediaAdvancement.class, elem.id);
|
||||||
|
return Response.ok().build();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -20,7 +20,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
@Path("/users")
|
@Path("/users")
|
||||||
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
|
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
|
||||||
public class UserResource {
|
public class UserResource {
|
||||||
final Logger logger = LoggerFactory.getLogger(UserResource.class);
|
static final Logger LOGGER = LoggerFactory.getLogger(UserResource.class);
|
||||||
|
|
||||||
@JsonInclude(JsonInclude.Include.NON_NULL)
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
public class UserOut {
|
public class UserOut {
|
||||||
@ -73,9 +73,9 @@ public class UserResource {
|
|||||||
@Path("me")
|
@Path("me")
|
||||||
@RolesAllowed("USER")
|
@RolesAllowed("USER")
|
||||||
public UserOut getMe(@Context SecurityContext sc) {
|
public UserOut getMe(@Context SecurityContext sc) {
|
||||||
logger.debug("getMe()");
|
LOGGER.debug("getMe()");
|
||||||
GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
GenericContext gc = (GenericContext) sc.getUserPrincipal();
|
||||||
logger.debug("== USER ? {}", gc.userByToken);
|
LOGGER.debug("== USER ? {}", gc.userByToken);
|
||||||
return new UserOut(gc.userByToken.id, gc.userByToken.name);
|
return new UserOut(gc.userByToken.id, gc.userByToken.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,6 +8,8 @@ import org.kar.karideo.model.Media;
|
|||||||
import org.kar.karideo.model.Season;
|
import org.kar.karideo.model.Season;
|
||||||
import org.kar.karideo.model.Series;
|
import org.kar.karideo.model.Series;
|
||||||
import org.kar.karideo.model.Type;
|
import org.kar.karideo.model.Type;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.kar.archidata.SqlWrapper;
|
import org.kar.archidata.SqlWrapper;
|
||||||
import org.kar.archidata.annotation.security.RolesAllowed;
|
import org.kar.archidata.annotation.security.RolesAllowed;
|
||||||
import org.kar.archidata.api.DataResource;
|
import org.kar.archidata.api.DataResource;
|
||||||
@ -26,6 +28,7 @@ import java.util.List;
|
|||||||
@Path("/video")
|
@Path("/video")
|
||||||
@Produces({MediaType.APPLICATION_JSON})
|
@Produces({MediaType.APPLICATION_JSON})
|
||||||
public class VideoResource {
|
public class VideoResource {
|
||||||
|
static final Logger LOGGER = LoggerFactory.getLogger(VideoResource.class);
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@RolesAllowed("USER")
|
@RolesAllowed("USER")
|
||||||
|
@ -7,6 +7,7 @@ import org.kar.karideo.model.Media;
|
|||||||
import org.kar.karideo.model.Season;
|
import org.kar.karideo.model.Season;
|
||||||
import org.kar.karideo.model.Series;
|
import org.kar.karideo.model.Series;
|
||||||
import org.kar.karideo.model.Type;
|
import org.kar.karideo.model.Type;
|
||||||
|
import org.kar.karideo.model.UserMediaAdvancement;
|
||||||
|
|
||||||
public class Initialization extends MigrationSqlStep {
|
public class Initialization extends MigrationSqlStep {
|
||||||
|
|
||||||
@ -24,6 +25,7 @@ public class Initialization extends MigrationSqlStep {
|
|||||||
addClass(Series.class);
|
addClass(Series.class);
|
||||||
addClass(Season.class);
|
addClass(Season.class);
|
||||||
addClass(User.class);
|
addClass(User.class);
|
||||||
|
addClass(UserMediaAdvancement.class);
|
||||||
|
|
||||||
addAction("""
|
addAction("""
|
||||||
INSERT INTO `type` (`id`, `name`, `description`) VALUES
|
INSERT INTO `type` (`id`, `name`, `description`) VALUES
|
||||||
@ -54,6 +56,9 @@ public class Initialization extends MigrationSqlStep {
|
|||||||
addAction("""
|
addAction("""
|
||||||
ALTER TABLE `season` AUTO_INCREMENT = 1000;
|
ALTER TABLE `season` AUTO_INCREMENT = 1000;
|
||||||
""");
|
""");
|
||||||
|
addAction("""
|
||||||
|
ALTER TABLE `userMediaAdvencement` AUTO_INCREMENT = 1000;
|
||||||
|
""");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
23
back/src/org/kar/karideo/migration/Migration20230810.java
Normal file
23
back/src/org/kar/karideo/migration/Migration20230810.java
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package org.kar.karideo.migration;
|
||||||
|
|
||||||
|
import org.kar.archidata.migration.MigrationSqlStep;
|
||||||
|
import org.kar.karideo.model.UserMediaAdvancement;
|
||||||
|
|
||||||
|
public class Migration20230810 extends MigrationSqlStep {
|
||||||
|
|
||||||
|
public static final int KARSO_INITIALISATION_ID = 1;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "migration-2023-08-10";
|
||||||
|
}
|
||||||
|
|
||||||
|
public Migration20230810() throws Exception {
|
||||||
|
addClass(UserMediaAdvancement.class);
|
||||||
|
|
||||||
|
addAction("""
|
||||||
|
ALTER TABLE `userMediaAdvencement` AUTO_INCREMENT = 1000;
|
||||||
|
""");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
34
back/src/org/kar/karideo/model/UserMediaAdvancement.java
Normal file
34
back/src/org/kar/karideo/model/UserMediaAdvancement.java
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package org.kar.karideo.model;
|
||||||
|
|
||||||
|
import org.kar.archidata.annotation.SQLComment;
|
||||||
|
import org.kar.archidata.annotation.SQLForeignKey;
|
||||||
|
import org.kar.archidata.annotation.SQLIfNotExists;
|
||||||
|
import org.kar.archidata.annotation.SQLNotNull;
|
||||||
|
import org.kar.archidata.annotation.SQLTableName;
|
||||||
|
import org.kar.archidata.model.GenericTable;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
|
||||||
|
|
||||||
|
@SQLTableName ("userMediaAdvancement")
|
||||||
|
@SQLIfNotExists
|
||||||
|
@JsonInclude(JsonInclude.Include.NON_NULL)
|
||||||
|
public class UserMediaAdvancement extends GenericTable {
|
||||||
|
@SQLNotNull
|
||||||
|
@SQLComment("Foreign Key Id of the user")
|
||||||
|
@SQLForeignKey("user")
|
||||||
|
public long userId;
|
||||||
|
@SQLNotNull
|
||||||
|
@SQLComment("Id of the media")
|
||||||
|
@SQLForeignKey("media")
|
||||||
|
public long mediaId;
|
||||||
|
@SQLNotNull
|
||||||
|
@SQLComment("Percent of admencement in the media")
|
||||||
|
public float percent;
|
||||||
|
@SQLNotNull
|
||||||
|
@SQLComment("Number of second of admencement in the media")
|
||||||
|
public int time;
|
||||||
|
@SQLNotNull
|
||||||
|
@SQLComment("Number of time this media has been read")
|
||||||
|
public int count;
|
||||||
|
}
|
43510
front/package-lock.json
generated
43510
front/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -8,31 +8,23 @@ import { BrowserModule } from '@angular/platform-browser';
|
|||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { HttpClientModule } from '@angular/common/http';
|
import { HttpClientModule } from '@angular/common/http';
|
||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; // this is needed for dynamic selection of the select
|
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
|
|
||||||
import { UploadFileComponent } from 'common/component/upload-file/upload-file';
|
|
||||||
import { ElementDataImageComponent } from './component/data-image/data-image';
|
|
||||||
import { ElementTypeComponent } from './component/element-type/element-type';
|
import { ElementTypeComponent } from './component/element-type/element-type';
|
||||||
import { ElementSeriesComponent } from './component/element-series/element-series';
|
import { ElementSeriesComponent } from './component/element-series/element-series';
|
||||||
import { ElementSeasonComponent } from './component/element-season/element-season';
|
import { ElementSeasonComponent } from './component/element-season/element-season';
|
||||||
import { ElementVideoComponent } from './component/element-video/element-video';
|
import { ElementVideoComponent } from './component/element-video/element-video';
|
||||||
import { PopInComponent } from 'common/component/popin/popin';
|
|
||||||
|
|
||||||
import { PopInCreateType } from './popin/create-type/create-type';
|
import { PopInCreateType } from './popin/create-type/create-type';
|
||||||
import { PopInUploadProgress } from 'common/popin/upload-progress/upload-progress';
|
|
||||||
import { PopInDeleteConfirm } from 'common/popin/delete-confirm/delete-confirm';
|
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import {
|
import {
|
||||||
HomeScene, HelpScene, TypeScene, SeriesScene, SeasonScene, VideoScene, SettingsScene,
|
HomeScene, HelpScene, TypeScene, SeriesScene, SeasonScene, VideoScene, SettingsScene,
|
||||||
VideoEditScene, SeasonEditScene, SeriesEditScene
|
VideoEditScene, SeasonEditScene, SeriesEditScene
|
||||||
} from './scene';
|
} from './scene';
|
||||||
import { TypeService, DataService, SeriesService, SeasonService, VideoService, ArianeService } from './service';
|
import { TypeService, DataService, SeriesService, SeasonService, VideoService, ArianeService, AdvancementService } from './service';
|
||||||
import { BddService, CookiesService, HttpWrapperService, OnlyAdminGuard, OnlyUnregisteredGuardHome, OnlyUsersGuard, OnlyUsersGuardHome, PopInService, SessionService, SSOService, StorageService, UserService } from 'common/service';
|
|
||||||
import { ErrorViewerScene, ForbiddenScene, HomeOutScene, NotFound404Scene, SsoScene } from 'common/scene';
|
|
||||||
import { UploadScene } from './scene/upload/upload';
|
import { UploadScene } from './scene/upload/upload';
|
||||||
import { AsyncActionStatusComponent, BurgerPropertyComponent, CheckboxComponent, EntryComponent, EntryNumberComponent, EntryValidatorComponent, ErrorComponent, ErrorMessageStateComponent, PasswordEntryComponent, RenderFormComponent, RenderSettingsComponent, SpinerComponent, TopMenuComponent } from 'common/component';
|
import { common_module_declarations, common_module_imports, common_module_providers, common_module_exports } from 'common/module';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@ -42,30 +34,10 @@ import { AsyncActionStatusComponent, BurgerPropertyComponent, CheckboxComponent,
|
|||||||
ElementVideoComponent,
|
ElementVideoComponent,
|
||||||
|
|
||||||
AppComponent,
|
AppComponent,
|
||||||
TopMenuComponent,
|
|
||||||
UploadFileComponent,
|
|
||||||
ErrorComponent,
|
|
||||||
PasswordEntryComponent,
|
|
||||||
EntryComponent,
|
|
||||||
EntryValidatorComponent,
|
|
||||||
SpinerComponent,
|
|
||||||
AsyncActionStatusComponent,
|
|
||||||
ErrorMessageStateComponent,
|
|
||||||
CheckboxComponent,
|
|
||||||
BurgerPropertyComponent,
|
|
||||||
RenderSettingsComponent,
|
|
||||||
RenderFormComponent,
|
|
||||||
EntryNumberComponent,
|
|
||||||
|
|
||||||
PopInComponent,
|
|
||||||
PopInCreateType,
|
PopInCreateType,
|
||||||
PopInUploadProgress,
|
|
||||||
PopInDeleteConfirm,
|
|
||||||
|
|
||||||
HomeScene,
|
HomeScene,
|
||||||
ErrorViewerScene,
|
|
||||||
HelpScene,
|
HelpScene,
|
||||||
SsoScene,
|
|
||||||
TypeScene,
|
TypeScene,
|
||||||
SeriesScene,
|
SeriesScene,
|
||||||
SeasonScene,
|
SeasonScene,
|
||||||
@ -75,52 +47,33 @@ import { AsyncActionStatusComponent, BurgerPropertyComponent, CheckboxComponent,
|
|||||||
SeasonEditScene,
|
SeasonEditScene,
|
||||||
SeriesEditScene,
|
SeriesEditScene,
|
||||||
UploadScene,
|
UploadScene,
|
||||||
ForbiddenScene,
|
...common_module_declarations,
|
||||||
HomeOutScene,
|
|
||||||
NotFound404Scene,
|
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
RouterModule,
|
RouterModule,
|
||||||
AppRoutingModule,
|
AppRoutingModule,
|
||||||
HttpClientModule,
|
HttpClientModule,
|
||||||
FormsModule,
|
...common_module_imports,
|
||||||
ReactiveFormsModule,
|
|
||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
PopInService,
|
|
||||||
HttpWrapperService,
|
|
||||||
SessionService,
|
|
||||||
CookiesService,
|
|
||||||
StorageService,
|
|
||||||
UserService,
|
|
||||||
SSOService,
|
|
||||||
BddService,
|
|
||||||
TypeService,
|
TypeService,
|
||||||
DataService,
|
DataService,
|
||||||
SeriesService,
|
SeriesService,
|
||||||
SeasonService,
|
SeasonService,
|
||||||
VideoService,
|
VideoService,
|
||||||
ArianeService,
|
ArianeService,
|
||||||
OnlyUsersGuard,
|
AdvancementService,
|
||||||
OnlyAdminGuard,
|
...common_module_providers,
|
||||||
OnlyUsersGuardHome,
|
|
||||||
OnlyUnregisteredGuardHome,
|
|
||||||
],
|
],
|
||||||
exports: [
|
exports: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
TopMenuComponent,
|
|
||||||
UploadFileComponent,
|
|
||||||
ErrorComponent,
|
|
||||||
ElementTypeComponent,
|
ElementTypeComponent,
|
||||||
ElementSeriesComponent,
|
ElementSeriesComponent,
|
||||||
ElementSeasonComponent,
|
ElementSeasonComponent,
|
||||||
ElementVideoComponent,
|
ElementVideoComponent,
|
||||||
PopInCreateType,
|
PopInCreateType,
|
||||||
|
...common_module_exports,
|
||||||
PopInComponent,
|
|
||||||
PopInUploadProgress,
|
|
||||||
PopInDeleteConfirm,
|
|
||||||
],
|
],
|
||||||
bootstrap: [
|
bootstrap: [
|
||||||
AppComponent
|
AppComponent
|
||||||
|
37
front/src/app/model/user-media-advancement.ts
Normal file
37
front/src/app/model/user-media-advancement.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { isNumberFinite, isString, isOptionalOf, isNumber } from "common/utils";
|
||||||
|
import { isNodeData, NodeData } from "common/model/node";
|
||||||
|
|
||||||
|
|
||||||
|
export interface UserMediaAdvancement {
|
||||||
|
id: number;
|
||||||
|
|
||||||
|
// Id of the media
|
||||||
|
mediaId?: number;
|
||||||
|
// Percent of advancement in the media
|
||||||
|
percent?: number;
|
||||||
|
// "Number of second of advancement in the media
|
||||||
|
time?: number;
|
||||||
|
// Number of time this media has been read
|
||||||
|
count?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export function isUserMediaAdvancement(data: any): data is UserMediaAdvancement {
|
||||||
|
if (!isNumberFinite(data.id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!isNumberFinite(data.mediaId)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!isNumber(data.percent)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!isNumberFinite(data.time)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!isNumberFinite(data.count)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
@ -1,14 +1,14 @@
|
|||||||
<div class="main-reduce">
|
<div class="main-reduce">
|
||||||
<div class="fill-all" *ngIf="mediaIsNotFound">
|
<div class="fill-all" *ngIf="mediaIsNotFound">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
Play media<br/><br/><br/><br/><br/>
|
Play media<br /><br /><br /><br /><br />
|
||||||
The media does not exist
|
The media does not exist
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fill-all" *ngIf="mediaIsLoading">
|
<div class="fill-all" *ngIf="mediaIsLoading">
|
||||||
<div class="title">
|
<div class="title">
|
||||||
Play media<br/><br/><br/><br/><br/>
|
Play media<br /><br /><br /><br /><br />
|
||||||
Loading ...<br/>
|
Loading ...<br />
|
||||||
Please wait.
|
Please wait.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -20,7 +20,7 @@
|
|||||||
<div class="cover-full">
|
<div class="cover-full">
|
||||||
<div class="cover">
|
<div class="cover">
|
||||||
<div class="cover-image" *ngIf="covers">
|
<div class="cover-image" *ngIf="covers">
|
||||||
<img src="{{covers[0]}}"/>
|
<img src="{{covers[0]}}" />
|
||||||
</div>
|
</div>
|
||||||
<div class="cover-no-image" *ngIf="covers"></div>
|
<div class="cover-no-image" *ngIf="covers"></div>
|
||||||
<div class="cover-button">
|
<div class="cover-button">
|
||||||
@ -53,41 +53,34 @@
|
|||||||
<div class="episode">
|
<div class="episode">
|
||||||
<b>generatedName:</b> {{generatedName}}
|
<b>generatedName:</b> {{generatedName}}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="description">
|
||||||
|
count= {{userMetaData?.count}} view percent={{userMetaData?.percent}}
|
||||||
|
percent={{convertIndisplayTime(userMetaData?.time)}}
|
||||||
|
</div>
|
||||||
<div class="description">
|
<div class="description">
|
||||||
{{description}}
|
{{description}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="fill-all bg-black" *ngIf="playVideo">
|
<div class="fill-all bg-black" *ngIf="playVideo">
|
||||||
<div class="video"
|
<div class="video" #globalVideoElement (mousemove)="startHideTimer()"
|
||||||
#globalVideoElement
|
|
||||||
(mousemove)="startHideTimer()"
|
|
||||||
(fullscreenchange)="onFullscreenChange($event)">
|
(fullscreenchange)="onFullscreenChange($event)">
|
||||||
<div class="video-elem">
|
<div class="video-elem">
|
||||||
<video src="{{videoSource}}"
|
<video src="{{videoSource}}" #videoPlayer preload (play)="changeStateToPlay()"
|
||||||
#videoPlayer
|
(pause)="changeStateToPause()" (timeupdate)="changeTimeupdate($event.currentTime)"
|
||||||
preload
|
(durationchange)="changeDurationchange($event.duration)" (loadedmetadata)="changeMetadata()"
|
||||||
(play)="changeStateToPlay()"
|
(audioTracks)="audioTracks($event)" autoplay (ended)="onVideoEnded()"><!-- controls > -->
|
||||||
(pause)="changeStateToPause()"
|
<!--preload="none"-->
|
||||||
(timeupdate)="changeTimeupdate($event.currentTime)"
|
|
||||||
(durationchange)="changeDurationchange($event.duration)"
|
|
||||||
(loadedmetadata)="changeMetadata()"
|
|
||||||
(audioTracks)="audioTracks($event)"
|
|
||||||
autoplay
|
|
||||||
(ended)="onVideoEnded()"
|
|
||||||
><!-- controls > --> <!--preload="none"-->
|
|
||||||
<!--<p>Your browser does not support HTML5 video player. download video: <a href="{{videoSource}}>link here</a>.</p>-->
|
<!--<p>Your browser does not support HTML5 video player. download video: <a href="{{videoSource}}>link here</a>.</p>-->
|
||||||
</video>
|
</video>
|
||||||
</div>
|
</div>
|
||||||
<div class="controls" *ngIf="!displayNeedHide || !isPlaying">
|
<div class="controls" *ngIf="!displayNeedHide || !isPlaying">
|
||||||
<button (click)="onPlay()" *ngIf="!isPlaying" ><i class="material-icons">play_arrow</i></button>
|
<button (click)="onPlay()" *ngIf="!isPlaying"><i class="material-icons">play_arrow</i></button>
|
||||||
<button (click)="onPause()" *ngIf="isPlaying" ><i class="material-icons">pause</i></button>
|
<button (click)="onPause()" *ngIf="isPlaying"><i class="material-icons">pause</i></button>
|
||||||
<button (click)="onStop()" ><i class="material-icons">stop</i></button>
|
<button (click)="onStop()"><i class="material-icons">stop</i></button>
|
||||||
<div class="timer">
|
<div class="timer">
|
||||||
<div>
|
<div>
|
||||||
<input type="range" min="0" class="slider"
|
<input type="range" min="0" class="slider" [value]="currentTime" [max]="duration"
|
||||||
[value]="currentTime"
|
(input)="seek($event.target)">
|
||||||
[max]="duration"
|
|
||||||
(input)="seek($event.target)">
|
|
||||||
</div>
|
</div>
|
||||||
<div class="timer-text">
|
<div class="timer-text">
|
||||||
<label class="unselectable">{{currentTimeDisplay}} / {{durationDisplay}}</label>
|
<label class="unselectable">{{currentTimeDisplay}} / {{durationDisplay}}</label>
|
||||||
@ -99,13 +92,17 @@
|
|||||||
<!--<button (click)="onNext()"><i class="material-icons">navigate_next</i></button>-->
|
<!--<button (click)="onNext()"><i class="material-icons">navigate_next</i></button>-->
|
||||||
<!--<button (click)="onMore()" ><i class="material-icons">more_vert</i></button>-->
|
<!--<button (click)="onMore()" ><i class="material-icons">more_vert</i></button>-->
|
||||||
<button (click)="onFullscreen()" *ngIf="!isFullScreen"><i class="material-icons">fullscreen</i></button>
|
<button (click)="onFullscreen()" *ngIf="!isFullScreen"><i class="material-icons">fullscreen</i></button>
|
||||||
<button (click)="onFullscreenExit()" *ngIf="isFullScreen"><i class="material-icons">fullscreen_exit</i></button>
|
<button (click)="onFullscreenExit()" *ngIf="isFullScreen"><i
|
||||||
|
class="material-icons">fullscreen_exit</i></button>
|
||||||
<!--<button (click)="onTakeScreenShoot()"><i class="material-icons">add_a_photo</i></button>-->
|
<!--<button (click)="onTakeScreenShoot()"><i class="material-icons">add_a_photo</i></button>-->
|
||||||
<button (click)="onVolumeMenu()" ><i class="material-icons">volume_up</i></button>
|
<button (click)="onVolumeMenu()"><i class="material-icons">volume_up</i></button>
|
||||||
|
|
||||||
<button class="bigPause" (click)="onPauseToggle()"><i *ngIf="!isPlaying" class="material-icons">play_circle_outline</i></button>
|
<button class="bigPause" (click)="onPauseToggle()"><i *ngIf="!isPlaying"
|
||||||
<button class="bigRewind" (click)="onRewind()"><i *ngIf="!isPlaying" class="material-icons">fast_rewind</i></button>
|
class="material-icons">play_circle_outline</i></button>
|
||||||
<button class="bigForward" (click)="onForward()"><i *ngIf="!isPlaying" class="material-icons">fast_forward</i></button>
|
<button class="bigRewind" (click)="onRewind()"><i *ngIf="!isPlaying"
|
||||||
|
class="material-icons">fast_rewind</i></button>
|
||||||
|
<button class="bigForward" (click)="onForward()"><i *ngIf="!isPlaying"
|
||||||
|
class="material-icons">fast_forward</i></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="title-inline" *ngIf="!isFullScreen || !isPlaying">
|
<div class="title-inline" *ngIf="!isFullScreen || !isPlaying">
|
||||||
@ -119,12 +116,13 @@
|
|||||||
<div class="volume" *ngIf="displayVolumeMenu && (!displayNeedHide || !isPlaying)">
|
<div class="volume" *ngIf="displayVolumeMenu && (!displayNeedHide || !isPlaying)">
|
||||||
<div class="volume-menu">
|
<div class="volume-menu">
|
||||||
<div class="slidecontainer">
|
<div class="slidecontainer">
|
||||||
<input type="range" min="0" max="100" class="slider"
|
<input type="range" min="0" max="100" class="slider" [value]="volumeValue"
|
||||||
[value]="volumeValue"
|
(input)="onVolume($event.target)">
|
||||||
(input)="onVolume($event.target)">
|
|
||||||
</div>
|
</div>
|
||||||
<button (click)="onVolumeMute()" *ngIf="!videoPlayer.muted"><i class="material-icons">volume_mute</i></button>
|
<button (click)="onVolumeMute()" *ngIf="!videoPlayer.muted"><i
|
||||||
<button (click)="onVolumeUnMute()" *ngIf="videoPlayer.muted"><i class="material-icons">volume_off</i></button>
|
class="material-icons">volume_mute</i></button>
|
||||||
|
<button (click)="onVolumeUnMute()" *ngIf="videoPlayer.muted"><i
|
||||||
|
class="material-icons">volume_off</i></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,93 +5,109 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
|
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { UserMediaAdvancement } from 'app/model/user-media-advancement';
|
||||||
import { DataService, VideoService, SeriesService, SeasonService, ArianeService } from 'app/service';
|
import { DataService, VideoService, SeriesService, SeasonService, ArianeService, AdvancementService } from 'app/service';
|
||||||
import { HttpWrapperService } from 'common/service';
|
import { HttpWrapperService } from 'common/service';
|
||||||
import { isNullOrUndefined } from 'common/utils';
|
import { isNullOrUndefined } from 'common/utils';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-video',
|
selector: 'app-video',
|
||||||
templateUrl: './video.html',
|
templateUrl: './video.html',
|
||||||
styleUrls: [ './video.less' ]
|
styleUrls: ['./video.less']
|
||||||
})
|
})
|
||||||
|
|
||||||
export class VideoScene implements OnInit {
|
export class VideoScene implements OnInit {
|
||||||
videoGlobal:any;
|
videoGlobal: any;
|
||||||
@ViewChild('globalVideoElement')
|
@ViewChild('globalVideoElement')
|
||||||
set mainDivEl(el: ElementRef) {
|
set mainDivEl(el: ElementRef) {
|
||||||
if(el !== null && el !== undefined) {
|
if (!isNullOrUndefined(el)) {
|
||||||
this.videoGlobal = el.nativeElement;
|
this.videoGlobal = el.nativeElement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
videoPlayer: HTMLVideoElement;
|
videoPlayer: HTMLVideoElement;
|
||||||
@ViewChild('videoPlayer')
|
@ViewChild('videoPlayer')
|
||||||
set mainVideoEl(el: ElementRef) {
|
set mainVideoEl(el: ElementRef) {
|
||||||
if(el !== null && el !== undefined) {
|
if (!isNullOrUndefined(el)) {
|
||||||
this.videoPlayer = el.nativeElement;
|
this.videoPlayer = el.nativeElement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
videoCanva: any;
|
videoCanva: any;
|
||||||
@ViewChild('canvascreenshoot')
|
@ViewChild('canvascreenshoot')
|
||||||
set mainCanvaEl(el: ElementRef) {
|
set mainCanvaEl(el: ElementRef) {
|
||||||
if(el !== null && el !== undefined) {
|
if (!isNullOrUndefined(el)) {
|
||||||
this.videoCanva = el.nativeElement;
|
this.videoCanva = el.nativeElement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
haveNext = null;
|
haveNext = null;
|
||||||
havePrevious = null;
|
havePrevious = null;
|
||||||
idVideo:number = -1;
|
idVideo: number = -1;
|
||||||
|
|
||||||
mediaIsNotFound:boolean = false;
|
mediaIsNotFound: boolean = false;
|
||||||
mediaIsLoading:boolean = true;
|
mediaIsLoading: boolean = true;
|
||||||
error:string = '';
|
error: string = '';
|
||||||
|
|
||||||
name:string = '';
|
name: string = '';
|
||||||
description:string = '';
|
description: string = '';
|
||||||
episode:number = undefined;
|
episode: number = undefined;
|
||||||
seriesId:number = undefined;
|
seriesId: number = undefined;
|
||||||
seriesName:string = undefined;
|
seriesName: string = undefined;
|
||||||
seasonId:number = undefined;
|
seasonId: number = undefined;
|
||||||
seasonName:string = undefined;
|
seasonName: string = undefined;
|
||||||
dataId:number = -1;
|
dataId: number = -1;
|
||||||
time:number = undefined;
|
time: number = undefined;
|
||||||
typeId:number = undefined;
|
typeId: number = undefined;
|
||||||
generatedName:string = '';
|
generatedName: string = '';
|
||||||
videoSource:string = '';
|
videoSource: string = '';
|
||||||
covers: string[];
|
covers: string[];
|
||||||
|
|
||||||
playVideo:boolean = false;
|
playVideo: boolean = false;
|
||||||
displayVolumeMenu:boolean = false;
|
displayVolumeMenu: boolean = false;
|
||||||
isPlaying:boolean = false;
|
isPlaying: boolean = false;
|
||||||
isFullScreen:boolean = false;
|
isFullScreen: boolean = false;
|
||||||
currentTime:number = 0;
|
currentTime: number = 0;
|
||||||
currentTimeDisplay:string = '00';
|
currentTimeDisplay: string = '00';
|
||||||
duration:number = 0;
|
duration: number = 0;
|
||||||
durationDisplay:string = '00';
|
durationDisplay: string = '00';
|
||||||
volumeValue:number = 100;
|
volumeValue: number = 100;
|
||||||
|
|
||||||
displayNeedHide:boolean = false;
|
displayNeedHide: boolean = false;
|
||||||
timeLeft: number = 10;
|
timeLeft: number = 10;
|
||||||
interval = null;
|
interval = null;
|
||||||
|
|
||||||
|
userMetaData: UserMediaAdvancement = undefined
|
||||||
|
|
||||||
|
previousTime: number = 0;
|
||||||
|
startPlayingTime: number = undefined;
|
||||||
|
hasFullReadTheVideo: {
|
||||||
|
previousTime: number,
|
||||||
|
totalCount: number,
|
||||||
|
registered: boolean
|
||||||
|
} = {
|
||||||
|
previousTime: 0,
|
||||||
|
totalCount: 0,
|
||||||
|
registered: false
|
||||||
|
};
|
||||||
|
|
||||||
constructor(private videoService: VideoService,
|
constructor(private videoService: VideoService,
|
||||||
private seriesService: SeriesService,
|
private seriesService: SeriesService,
|
||||||
private seasonService: SeasonService,
|
private seasonService: SeasonService,
|
||||||
private httpService: HttpWrapperService,
|
private httpService: HttpWrapperService,
|
||||||
private arianeService: ArianeService,
|
private arianeService: ArianeService,
|
||||||
private dataService: DataService) {
|
private dataService: DataService,
|
||||||
|
private advancementService: AdvancementService) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
startHideTimer() {
|
startHideTimer() {
|
||||||
this.displayNeedHide = false;
|
this.displayNeedHide = false;
|
||||||
this.timeLeft = 5;
|
this.timeLeft = 5;
|
||||||
if(this.interval !== null) {
|
if (this.interval !== null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let self = this;
|
let self = this;
|
||||||
this.interval = setInterval(() => {
|
this.interval = setInterval(() => {
|
||||||
console.log(`periodic event: ${ self.timeLeft}`);
|
console.log(`periodic event: ${self.timeLeft}`);
|
||||||
if(self.timeLeft > 0) {
|
if (self.timeLeft > 0) {
|
||||||
self.timeLeft--;
|
self.timeLeft--;
|
||||||
} else {
|
} else {
|
||||||
clearInterval(self.interval);
|
clearInterval(self.interval);
|
||||||
@ -106,32 +122,32 @@ export class VideoScene implements OnInit {
|
|||||||
this.interval = null;
|
this.interval = null;
|
||||||
}
|
}
|
||||||
onRequireNext(event: any) {
|
onRequireNext(event: any) {
|
||||||
console.log(`generate next : ${ this.haveNext.id}`);
|
console.log(`generate next : ${this.haveNext.id}`);
|
||||||
this.arianeService.navigateVideo(this.haveNext.id, event.which === 2, event.ctrlKey);
|
this.arianeService.navigateVideo(this.haveNext.id, event.which === 2, event.ctrlKey);
|
||||||
this.arianeService.setVideo(this.haveNext.id);
|
this.arianeService.setVideo(this.haveNext.id);
|
||||||
}
|
}
|
||||||
onRequirePrevious(event: any) {
|
onRequirePrevious(event: any) {
|
||||||
console.log(`generate previous : ${ this.havePrevious.id}`);
|
console.log(`generate previous : ${this.havePrevious.id}`);
|
||||||
this.arianeService.navigateVideo(this.havePrevious.id, event.which === 2, event.ctrlKey);
|
this.arianeService.navigateVideo(this.havePrevious.id, event.which === 2, event.ctrlKey);
|
||||||
this.arianeService.setVideo(this.havePrevious.id);
|
this.arianeService.setVideo(this.havePrevious.id);
|
||||||
}
|
}
|
||||||
generateName() {
|
generateName() {
|
||||||
this.generatedName = '';
|
this.generatedName = '';
|
||||||
if(this.seriesName !== undefined) {
|
if (this.seriesName !== undefined) {
|
||||||
this.generatedName = `${this.generatedName }${this.seriesName }-`;
|
this.generatedName = `${this.generatedName}${this.seriesName}-`;
|
||||||
}
|
}
|
||||||
if(this.seasonName !== undefined) {
|
if (this.seasonName !== undefined) {
|
||||||
if(this.seasonName.length < 2) {
|
if (this.seasonName.length < 2) {
|
||||||
this.generatedName = `${this.generatedName }s0${ this.seasonName }-`;
|
this.generatedName = `${this.generatedName}s0${this.seasonName}-`;
|
||||||
} else {
|
} else {
|
||||||
this.generatedName = `${this.generatedName }s${ this.seasonName }-`;
|
this.generatedName = `${this.generatedName}s${this.seasonName}-`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(this.episode !== undefined) {
|
if (this.episode !== undefined) {
|
||||||
if(this.episode < 10) {
|
if (this.episode < 10) {
|
||||||
this.generatedName = `${this.generatedName }e0${ this.episode }-`;
|
this.generatedName = `${this.generatedName}e0${this.episode}-`;
|
||||||
} else {
|
} else {
|
||||||
this.generatedName = `${this.generatedName }e${ this.episode }-`;
|
this.generatedName = `${this.generatedName}e${this.episode}-`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.generatedName = this.generatedName + this.name;
|
this.generatedName = this.generatedName + this.name;
|
||||||
@ -139,7 +155,7 @@ export class VideoScene implements OnInit {
|
|||||||
this.generatedName = this.generatedName.replace(new RegExp('/', 'g'), '_');
|
this.generatedName = this.generatedName.replace(new RegExp('/', 'g'), '_');
|
||||||
// update the path of the uri request
|
// update the path of the uri request
|
||||||
this.videoSource = this.httpService.createRESTCall2({
|
this.videoSource = this.httpService.createRESTCall2({
|
||||||
api: `data/${ this.dataId}/${this.generatedName}`,
|
api: `data/${this.dataId}/${this.generatedName}`,
|
||||||
addURLToken: true,
|
addURLToken: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -153,27 +169,27 @@ export class VideoScene implements OnInit {
|
|||||||
/*
|
/*
|
||||||
let captureStream = this.videoPlayer.audioTracks;
|
let captureStream = this.videoPlayer.audioTracks;
|
||||||
for (let iii=0; iii < captureStream.length; iii++) {
|
for (let iii=0; iii < captureStream.length; iii++) {
|
||||||
console.log(" - " + captureStream[iii].language);
|
console.log(" - " + captureStream[iii].language);
|
||||||
if (captureStream[iii].language.substring(0,2) === "fr") {
|
if (captureStream[iii].language.substring(0,2) === "fr") {
|
||||||
captureStream[iii].enabled = true;
|
captureStream[iii].enabled = true;
|
||||||
} else {
|
} else {
|
||||||
captureStream[iii].enabled = false;
|
captureStream[iii].enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
audioTracks(event) {
|
audioTracks(event) {
|
||||||
console.log(`list of the stream:${ event}`);
|
console.log(`list of the stream:${event}`);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
let captureStream = this.videoPlayer.audioTracks;
|
let captureStream = this.videoPlayer.audioTracks;
|
||||||
for (let iii=0; iii < captureStream.length; iii++) {
|
for (let iii=0; iii < captureStream.length; iii++) {
|
||||||
console.log(" - " + captureStream[iii].language);
|
console.log(" - " + captureStream[iii].language);
|
||||||
if (captureStream[iii].language.substring(0,2) === "fr") {
|
if (captureStream[iii].language.substring(0,2) === "fr") {
|
||||||
captureStream[iii].enabled = true;
|
captureStream[iii].enabled = true;
|
||||||
} else {
|
} else {
|
||||||
captureStream[iii].enabled = false;
|
captureStream[iii].enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
@ -183,19 +199,19 @@ export class VideoScene implements OnInit {
|
|||||||
this.startHideTimer();
|
this.startHideTimer();
|
||||||
this.idVideo = this.arianeService.getVideoId();
|
this.idVideo = this.arianeService.getVideoId();
|
||||||
this.arianeService.videoChange.subscribe((videoId) => {
|
this.arianeService.videoChange.subscribe((videoId) => {
|
||||||
console.log(`Detect videoId change...${ videoId}`);
|
console.log(`Detect videoId change...${videoId}`);
|
||||||
self.idVideo = videoId;
|
self.idVideo = videoId;
|
||||||
self.updateDisplay();
|
self.updateDisplay();
|
||||||
});
|
});
|
||||||
self.updateDisplay();
|
self.updateDisplay();
|
||||||
}
|
}
|
||||||
updateDisplay():void {
|
updateDisplay(): void {
|
||||||
let self = this;
|
let self = this;
|
||||||
self.haveNext = null;
|
self.haveNext = null;
|
||||||
self.havePrevious = null;
|
self.havePrevious = null;
|
||||||
this.videoService.get(this.idVideo)
|
this.videoService.get(this.idVideo)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
console.log(`get response of video : ${ JSON.stringify(response, null, 2)}`);
|
console.log(`get response of video : ${JSON.stringify(response, null, 2)}`);
|
||||||
self.error = '';
|
self.error = '';
|
||||||
self.name = response.name;
|
self.name = response.name;
|
||||||
self.description = response.description;
|
self.description = response.description;
|
||||||
@ -205,7 +221,7 @@ export class VideoScene implements OnInit {
|
|||||||
self.dataId = response.dataId;
|
self.dataId = response.dataId;
|
||||||
self.time = response.time;
|
self.time = response.time;
|
||||||
self.generatedName = "????????? TODO: ???????" //response.generatedName;
|
self.generatedName = "????????? TODO: ???????" //response.generatedName;
|
||||||
if(self.dataId !== -1) {
|
if (self.dataId !== -1) {
|
||||||
self.videoSource = self.httpService.createRESTCall2({
|
self.videoSource = self.httpService.createRESTCall2({
|
||||||
api: `data/${self.dataId}/${self.generatedName}`,
|
api: `data/${self.dataId}/${self.generatedName}`,
|
||||||
addURLToken: true,
|
addURLToken: true,
|
||||||
@ -216,7 +232,7 @@ export class VideoScene implements OnInit {
|
|||||||
self.covers = self.dataService.getCoverListUrl(response.covers);
|
self.covers = self.dataService.getCoverListUrl(response.covers);
|
||||||
|
|
||||||
self.generateName();
|
self.generateName();
|
||||||
if(self.seriesId !== undefined && self.seriesId !== null) {
|
if (self.seriesId !== undefined && self.seriesId !== null) {
|
||||||
self.seriesService.get(self.seriesId)
|
self.seriesService.get(self.seriesId)
|
||||||
.then((response2) => {
|
.then((response2) => {
|
||||||
self.seriesName = response2.name;
|
self.seriesName = response2.name;
|
||||||
@ -225,7 +241,7 @@ export class VideoScene implements OnInit {
|
|||||||
// nothing to do ...
|
// nothing to do ...
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if(self.seasonId !== undefined && self.seasonId !== null) {
|
if (self.seasonId !== undefined && self.seasonId !== null) {
|
||||||
self.seasonService.get(self.seasonId)
|
self.seasonService.get(self.seasonId)
|
||||||
.then((response4) => {
|
.then((response4) => {
|
||||||
self.seasonName = response4.name;
|
self.seasonName = response4.name;
|
||||||
@ -234,30 +250,30 @@ export class VideoScene implements OnInit {
|
|||||||
// nothing to do ...
|
// nothing to do ...
|
||||||
});
|
});
|
||||||
self.seasonService.getVideo(self.seasonId)
|
self.seasonService.getVideo(self.seasonId)
|
||||||
.then((response6:any) => {
|
.then((response6: any) => {
|
||||||
// console.log("saison property: " + JSON.stringify(response, null, 2));
|
// console.log("saison property: " + JSON.stringify(response, null, 2));
|
||||||
self.haveNext = null;
|
self.haveNext = null;
|
||||||
self.havePrevious = null;
|
self.havePrevious = null;
|
||||||
for(let iii = 0; iii < response6.length; iii++) {
|
for (let iii = 0; iii < response6.length; iii++) {
|
||||||
if(isNullOrUndefined(response6[iii].episode)) {
|
if (isNullOrUndefined(response6[iii].episode)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(response6[iii].episode < self.episode) {
|
if (response6[iii].episode < self.episode) {
|
||||||
if(self.havePrevious === null) {
|
if (self.havePrevious === null) {
|
||||||
self.havePrevious = response6[iii];
|
self.havePrevious = response6[iii];
|
||||||
} else if(self.havePrevious.episode < response6[iii].episode) {
|
} else if (self.havePrevious.episode < response6[iii].episode) {
|
||||||
self.havePrevious = response6[iii];
|
self.havePrevious = response6[iii];
|
||||||
}
|
}
|
||||||
} else if(response6[iii].episode > self.episode) {
|
} else if (response6[iii].episode > self.episode) {
|
||||||
if(self.haveNext === null) {
|
if (self.haveNext === null) {
|
||||||
self.haveNext = response6[iii];
|
self.haveNext = response6[iii];
|
||||||
} else if(self.haveNext.episode > response6[iii].episode) {
|
} else if (self.haveNext.episode > response6[iii].episode) {
|
||||||
self.haveNext = response6[iii];
|
self.haveNext = response6[iii];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//self.covers.push(self.dataService.getCoverUrl(response6[iii]));
|
//self.covers.push(self.dataService.getCoverUrl(response6[iii]));
|
||||||
}
|
}
|
||||||
}).catch((response7:any) => {
|
}).catch((response7: any) => {
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -281,16 +297,28 @@ export class VideoScene implements OnInit {
|
|||||||
self.mediaIsNotFound = true;
|
self.mediaIsNotFound = true;
|
||||||
self.mediaIsLoading = false;
|
self.mediaIsLoading = false;
|
||||||
});
|
});
|
||||||
|
this.advancementService.get(this.idVideo)
|
||||||
|
.then((response: UserMediaAdvancement) => {
|
||||||
|
this.userMetaData = response
|
||||||
|
this.startPlayingTime = response.time
|
||||||
|
})
|
||||||
}
|
}
|
||||||
onRequirePlay() {
|
onRequirePlay() {
|
||||||
this.startHideTimer();
|
this.startHideTimer();
|
||||||
this.playVideo = true;
|
this.playVideo = true;
|
||||||
|
this.hasFullReadTheVideo = {
|
||||||
|
previousTime: 0,
|
||||||
|
totalCount: 0,
|
||||||
|
registered: false
|
||||||
|
};
|
||||||
this.displayVolumeMenu = false;
|
this.displayVolumeMenu = false;
|
||||||
}
|
}
|
||||||
onRequireStop() {
|
onRequireStop() {
|
||||||
this.startHideTimer();
|
this.startHideTimer();
|
||||||
|
const startPlayingTime = this.videoPlayer.currentTime
|
||||||
this.playVideo = false;
|
this.playVideo = false;
|
||||||
this.displayVolumeMenu = false;
|
this.displayVolumeMenu = false;
|
||||||
|
this.startPlayingTime = startPlayingTime;
|
||||||
}
|
}
|
||||||
onVideoEnded() {
|
onVideoEnded() {
|
||||||
this.startHideTimer();
|
this.startHideTimer();
|
||||||
@ -306,7 +334,7 @@ export class VideoScene implements OnInit {
|
|||||||
|
|
||||||
changeStateToPlay() {
|
changeStateToPlay() {
|
||||||
this.isPlaying = true;
|
this.isPlaying = true;
|
||||||
if(this.isFullScreen === true) {
|
if (this.isFullScreen === true) {
|
||||||
this.onFullscreen();
|
this.onFullscreen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -314,39 +342,82 @@ export class VideoScene implements OnInit {
|
|||||||
this.isPlaying = false;
|
this.isPlaying = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
convertIndisplayTime(time:number) : string {
|
convertIndisplayTime(time: number): string {
|
||||||
let tmpp = parseInt(`${ time}`, 10);
|
let tmpp = parseInt(`${time}`, 10);
|
||||||
let heures = parseInt(`${ tmpp / 3600}`, 10);
|
let heures = parseInt(`${tmpp / 3600}`, 10);
|
||||||
tmpp = tmpp - heures * 3600;
|
tmpp = tmpp - heures * 3600;
|
||||||
let minutes = parseInt(`${ tmpp / 60}`, 10);
|
let minutes = parseInt(`${tmpp / 60}`, 10);
|
||||||
let seconds = tmpp - minutes * 60;
|
let seconds = tmpp - minutes * 60;
|
||||||
let out = '';
|
let out = '';
|
||||||
if(heures !== 0) {
|
if (heures !== 0) {
|
||||||
out = `${out }${heures }:`;
|
out = `${out}${heures}:`;
|
||||||
}
|
}
|
||||||
if(minutes >= 10) {
|
if (minutes >= 10) {
|
||||||
out = `${out }${minutes }:`;
|
out = `${out}${minutes}:`;
|
||||||
} else {
|
} else {
|
||||||
out = `${out }0${ minutes }:`;
|
out = `${out}0${minutes}:`;
|
||||||
}
|
}
|
||||||
if(seconds >= 10) {
|
if (seconds >= 10) {
|
||||||
out = out + seconds;
|
out = out + seconds;
|
||||||
} else {
|
} else {
|
||||||
out = `${out }0${ seconds}`;
|
out = `${out}0${seconds}`;
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
configureDefaultValue(): boolean {
|
||||||
|
if (!isNullOrUndefined(this.startPlayingTime)) {
|
||||||
|
this.videoPlayer.currentTime = this.startPlayingTime
|
||||||
|
this.startPlayingTime = undefined;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
changeTimeupdate(currentTime: any) {
|
changeTimeupdate(currentTime: any) {
|
||||||
// console.log("time change ");
|
// console.log("time change ");
|
||||||
// console.log(" ==> " + this.videoPlayer.currentTime);
|
// console.log(" ==> " + this.videoPlayer.currentTime);
|
||||||
|
// Normal display part
|
||||||
this.currentTime = this.videoPlayer.currentTime;
|
this.currentTime = this.videoPlayer.currentTime;
|
||||||
this.currentTimeDisplay = this.convertIndisplayTime(this.currentTime);
|
this.currentTimeDisplay = this.convertIndisplayTime(this.currentTime);
|
||||||
|
|
||||||
|
// Cat set default value only at start
|
||||||
|
if (this.configureDefaultValue()) {
|
||||||
|
this.hasFullReadTheVideo.previousTime = this.currentTime;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let needAddOneCount = false;
|
||||||
|
// Section to manage the detection of full read of the video
|
||||||
|
if (!this.hasFullReadTheVideo.registered) {
|
||||||
|
console.log(`Check !!!!!!!! ${this.currentTime} / ${this.hasFullReadTheVideo.previousTime} ==> ${this.currentTime - this.hasFullReadTheVideo.previousTime}`);
|
||||||
|
if (Math.abs(this.currentTime - this.hasFullReadTheVideo.previousTime) < 10) {
|
||||||
|
console.log(` ==> step 1`);
|
||||||
|
if (this.currentTime > this.hasFullReadTheVideo.previousTime) {
|
||||||
|
this.hasFullReadTheVideo.totalCount += this.currentTime - this.hasFullReadTheVideo.previousTime;
|
||||||
|
}
|
||||||
|
console.log(` ==> step 2 percent = ${this.currentTime / this.duration}, total=${this.hasFullReadTheVideo.totalCount / 60}`);
|
||||||
|
// Detect the passing of 90%
|
||||||
|
if (this.currentTime / this.duration > 0.9) {
|
||||||
|
console.log(` ==> step 3`);
|
||||||
|
this.hasFullReadTheVideo.registered = true;
|
||||||
|
// Add cont only if the user watching more than 3 minutes
|
||||||
|
if (this.hasFullReadTheVideo.totalCount > 60 * 3) {
|
||||||
|
console.log(` ==> step 4 ==> You win`);
|
||||||
|
needAddOneCount = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.hasFullReadTheVideo.previousTime = this.currentTime;
|
||||||
// console.log(" ==> " + this.currentTimeDisplay);
|
// console.log(" ==> " + this.currentTimeDisplay);
|
||||||
|
if (needAddOneCount || Math.abs(this.previousTime - this.currentTime) > 15) {
|
||||||
|
this.previousTime = this.currentTime;
|
||||||
|
this.advancementService.updateTime(this.idVideo, this.currentTime, this.duration, needAddOneCount);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
changeDurationchange(duration: any) {
|
changeDurationchange(duration: any) {
|
||||||
console.log('duration change ');
|
console.log('duration change ');
|
||||||
console.log(` ==> ${ this.videoPlayer.duration}`);
|
console.log(` ==> ${this.videoPlayer.duration}`);
|
||||||
|
this.configureDefaultValue();
|
||||||
this.duration = this.videoPlayer.duration;
|
this.duration = this.videoPlayer.duration;
|
||||||
this.durationDisplay = this.convertIndisplayTime(this.duration);
|
this.durationDisplay = this.convertIndisplayTime(this.duration);
|
||||||
}
|
}
|
||||||
@ -354,9 +425,9 @@ export class VideoScene implements OnInit {
|
|||||||
onPlay() {
|
onPlay() {
|
||||||
console.log('play');
|
console.log('play');
|
||||||
this.startHideTimer();
|
this.startHideTimer();
|
||||||
if(this.videoPlayer === null ||
|
if (this.videoPlayer === null ||
|
||||||
this.videoPlayer === undefined) {
|
this.videoPlayer === undefined) {
|
||||||
console.log(`error element: ${ this.videoPlayer}`);
|
console.log(`error element: ${this.videoPlayer}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.videoPlayer.volume = this.volumeValue / 100;
|
this.videoPlayer.volume = this.volumeValue / 100;
|
||||||
@ -366,9 +437,9 @@ export class VideoScene implements OnInit {
|
|||||||
onPause() {
|
onPause() {
|
||||||
console.log('pause');
|
console.log('pause');
|
||||||
this.startHideTimer();
|
this.startHideTimer();
|
||||||
if(this.videoPlayer === null ||
|
if (this.videoPlayer === null ||
|
||||||
this.videoPlayer === undefined) {
|
this.videoPlayer === undefined) {
|
||||||
console.log(`error element: ${ this.videoPlayer}`);
|
console.log(`error element: ${this.videoPlayer}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.videoPlayer.pause();
|
this.videoPlayer.pause();
|
||||||
@ -376,7 +447,7 @@ export class VideoScene implements OnInit {
|
|||||||
|
|
||||||
onPauseToggle() {
|
onPauseToggle() {
|
||||||
console.log('pause toggle ...');
|
console.log('pause toggle ...');
|
||||||
if(this.isPlaying === true) {
|
if (this.isPlaying === true) {
|
||||||
this.onPause();
|
this.onPause();
|
||||||
} else {
|
} else {
|
||||||
this.onPlay();
|
this.onPlay();
|
||||||
@ -386,9 +457,9 @@ export class VideoScene implements OnInit {
|
|||||||
onStop() {
|
onStop() {
|
||||||
console.log('stop');
|
console.log('stop');
|
||||||
this.startHideTimer();
|
this.startHideTimer();
|
||||||
if(this.videoPlayer === null ||
|
if (this.videoPlayer === null ||
|
||||||
this.videoPlayer === undefined) {
|
this.videoPlayer === undefined) {
|
||||||
console.log(`error element: ${ this.videoPlayer}`);
|
console.log(`error element: ${this.videoPlayer}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.videoPlayer.pause();
|
this.videoPlayer.pause();
|
||||||
@ -405,12 +476,12 @@ export class VideoScene implements OnInit {
|
|||||||
this.startHideTimer();
|
this.startHideTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
seek(newValue:any) {
|
seek(newValue: any) {
|
||||||
console.log(`seek ${ newValue.value}`);
|
console.log(`seek ${newValue.value}`);
|
||||||
this.startHideTimer();
|
this.startHideTimer();
|
||||||
if(this.videoPlayer === null ||
|
if (this.videoPlayer === null ||
|
||||||
this.videoPlayer === undefined) {
|
this.videoPlayer === undefined) {
|
||||||
console.log(`error element: ${ this.videoPlayer}`);
|
console.log(`error element: ${this.videoPlayer}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.videoPlayer.currentTime = newValue.value;
|
this.videoPlayer.currentTime = newValue.value;
|
||||||
@ -419,9 +490,9 @@ export class VideoScene implements OnInit {
|
|||||||
onRewind() {
|
onRewind() {
|
||||||
console.log('rewind');
|
console.log('rewind');
|
||||||
this.startHideTimer();
|
this.startHideTimer();
|
||||||
if(this.videoPlayer === null ||
|
if (this.videoPlayer === null ||
|
||||||
this.videoPlayer === undefined) {
|
this.videoPlayer === undefined) {
|
||||||
console.log(`error element: ${ this.videoPlayer}`);
|
console.log(`error element: ${this.videoPlayer}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.videoPlayer.currentTime = this.currentTime - 10;
|
this.videoPlayer.currentTime = this.currentTime - 10;
|
||||||
@ -430,9 +501,9 @@ export class VideoScene implements OnInit {
|
|||||||
onForward() {
|
onForward() {
|
||||||
console.log('forward');
|
console.log('forward');
|
||||||
this.startHideTimer();
|
this.startHideTimer();
|
||||||
if(this.videoPlayer === null ||
|
if (this.videoPlayer === null ||
|
||||||
this.videoPlayer === undefined) {
|
this.videoPlayer === undefined) {
|
||||||
console.log(`error element: ${ this.videoPlayer}`);
|
console.log(`error element: ${this.videoPlayer}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.videoPlayer.currentTime = this.currentTime + 10;
|
this.videoPlayer.currentTime = this.currentTime + 10;
|
||||||
@ -441,27 +512,27 @@ export class VideoScene implements OnInit {
|
|||||||
onMore() {
|
onMore() {
|
||||||
console.log('more');
|
console.log('more');
|
||||||
this.startHideTimer();
|
this.startHideTimer();
|
||||||
if(this.videoPlayer === null ||
|
if (this.videoPlayer === null ||
|
||||||
this.videoPlayer === undefined) {
|
this.videoPlayer === undefined) {
|
||||||
console.log(`error element: ${ this.videoPlayer}`);
|
console.log(`error element: ${this.videoPlayer}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onFullscreen() {
|
onFullscreen() {
|
||||||
console.log('fullscreen');
|
console.log('fullscreen');
|
||||||
this.startHideTimer();
|
this.startHideTimer();
|
||||||
if(this.videoGlobal === null ||
|
if (this.videoGlobal === null ||
|
||||||
this.videoGlobal === undefined) {
|
this.videoGlobal === undefined) {
|
||||||
console.log(`error element: ${ this.videoGlobal}`);
|
console.log(`error element: ${this.videoGlobal}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(this.videoGlobal.requestFullscreen) {
|
if (this.videoGlobal.requestFullscreen) {
|
||||||
this.videoGlobal.requestFullscreen();
|
this.videoGlobal.requestFullscreen();
|
||||||
} else if(this.videoGlobal.mozRequestFullScreen) {
|
} else if (this.videoGlobal.mozRequestFullScreen) {
|
||||||
this.videoGlobal.mozRequestFullScreen();
|
this.videoGlobal.mozRequestFullScreen();
|
||||||
} else if(this.videoGlobal.webkitRequestFullscreen) {
|
} else if (this.videoGlobal.webkitRequestFullscreen) {
|
||||||
this.videoGlobal.webkitRequestFullscreen();
|
this.videoGlobal.webkitRequestFullscreen();
|
||||||
} else if(this.videoGlobal.msRequestFullscreen) {
|
} else if (this.videoGlobal.msRequestFullscreen) {
|
||||||
this.videoGlobal.msRequestFullscreen();
|
this.videoGlobal.msRequestFullscreen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -469,21 +540,21 @@ export class VideoScene implements OnInit {
|
|||||||
onFullscreenExit() {
|
onFullscreenExit() {
|
||||||
this.onFullscreenExit22(document);
|
this.onFullscreenExit22(document);
|
||||||
}
|
}
|
||||||
onFullscreenExit22(docc:any) {
|
onFullscreenExit22(docc: any) {
|
||||||
console.log('fullscreen EXIT');
|
console.log('fullscreen EXIT');
|
||||||
this.startHideTimer();
|
this.startHideTimer();
|
||||||
if(this.videoGlobal === null ||
|
if (this.videoGlobal === null ||
|
||||||
this.videoGlobal === undefined) {
|
this.videoGlobal === undefined) {
|
||||||
console.log(`error element: ${ this.videoGlobal}`);
|
console.log(`error element: ${this.videoGlobal}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(docc.exitFullscreen) {
|
if (docc.exitFullscreen) {
|
||||||
docc.exitFullscreen();
|
docc.exitFullscreen();
|
||||||
} else if(docc.mozCancelFullScreen) {
|
} else if (docc.mozCancelFullScreen) {
|
||||||
docc.mozCancelFullScreen();
|
docc.mozCancelFullScreen();
|
||||||
} else if(docc.webkitExitFullscreen) {
|
} else if (docc.webkitExitFullscreen) {
|
||||||
docc.webkitExitFullscreen();
|
docc.webkitExitFullscreen();
|
||||||
} else if(docc.msExitFullscreen) {
|
} else if (docc.msExitFullscreen) {
|
||||||
docc.msExitFullscreen();
|
docc.msExitFullscreen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -491,12 +562,12 @@ export class VideoScene implements OnInit {
|
|||||||
onFullscreenChange() {
|
onFullscreenChange() {
|
||||||
this.onFullscreenChange22(document);
|
this.onFullscreenChange22(document);
|
||||||
}
|
}
|
||||||
onFullscreenChange22(element:any) {
|
onFullscreenChange22(element: any) {
|
||||||
let isInFullScreen = element.fullscreenElement && element.fullscreenElement !== null ||
|
let isInFullScreen = element.fullscreenElement && element.fullscreenElement !== null ||
|
||||||
element.webkitFullscreenElement && element.webkitFullscreenElement !== null ||
|
element.webkitFullscreenElement && element.webkitFullscreenElement !== null ||
|
||||||
element.mozFullScreenElement && element.mozFullScreenElement !== null ||
|
element.mozFullScreenElement && element.mozFullScreenElement !== null ||
|
||||||
element.msFullscreenElement && element.msFullscreenElement !== null;
|
element.msFullscreenElement && element.msFullscreenElement !== null;
|
||||||
console.log(`onFullscreenChange(${ isInFullScreen })`);
|
console.log(`onFullscreenChange(${isInFullScreen})`);
|
||||||
this.isFullScreen = isInFullScreen;
|
this.isFullScreen = isInFullScreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,12 +576,12 @@ export class VideoScene implements OnInit {
|
|||||||
this.startHideTimer();
|
this.startHideTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
onVolume(newValue:any) {
|
onVolume(newValue: any) {
|
||||||
console.log(`onVolume ${ newValue.value}`);
|
console.log(`onVolume ${newValue.value}`);
|
||||||
this.startHideTimer();
|
this.startHideTimer();
|
||||||
if(this.videoPlayer === null ||
|
if (this.videoPlayer === null ||
|
||||||
this.videoPlayer === undefined) {
|
this.videoPlayer === undefined) {
|
||||||
console.log(`error element: ${ this.videoPlayer}`);
|
console.log(`error element: ${this.videoPlayer}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.volumeValue = newValue.value;
|
this.volumeValue = newValue.value;
|
||||||
@ -520,9 +591,9 @@ export class VideoScene implements OnInit {
|
|||||||
|
|
||||||
onVolumeMute() {
|
onVolumeMute() {
|
||||||
this.startHideTimer();
|
this.startHideTimer();
|
||||||
if(this.videoPlayer === null ||
|
if (this.videoPlayer === null ||
|
||||||
this.videoPlayer === undefined) {
|
this.videoPlayer === undefined) {
|
||||||
console.log(`error element: ${ this.videoPlayer}`);
|
console.log(`error element: ${this.videoPlayer}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.videoPlayer.muted = true;
|
this.videoPlayer.muted = true;
|
||||||
@ -530,9 +601,9 @@ export class VideoScene implements OnInit {
|
|||||||
|
|
||||||
onVolumeUnMute() {
|
onVolumeUnMute() {
|
||||||
this.startHideTimer();
|
this.startHideTimer();
|
||||||
if(this.videoPlayer === null ||
|
if (this.videoPlayer === null ||
|
||||||
this.videoPlayer === undefined) {
|
this.videoPlayer === undefined) {
|
||||||
console.log(`error element: ${ this.videoPlayer}`);
|
console.log(`error element: ${this.videoPlayer}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.videoPlayer.muted = false;
|
this.videoPlayer.muted = false;
|
||||||
|
96
front/src/app/service/GenericInterfaceModelDBv2.ts
Normal file
96
front/src/app/service/GenericInterfaceModelDBv2.ts
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
import { isNodeData, NodeData } from "common/model";
|
||||||
|
import { HttpWrapperService, BddService } from "common/service";
|
||||||
|
import { DataInterface, isArrayOf, isNullOrUndefined, TypeCheck } from "common/utils";
|
||||||
|
|
||||||
|
export class GenericInterfaceModelDBv2<TYPE> {
|
||||||
|
constructor(
|
||||||
|
protected serviceName: string,
|
||||||
|
protected http: HttpWrapperService,
|
||||||
|
protected bdd: BddService,
|
||||||
|
protected checker: (subData: any) => subData is TYPE) {
|
||||||
|
// nothing to do ...
|
||||||
|
}
|
||||||
|
|
||||||
|
gets(): Promise<TYPE[]> {
|
||||||
|
let self = this;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
self.bdd.get(self.serviceName)
|
||||||
|
.then((response: DataInterface) => {
|
||||||
|
let data = response.gets();
|
||||||
|
if (isNullOrUndefined(data)) {
|
||||||
|
reject('Data does not exist in the local BDD');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (isArrayOf<TYPE>(data, this.checker)) {
|
||||||
|
resolve(data);
|
||||||
|
} else {
|
||||||
|
reject("The data is not an array of the correct type ...");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}).catch((response) => {
|
||||||
|
reject(response);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
get(id: number): Promise<TYPE> {
|
||||||
|
let self = this;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
self.bdd.get(self.serviceName)
|
||||||
|
.then((response: DataInterface) => {
|
||||||
|
let data = response.get(id);
|
||||||
|
if (isNullOrUndefined(data)) {
|
||||||
|
reject('Data does not exist in the local BDD');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.checker(data)) {
|
||||||
|
resolve(data);
|
||||||
|
} else {
|
||||||
|
reject("The data is not an array of the correct type ...");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}).catch((response) => {
|
||||||
|
reject(response);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getFilter(filter: (subData: any) => boolean): Promise<TYPE[]> {
|
||||||
|
let self = this;
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
self.bdd.get(self.serviceName)
|
||||||
|
.then((response: DataInterface) => {
|
||||||
|
let data = response.gets();
|
||||||
|
if (isNullOrUndefined(data)) {
|
||||||
|
reject('Data does not exist in the local BDD');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let out = [];
|
||||||
|
for (const elem of data) {
|
||||||
|
if (filter(elem)) {
|
||||||
|
out.push(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve(out as TYPE[]);
|
||||||
|
return;
|
||||||
|
}).catch((response) => {
|
||||||
|
reject(response);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
insert(data: object): TYPE {
|
||||||
|
let ret = this.http.postSpecific([this.serviceName], data);
|
||||||
|
return this.bdd.addAfterPost(this.serviceName, ret) as TYPE;
|
||||||
|
|
||||||
|
}
|
||||||
|
put(id: number, data: object): TYPE {
|
||||||
|
let ret = this.http.putSpecific([this.serviceName, id], data);
|
||||||
|
return this.bdd.setAfterPut(this.serviceName, id, ret) as TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(id: number): TYPE {
|
||||||
|
let ret = this.http.deleteSpecific([this.serviceName, id]);
|
||||||
|
return this.bdd.delete(this.serviceName, id, ret) as TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
39
front/src/app/service/advancement.ts
Normal file
39
front/src/app/service/advancement.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2018, Edouard DUPIN, all right reserved
|
||||||
|
* @license PROPRIETARY (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
|
||||||
|
import { HttpWrapperService, BddService } from 'common/service';
|
||||||
|
import { isUserMediaAdvancement, UserMediaAdvancement } from 'app/model/user-media-advancement';
|
||||||
|
import { GenericInterfaceModelDBv2 } from './GenericInterfaceModelDBv2';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AdvancementService extends GenericInterfaceModelDBv2<UserMediaAdvancement> {
|
||||||
|
|
||||||
|
constructor(http: HttpWrapperService,
|
||||||
|
bdd: BddService) {
|
||||||
|
super('advancement', http, bdd, isUserMediaAdvancement);
|
||||||
|
}
|
||||||
|
get(id: number): Promise<UserMediaAdvancement> {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
super.getFilter((data: any) => { return data.mediaId == id }).then((data: UserMediaAdvancement[]) => {
|
||||||
|
resolve(data[0]);
|
||||||
|
return;
|
||||||
|
}).catch((reason: any) => {
|
||||||
|
reject(reason);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
updateTime(id: number, time: number, total: number, addCount: boolean) {
|
||||||
|
this.put(id, {
|
||||||
|
time: time,
|
||||||
|
percent: time / total,
|
||||||
|
addCount: addCount
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,4 @@
|
|||||||
|
import { AdvancementService } from "./advancement";
|
||||||
import { ArianeService } from "./ariane";
|
import { ArianeService } from "./ariane";
|
||||||
import { DataService } from "./data";
|
import { DataService } from "./data";
|
||||||
import { SeasonService } from "./season";
|
import { SeasonService } from "./season";
|
||||||
@ -14,6 +15,7 @@ export {
|
|||||||
SeriesService,
|
SeriesService,
|
||||||
TypeService,
|
TypeService,
|
||||||
VideoService,
|
VideoService,
|
||||||
|
AdvancementService
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 9fc25b4feaeba509ff39f70b24d97be47f4b30e1
|
Subproject commit ea5a4f6b7537eb707916f4610bf79fbe86c6296f
|
Loading…
Reference in New Issue
Block a user