import { Injectable } from '@angular/core' ; import { Attachment } from './attachment.service' ; import { ConfigsService } from '../../../common/services/configs.service' ; import { Session } from '../../../services/session' ; const DEFAULT_MAX_LENGTH = 1260 ; const DEFAULT_MAX_LENGTH_PLUS = 5700 ; const DEFAULT_MAX_FILE_SIZE = 4294967296 ; export type AttachmentValidationFailureCode = 'Video:MaxLengthExceeded' | 'Video:MaxSizeExceeded' ; export type AttachmentValidationPayload = { isValid : boolean ; codes ? : [ AttachmentValidationFailureCode ] | any [ ] ; message ? : string ; maxFileSize ? : number ; maxLength ? : number ; maxLengthPlus ? : number ; } | null ; /**
 * Validates a given attachment's filesize and duration.
 */ @ Injectable ( { providedIn : 'root' } ) export class AttachmentValidatorService { private readonly maxLength ; private readonly maxLengthPlus ; private readonly maxFileSize ; constructor ( private session , config ) { this . maxLength = config . get ( 'max_video_length' ) ?? DEFAULT_MAX_LENGTH ; this . maxLengthPlus = config . get ( 'max_video_length_plus' ) ?? DEFAULT_MAX_LENGTH_PLUS ; this . maxFileSize = config . get ( 'max_video_file_size' ) ?? DEFAULT_MAX_FILE_SIZE ; } param { File | Attachment } returns { Promise < GlobalEventHandlers > } private loadVideo ( file ) { return new Promise ( ( resolve , reject ) => { try { if ( file . type === 'video/x-ms-wmv' ) { throw new Error ( 'Filetype cannot be loaded as a video element' ) ; } let video = document . createElement ( 'video' ) ; video . preload = 'metadata' ; video . onloadedmetadata = function ( ) { resolve ( this ) ; } ; video . onerror = function ( ) { reject ( 'An unknown error has occurred' ) ; } ; video . src = window . URL . createObjectURL ( file ) ; } catch ( e ) { reject ( e ) ; } } ) ; } param { File | Attachment } file returns { Promise < AttachmentValidationPayload > } public async validate ( file ) { if ( ! file || ! file . type ) { return ; } if ( /image\/.+/ . test ( file . type ) ) { return { isValid : true } ; } else if ( /video\/.+/ . test ( file . type ) ) { let payload = { isValid : true , codes : [ ] , maxLength : this . maxLength , maxLengthPlus : this . maxLengthPlus , maxFileSize : this . maxFileSize , } ; if ( ! this . isValidSize ( file ) ) { payload . isValid = false ; payload . codes . push ( 'Video:MaxSizeExceeded' ) ; } let video = null ; try { video = await this . loadVideo ( file ) ; } catch ( e ) { return payload ; } if ( ! this . isValidLength ( video ) ) { payload . isValid = false ; payload . codes . push ( 'Video:MaxLengthExceeded' ) ; } return payload ; } } param video returns { boolean } private isValidLength ( video ) { let maxLength = this . maxLength ; if ( this . session . getLoggedInUser ( ) . plus ) { maxLength = this . maxLengthPlus ; } return ( video as any ) . duration <= maxLength ?? false ; } param file returns { boolean } private isValidSize ( file ) { return file . size && file . size <= this . maxFileSize ; } }