Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block Editor: Allow users to insert videos from external sources#23861 #24409

Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@
.horizontal-video,
.node-image {
height: auto;
width: 50%;
max-width: 50%;
}

.node-container {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
/>
</div>
<div class="footer">
<span class="error-message" [class.hide]="!form.controls['url'].invalid || form.pristine"
>Enter a valid url</span
>
<button [disabled]="form.invalid" type="submit" pButton>Insert</button>
<span
class="error-message"
[innerHTML]="error || 'Enter a valid url'"
[class.hide]="!isInvalid || form.pristine"
></span>
<button [disabled]="form.invalid || disableAction" type="submit" pButton>Insert</button>
</div>
</form>
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
color: $red;
font-size: $font-size-small;
text-align: left;
max-width: 30rem;
}

.hide {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,15 @@ import {
Output,
ViewChild,
ElementRef,
Input
Input,
ChangeDetectorRef
} from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

import { EditorAssetTypes } from '@dotcms/dotcms-models';

import { handleLoadVideoError } from './utils';

const regexURL =
'^((http|https)://)[-a-zA-Z0-9@:%._\\+~#?&//=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%._\\+~#?&//=]*)$';

Expand All @@ -28,16 +31,33 @@ export class DotExternalAssetComponent {
type: EditorAssetTypes;

form: FormGroup;
disableAction = false;

get placerHolder() {
get placerHolder(): string {
return `https://example.com/${this.type === 'video' ? 'video.mp4' : 'image.jpg'}`;
}

constructor(private fb: FormBuilder) {
get error(): string {
return this.form.controls.url?.errors?.message || '';
}

get isInvalid(): boolean {
return this.form.controls.url?.invalid;
}

constructor(private fb: FormBuilder, private cd: ChangeDetectorRef) {
this.form = this.fb.group({
url: ['', [Validators.required, Validators.pattern(regexURL)]]
});

this.form.valueChanges.subscribe(({ url }) => {
if (this.type === 'video' && !this.isInvalid) {
this.tryToPlayVideo(url);

return;
}
});

requestAnimationFrame(() => this.input.nativeElement.focus());
}

Expand All @@ -50,4 +70,29 @@ export class DotExternalAssetComponent {
onSubmit({ url }: { url: string }) {
this.addAsset.emit(url);
}

/**
*
* Try to play a video by url but if it fails return the error
* @private
* @param {string} url
* @memberof DotExternalAssetComponent
*/
private tryToPlayVideo(url: string): void {
const video = document.createElement('video') as HTMLVideoElement;

this.disableAction = true;

video.addEventListener('error', (e) => {
this.form.controls.url.setErrors({ message: handleLoadVideoError(e) });
this.cd.detectChanges();
});

video.addEventListener('canplay', () => {
this.form.controls.url.setErrors(null);
this.disableAction = false;
this.cd.detectChanges();
});
video.src = `${url}#t=0.1`;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* Handle the error of the video
*
* @param {*} e
* @return {*} {string}
*/
export const handleLoadVideoError = (e): string => {
switch (e.target.error.code) {
case e.target.error.MEDIA_ERR_ABORTED:
return 'You aborted the video playback.';

case e.target.error.MEDIA_ERR_NETWORK:
return 'A network error caused the video download to fail part-way.';

case e.target.error.MEDIA_ERR_DECODE:
return 'Video playback aborted due to browser compatibility issues. Try a different browser or visit <a href="https://developer.mozilla.org/en-US/docs/Web/Media/Formats#media_file_types_and_codecs">MDN Video Support</a> for more information.';

case e.target.error.MEDIA_ERR_SRC_NOT_SUPPORTED:
return 'Invalid URL. Please provide a URL to a .mp4, .webm, or .ogv video file. For more info, visit: <a href="https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Containers#common_container_formats" target="_blank">MDN Video Format Support</a>';

default:
return 'An unknown error occurred. <a href="https://www.dotcms.com/services/support/" target="_blank">Please contact support</a>';
}
};
2 changes: 1 addition & 1 deletion dotCMS/src/main/webapp/html/dotcms-block-editor.js

Large diffs are not rendered by default.