main

mattermost/focalboard

Last updated at: 28/12/2023 01:37

index.tsx

TLDR

This file is a React component that represents a video block in a blocks editor. It contains a Video component that displays a video player and an input field for uploading video files. The component utilizes the octoClient to retrieve a video file's data URL and display it in the player.

Classes

Video

This class represents a video block component in the blocks editor. It has the following properties:

  • name: The name of the block, which is set to 'video'.
  • displayName: The display name of the block, which is set to 'Video'.
  • slashCommand: The slash command associated with the block, which is set to '/video'.
  • prefix: A prefix for the slash command, which is set to an empty string.
  • runSlashCommand: A method that handles the execution of the slash command. However, in the provided code, this method is empty.
  • editable: A boolean value indicating whether the block is editable. In this case, it is set to false.
  • Display: A functional component that renders the video player and displays the video file.
  • Input: A functional component that renders an input field for uploading video files.

END

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React, {useRef, useEffect, useState} from 'react'

import {BlockInputProps, ContentType} from '../types'
import octoClient from '../../../../octoClient'

import './video.scss'

type FileInfo = {
    file: string|File
    filename: string
    width?: number
    align?: 'left'|'center'|'right'
}

const Video: ContentType<FileInfo> = {
    name: 'video',
    displayName: 'Video',
    slashCommand: '/video',
    prefix: '',
    runSlashCommand: (): void => {},
    editable: false,
    Display: (props: BlockInputProps<FileInfo>) => {
        const [videoDataUrl, setVideoDataUrl] = useState<string|null>(null)

        useEffect(() => {
            if (!videoDataUrl) {
                const loadVideo = async () => {
                    if (props.value && props.value.file && typeof props.value.file === 'string') {
                        const fileURL = await octoClient.getFileAsDataUrl(props.currentBoardId || '', props.value.file)
                        setVideoDataUrl(fileURL.url || '')
                    }
                }
                loadVideo()
            }
        }, [props.value, props.value.file, props.currentBoardId])

        if (videoDataUrl) {
            return (
                <video
                    width='320'
                    height='240'
                    controls={true}
                    className='VideoView'
                    data-testid='video'
                >
                    <source src={videoDataUrl}/>
                </video>
            )
        }
        return null
    },
    Input: (props: BlockInputProps<FileInfo>) => {
        const ref = useRef<HTMLInputElement|null>(null)
        useEffect(() => {
            ref.current?.click()
        }, [])

        return (
            <input
                ref={ref}
                className='Video'
                data-testid='video-input'
                type='file'
                accept='video/*'
                onChange={(e) => {
                    const file = (e.currentTarget?.files || [])[0]
                    props.onSave({file, filename: file.name})
                }}
            />
        )
    },
}

Video.runSlashCommand = (changeType: (contentType: ContentType<FileInfo>) => void, changeValue: (value: FileInfo) => void): void => {
    changeType(Video)
    changeValue({} as any)
}

export default Video