Files
xTestFrameworkClient/src/app/views/files/v-media/v-media.component.ts
T

644 lines
14 KiB
TypeScript

import {
isImage,
isVideo,
isAudio,
XFileBlob,
isValidURL,
isDocument,
isFunction,
isXFileBlob,
nameofInstance,
isNullOrUndefined,
isNullOrEmptyString,
XResourceIdentifier,
XColorIdentifier,
} from 'x-framework-core';
import {
MediaType,
toMediaType,
MediaSourceType,
isMediaTypePassed,
VMediaPresentType,
getMediaSourceType,
isVMediaPresentType,
MediaSourceInputType,
isVMediaPresentTypePassed,
VMediaPresentTypeIdentifier,
} from './v-media.typings';
import {
XSlotName,
XIconNames,
XSlotLayout,
XButtonType,
XIconIdentifier,
} from 'x-framework-components';
import { XFileDto } from 'x-saherelm-api-sdk';
import { Component, Input } from '@angular/core';
import { SafeUrl } from '@angular/platform-browser';
import { FileLocalizationsResourceIDs } from '../v-file.configs';
import { VBaseInCardComponent } from '../../classes/v-base.component';
import { XSimpleListItemSlideOption } from '../../typings/simple.list-item.typings';
@Component({
selector: 'v-media',
templateUrl: './v-media.component.html',
styleUrls: ['./v-media.component.scss'],
})
export class VMediaComponent extends VBaseInCardComponent {
//
//#region Props ...
//
readonly SlotNames = Object.assign({}, XSlotName);
readonly ButtonTypes = Object.assign({}, XButtonType);
readonly SlotLayouts = Object.assign({}, XSlotLayout);
readonly MediaPresentTypes = Object.assign({}, VMediaPresentType);
/**
* Provided Source for Presenting ...
*/
@Input()
src: MediaSourceInputType = undefined;
/**
* CSS Classes names to Attach ...
*/
@Input()
cssClass: Array<string> = [];
/**
* Force to Use Thumbnails Paths if Provided XFileDto source ...
*/
@Input()
useThumbnailsIfProvided: boolean = true;
/**
* Specify How to Represent Component ...
*/
@Input()
presentType: VMediaPresentTypeIdentifier = VMediaPresentType.AsCard;
/**
* Thumbnail Provided Icon's Color ...
*/
@Input()
thumbnailIconColor: XColorIdentifier = this.ColorNames.TertiaryShade;
/**
* Provides Thumbnails Icon for Use if necessary ...
*
* @param type
* @returns
*/
@Input()
thumbnailIconProvider: (type: MediaType) => XIconIdentifier = (type) => {
//
let result: XIconIdentifier = undefined;
//
if (isMediaTypePassed(type)) {
//
switch (type) {
//
case MediaType.Image:
result = XIconNames.image;
break;
//
case MediaType.Video:
result = XIconNames.video;
break;
//
case MediaType.Audio:
result = XIconNames.audio;
break;
//
case MediaType.Document:
result = XIconNames.document;
break;
}
}
//
return result;
};
/**
* Provides Thumbnail Title for Use if necessary ...
* @param type
* @returns
*/
@Input()
thumbnailTitleProvider: (type: MediaType) => XResourceIdentifier = (type) => {
//
let result: XResourceIdentifier = undefined;
//
if (isMediaTypePassed(type)) {
//
switch (type) {
//
case MediaType.Image:
result = FileLocalizationsResourceIDs.image;
break;
//
case MediaType.Video:
result = FileLocalizationsResourceIDs.video;
break;
//
case MediaType.Audio:
result = FileLocalizationsResourceIDs.audio;
break;
//
case MediaType.Document:
result = FileLocalizationsResourceIDs.document;
break;
}
}
//
return result;
};
/**
* Provided Actions which Used only in Card Present Type ...
*/
@Input()
providedActions: Array<XSimpleListItemSlideOption> = [];
//
// Required Fields For Describe Media ...
//
url: string = undefined;
info: string = undefined;
type: MediaType = undefined;
safeUrl: SafeUrl = undefined;
inputType: MediaSourceType = undefined;
//
thumbnailUrl: string = undefined;
thumbnailSafeUrl: SafeUrl = undefined;
thumbnailIcon: XIconIdentifier = undefined;
thumbnailTitle: XResourceIdentifier = undefined;
//#endregion
//
//#region LifeCycles ...
afterViewInit(): void {
super.afterViewInit();
//
this.handlePrepareSource();
}
onChange(changeKeys: string[]): void {
super.onChange(changeKeys);
//
let isChanged = false;
let applyChnages = false;
//
// Providers Change ...
isChanged =
changeKeys.includes(nameofInstance(this, 'thumbnailIconProvider')) ||
changeKeys.includes(nameofInstance(this, 'thumbnailTitleProvider'));
if (isChanged) {
//
// Icon ...
if (
isNullOrUndefined(this.thumbnailIconProvider) ||
!isFunction(this.thumbnailIconProvider)
) {
//
this.thumbnailIconProvider = (type) => {
//
let result: XIconIdentifier = undefined;
//
if (isMediaTypePassed(type)) {
//
switch (type) {
//
case MediaType.Image:
result = XIconNames.image;
break;
//
case MediaType.Video:
result = XIconNames.video;
break;
//
case MediaType.Audio:
result = XIconNames.audio;
break;
//
case MediaType.Document:
result = XIconNames.document;
break;
}
}
//
return result;
};
}
//
// Title ...
if (
isNullOrUndefined(this.thumbnailTitleProvider) ||
!isFunction(this.thumbnailTitleProvider)
) {
//
this.thumbnailTitleProvider = (type) => {
//
let result: XResourceIdentifier = undefined;
//
if (isMediaTypePassed(type)) {
//
switch (type) {
//
case MediaType.Image:
result = FileLocalizationsResourceIDs.image;
break;
//
case MediaType.Video:
result = FileLocalizationsResourceIDs.video;
break;
//
case MediaType.Audio:
result = FileLocalizationsResourceIDs.audio;
break;
//
case MediaType.Document:
result = FileLocalizationsResourceIDs.document;
break;
}
}
//
return result;
};
}
//
applyChnages = true;
this.thumbnailIcon = this.thumbnailIconProvider(this.type);
this.thumbnailTitle = this.thumbnailTitleProvider(this.type);
}
//
// Source Change ...
isChanged = changeKeys.includes(nameofInstance(this, 'src'));
if (isChanged) {
this.handlePrepareSource();
}
//
// PresentType Change ...
isChanged = changeKeys.includes(nameofInstance(this, 'presentType'));
if (isChanged) {
//
if (
isNullOrUndefined(this.presentType) ||
!isVMediaPresentType(this.presentType)
) {
//
applyChnages = true;
this.presentType = VMediaPresentType.AsCard;
}
//
this.setAttribute(nameofInstance(this, 'presentType'), this.presentType);
}
//
// Provided Actions ...
isChanged = changeKeys.includes(nameofInstance(this, 'providedActions'));
if (isChanged) {
//
if (isNullOrUndefined(this.providedActions)) {
//
applyChnages = true;
this.providedActions = [];
}
}
//
// Thumbnail Icon Color ...
isChanged = changeKeys.includes(nameofInstance(this, 'thumbnailIconColor'));
if (isChanged) {
//
if (isNullOrEmptyString(this.thumbnailIconColor)) {
//
applyChnages = true;
this.thumbnailIconColor = this.ColorNames.TertiaryShade;
}
}
//
if (applyChnages) {
this.detectChanges();
}
}
//#endregion
//
//#region Providers ...
/**
* Check Present Type is Allow Component Presenting ...
*
* @returns
*/
canPresent() {
return isVMediaPresentTypePassed(this.presentType);
}
/**
* Check Conditions For Thumbnail Present Type ...
*/
canShowAsThumbnail() {
return (
!isNullOrUndefined(this.thumbnailIcon) &&
!isNullOrUndefined(this.thumbnailTitle)
);
}
/**
* Check Provided Actions ...
*/
hasActions() {
return (
!isNullOrUndefined(this.providedActions) &&
this.hasChild(this.providedActions)
);
}
//#endregion
//
//#region Handlers ...
/**
* Prepare Source and Parse data ...
*
* @returns
*/
handlePrepareSource() {
//
// Validate ...
if (isNullOrUndefined(this.src)) {
return;
}
//
// Detect Input Type ...
this.inputType = getMediaSourceType(this.src);
switch (this.inputType) {
//
case MediaSourceType.Url:
this.handlePrepareUrlSource();
break;
//
case MediaSourceType.File:
this.handlePrepareFileSource();
break;
//
case MediaSourceType.Blob:
case MediaSourceType.XFileBlob:
this.handlePrepareBlobSource();
break;
//
case MediaSourceType.XFileDto:
this.handlePrepareDtoSource();
break;
}
//
// Preparing Thumbnail Info ...
this.thumbnailIcon = this.thumbnailIconProvider(this.type);
this.thumbnailTitle = this.thumbnailTitleProvider(this.type);
//
// Detect Thumbnail URL ...
if (this.type === MediaType.Image) {
//
if (this.inputType === MediaSourceType.XFileDto) {
//
const value = this.src as XFileDto;
this.thumbnailUrl = !isNullOrEmptyString(value.thumbPath)
? value.thumbPath
: value.path;
} else {
this.thumbnailUrl = this.url;
}
//
if (isNullOrUndefined(this.thumbnailUrl)) {
this.thumbnailUrl = undefined;
}
//
if (!isNullOrUndefined(this.safeUrl) && isNullOrEmptyString(this.url)) {
//
this.thumbnailUrl = undefined;
this.thumbnailSafeUrl = this.safeUrl;
}
}
}
/**
* Calling Action Handler ...
*
* @param action
* @returns
*/
async handleCallingActionHandler(action: XSimpleListItemSlideOption) {
//
// Validate ...
if (isNullOrUndefined(action)) {
return;
}
//
// Validate Handler Exists ...
if (isNullOrUndefined(action.handler) && !isFunction(action.handler)) {
return;
}
//
// Calling Action Handler ...
await this.getValuesAsync(action.handler(this.src));
}
//#endregion
//
//#region Private ...
/**
* Set Thumbnail Size ...
*
* @param size
*/
private handleSetThumbnailSize(size: number) {
//
if (size < 32) {
size = 32;
}
//
const name = 'thumbnail-size';
const value = `${size}px;`;
//
this.setCssVar(name, value);
this.setCssVar(name, value, document.documentElement);
}
/**
* Extract required data when user provides string as source ...
*/
private handlePrepareUrlSource() {
//
let value = this.src as string;
//
// Detecting Type ...
this.detectType(value);
//
// Assign URL if has a Valid Url ...
this.url = value;
//
if (isValidURL(value)) {
//
this.info = value;
}
//
this.safeUrl = undefined;
this.thumbnailSafeUrl = undefined;
}
/**
* Extract required data when user provides XFileDto as source ...
*/
private handlePrepareDtoSource() {
//
let value = this.src as XFileDto;
//
// Validate ...
if (isNullOrUndefined(value) || isNullOrEmptyString(value.id)) {
return;
}
//
// Detecting Type ...
this.detectType(value);
//
// Check Can User Thumbnail ...
if (this.useThumbnailsIfProvided && !isNullOrEmptyString(value.thumbPath)) {
this.url = value.thumbPath;
} else if (!isNullOrEmptyString(value.path)) {
this.url = value.path;
}
//
this.safeUrl = undefined;
this.thumbnailSafeUrl = undefined;
this.info = value.name || value.path || value.thumb || value.thumbPath;
}
/**
* Extract required data when user provides Blob as source ...
*/
private handlePrepareBlobSource() {
//
// Blob ...
if (this.src instanceof Blob) {
//
let value = this.src as Blob;
this.url = undefined;
this.detectType(value);
this.safeUrl =
this.sharedService.managerService.securityService.toSafeURL(
URL.createObjectURL(value),
);
} else if (isXFileBlob(this.src)) {
//
let value = this.src as XFileBlob;
this.detectType(value);
this.url = value.name;
this.info = value.name;
this.safeUrl = undefined;
}
}
/**
* Extract required data when user provides File as source ...
*/
private handlePrepareFileSource() {
//
let value = this.src as File;
//
this.detectType(value);
this.url = undefined;
this.safeUrl = this.sharedService.managerService.securityService.toSafeURL(
URL.createObjectURL(value),
);
this.info = value.name;
}
/**
* Detect Media Type based on Identifier ...
*
* @param identifier
* @returns
*/
private detectType(identifier: XFileDto | File | Blob | XFileBlob | string) {
//
let result: MediaType = MediaType.None;
//
// Validate ...
if (!isNullOrUndefined(identifier)) {
//
if (this.inputType === MediaSourceType.XFileDto) {
this.type = toMediaType((identifier as XFileDto).type);
} else {
//
if (isImage(identifier as any)) {
this.type = MediaType.Image;
} else if (isVideo(identifier as any)) {
this.type = MediaType.Video;
} else if (isAudio(identifier as any)) {
this.type = MediaType.Audio;
} else if (isDocument(identifier as any)) {
this.type = MediaType.Document;
}
}
}
//
return result;
}
//#endregion
}