diff --git a/vocodes/public/image-thumbnails/bill-gates.jpg b/vocodes/public/image-thumbnails/bill-gates.jpg new file mode 100644 index 0000000000..3697332061 Binary files /dev/null and b/vocodes/public/image-thumbnails/bill-gates.jpg differ diff --git a/vocodes/public/image-thumbnails/elon-musk.jpg b/vocodes/public/image-thumbnails/elon-musk.jpg new file mode 100644 index 0000000000..aa48d6671e Binary files /dev/null and b/vocodes/public/image-thumbnails/elon-musk.jpg differ diff --git a/vocodes/public/image-thumbnails/hillary-clinton-laugh.jpg b/vocodes/public/image-thumbnails/hillary-clinton-laugh.jpg new file mode 100644 index 0000000000..eaf9648bfe Binary files /dev/null and b/vocodes/public/image-thumbnails/hillary-clinton-laugh.jpg differ diff --git a/vocodes/public/image-thumbnails/markiplier.jpg b/vocodes/public/image-thumbnails/markiplier.jpg new file mode 100644 index 0000000000..3b4da04e7d Binary files /dev/null and b/vocodes/public/image-thumbnails/markiplier.jpg differ diff --git a/vocodes/public/image-thumbnails/solid-snake.jpg b/vocodes/public/image-thumbnails/solid-snake.jpg new file mode 100644 index 0000000000..b56bf7d7f0 Binary files /dev/null and b/vocodes/public/image-thumbnails/solid-snake.jpg differ diff --git a/vocodes/public/image-thumbnails/sonic-movie.jpg b/vocodes/public/image-thumbnails/sonic-movie.jpg new file mode 100644 index 0000000000..91ddab0591 Binary files /dev/null and b/vocodes/public/image-thumbnails/sonic-movie.jpg differ diff --git a/vocodes/src/modes/video/ImageTemplates.ts b/vocodes/src/modes/video/ImageTemplates.ts new file mode 100644 index 0000000000..ed0030a3ba --- /dev/null +++ b/vocodes/src/modes/video/ImageTemplates.ts @@ -0,0 +1,64 @@ + +class ImageTemplate { + name: string; + slug: string; + thumbnail: string; + + constructor( + name: string, + slug: string, + thumbnail: string, + ) { + this.name = name; + this.slug = slug; + this.thumbnail = thumbnail; + } + + static fromJson(json: any) : ImageTemplate { + return new ImageTemplate( + json.name, + json.slug, + json.thumbnail, + ); + } + + getThumbnailUrl() : string { + return `/image-thumbnails/${this.thumbnail}`; + } +} + + +const IMAGE_TEMPLATES : ImageTemplate[] = [ + ImageTemplate.fromJson({ + name: "Bill Gates", + slug: "bill-gates.jpg", + thumbnail: "bill-gates.jpg", + }), + ImageTemplate.fromJson({ + name: "Elon Musk", + slug: "elon-musk.jpg", + thumbnail: "elon-musk.jpg", + }), + ImageTemplate.fromJson({ + name: "Hillary Clinton", + slug: "hillary-clinton-laugh.jpg", + thumbnail: "hillary-clinton-laugh.jpg", + }), + ImageTemplate.fromJson({ + name: "Markiplier", + slug: "markiplier.jpg", + thumbnail: "markiplier.jpg", + }), + ImageTemplate.fromJson({ + name: "Solid Snake", + slug: "solid-snake.jpg", + thumbnail: "solid-snake.jpg", + }), + ImageTemplate.fromJson({ + name: "Sonic", + slug: "sonic-movie.jpg", + thumbnail: "sonic-movie.jpg", + }), +]; + +export { ImageTemplate, IMAGE_TEMPLATES } diff --git a/vocodes/src/modes/video/VideoComponent.tsx b/vocodes/src/modes/video/VideoComponent.tsx index 0f2a5f91c1..396c1b9368 100644 --- a/vocodes/src/modes/video/VideoComponent.tsx +++ b/vocodes/src/modes/video/VideoComponent.tsx @@ -4,6 +4,7 @@ import axios from 'axios'; import { VideoJob, VideoJobStatus } from './VideoJob'; import { VideoQueuePoller } from './VideoQueuePoller'; import { VideoQueueStats } from './VideoQueueStats'; +import { IMAGE_TEMPLATES, ImageTemplate } from './ImageTemplates'; interface Props { currentVideoJob?: VideoJob, @@ -17,7 +18,8 @@ interface Props { interface State { // Before upload audioFile?: File, - selectedVideoTemplate: VideoTemplate, + selectedVideoTemplate?: VideoTemplate, + selectedImageTemplate?: ImageTemplate, // After upload jobUuid?: string, } @@ -30,6 +32,7 @@ class VideoComponent extends React.Component { // Before upload audioFile: undefined, selectedVideoTemplate: VIDEO_TEMPLATES[0], + selectedImageTemplate: undefined, // After upload jobUuid: undefined, }; @@ -62,9 +65,18 @@ class VideoComponent extends React.Component { selectVideoTemplate = (videoTemplate: VideoTemplate) => { this.setState({ selectedVideoTemplate: videoTemplate, + selectedImageTemplate: undefined, }); } + selectImageTemplate = (imageTemplate: ImageTemplate) => { + this.setState({ + selectedImageTemplate: imageTemplate, + selectedVideoTemplate: undefined, + }); + } + + handleFormSubmit = (ev: React.FormEvent) : boolean => { ev.preventDefault(); @@ -74,7 +86,14 @@ class VideoComponent extends React.Component { let formData = new FormData(); formData.append('audio', this.state.audioFile!); - formData.append('video-template', this.state.selectedVideoTemplate.slug); + + if (this.state.selectedVideoTemplate !== undefined) { + formData.append('video-template', this.state.selectedVideoTemplate.slug); + } + + if (this.state.selectedImageTemplate !== undefined) { + formData.append('image-template', this.state.selectedImageTemplate.slug); + } // NB: Using 'axios' because 'fetch' was having problems with form-multipart // and then interpreting the resultant JSON. Maybe I didn't try hard enough? @@ -106,12 +125,37 @@ class VideoComponent extends React.Component { return false; } - public render() { - let thumbnails : any[] = []; + public getImageThumbnails() : any[] { + let imageThumbnails : any[] = []; + let selectedTemplateSlug = this.state.selectedImageTemplate?.slug || ''; + + IMAGE_TEMPLATES.forEach(imageTemplate => { + let selectedName = ''; + if (selectedTemplateSlug === imageTemplate.slug) { + selectedName = 'selected'; + } + let className = `video-thumbnail ${selectedName}` + let thumbnail = this.selectImageTemplate(imageTemplate) } + alt={imageTemplate.name} + /> + + imageThumbnails.push(thumbnail); + }); + + return imageThumbnails; + } + + public getVideoThumbnails() : any[] { + let videoThumbnails : any[] = []; + let selectedTemplateSlug = this.state.selectedVideoTemplate?.slug || ''; VIDEO_TEMPLATES.forEach(videoTemplate => { let selectedName = ''; - if (this.state.selectedVideoTemplate.slug === videoTemplate.slug) { + if (selectedTemplateSlug === videoTemplate.slug) { selectedName = 'selected'; } let className = `video-thumbnail ${selectedName}` @@ -123,9 +167,16 @@ class VideoComponent extends React.Component { alt={videoTemplate.name} /> - thumbnails.push(thumbnail); + videoThumbnails.push(thumbnail); }); + return videoThumbnails; + } + + public render() { + let imageThumbnails = this.getImageThumbnails(); + let videoThumbnails = this.getVideoThumbnails(); + let audioFilename = '(select a file)'; if (this.state.audioFile !== undefined) { @@ -246,8 +297,14 @@ class VideoComponent extends React.Component { +

Video Templates

- {thumbnails.map(v => v)} + {videoThumbnails.map(v => v)} +
+ +

Image Templates

+
+ {imageThumbnails.map(v => v)}