@fortawesome/free-solid-svg-icons#faDownload JavaScript Examples

The following examples show how to use @fortawesome/free-solid-svg-icons#faDownload. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Buttons.jsx    From signdocs with MIT License 6 votes vote down vote up
DownloadButton = ({ downloadUrl, status }) => (
  <a
    href={downloadUrl}
    download
    className="inline-link"
    aria-label="Download this document"
  >
    <FontAwesomeIcon icon={faDownload} color="inherit" title="Download" />
    &nbsp;&nbsp;{status === 'Final' ? 'Download Final' : 'Download'}
  </a>
)
Example #2
Source File: index.js    From Artion-Client with GNU General Public License v3.0 5 votes vote down vote up
DownloadIcon = (
  <FontAwesomeIcon icon={faDownload} color="#007bff" />
)
Example #3
Source File: fontawesome.js    From xmrig-workers with GNU General Public License v3.0 5 votes vote down vote up
export default function () {
  library.add(faGithub, faWindows, faLinux, faTwitter, faReddit, faTelegram, faCheckCircle, faMicrochip, faTrashAlt,
    faPaperPlane, faSpinner, faFlask, faInfoCircle, faPen, faTools, faCheck, faPlus, faCog, faExclamationTriangle,
    faQuestionCircle, faSyncAlt, faInfinity, faDownload, faCopy, faPlug, faTimesCircle);
}
Example #4
Source File: Index.js    From Easy-Annotator with GNU General Public License v3.0 4 votes vote down vote up
render() {
    const { listrois, selected } = this.state;
    return (
      <ThemeProvider theme={this.state.currentTheme}>
        <Layout>
          <Header>
            <Select
              id="theme"
              name="theme"
              defaultValue={this.state.currentTheme}
              sx={{
                px: 2,
                mx: 2,
              }}
              onChange={(e) => {
                console.log(e.target.value);
                this.setState({
                  currentTheme: presets[e.target.value],
                });
                cookie.save("theme", presets[e.target.value], { path: "/" });
              }}
            >
              {Object.keys(presets).map((key) => (
                <option
                  sx={{ bg: "background" }}
                  key={key}
                  children={key}
                ></option>
              ))}
            </Select>
            <VideoUploadForm refresh={this.refreshCanvas} />
          </Header>
          <Body>
            <Content>
              <Canvas
                ref={this.canvasRef}
                listrois={listrois}
                addNewRoi={this.addNewRoi}
                onFPSCallback={this.onFPSCallback}
                onDurationCallback={this.onDurationCallback}
                onTrackingCallback={this.onTrackingCallback}
                selected={selected}
                disableRois={this.disableRois}
              />
            </Content>

            <Panel>
              <Flex>
                <Box width={1 / 2} mx={2}>
                  <Menu id="dropdown-roi">
                    <MenuButton
                      sx={{
                        bg: "primary",
                        my: 2,
                        color: "background",
                        border: "0",
                        "&:hover": {
                          bg: "highlight",
                          border: "0",
                        },
                        "&:visited": {
                          bg: "primary",
                        },
                        "&:active": {
                          bg: "primary",
                        },
                        "&:visited": {
                          bg: "primary",
                        },
                      }}
                    >
                      <FontAwesomeIcon icon={faPen} />
                      <span aria-hidden>â–¾</span>
                    </MenuButton>
                    <MenuList
                      className="slide-down"
                      sx={{
                        "&[data-reach-menu-items]": {
                          color: "background",
                          bg: "primary",
                          border: "0",
                          borderRadius: 4,
                          animation: "slide-down 0.2s ease",
                        },
                      }}
                    >
                      <MenuItem
                        onSelect={() =>
                          this.canvasRef.current.addROI("Benign", false)
                        }
                        sx={styledDropdown}
                      >
                        Benign
                      </MenuItem>
                      <MenuItem
                        onSelect={() =>
                          this.canvasRef.current.addROI("Suspicious", false)
                        }
                        sx={styledDropdown}
                      >
                        Suspicious
                      </MenuItem>
                      <MenuItem
                        onSelect={() =>
                          this.canvasRef.current.addROI("Cancerous", false)
                        }
                        sx={styledDropdown}
                      >
                        Cancerous
                      </MenuItem>
                      <MenuItem
                        onSelect={() =>
                          this.canvasRef.current.addROI("Unknown", false)
                        }
                        sx={styledDropdown}
                      >
                        Unknown
                      </MenuItem>
                      <MenuItem
                        onSelect={() =>
                          this.canvasRef.current.addROI("Custom", true)
                        }
                        sx={styledDropdown}
                      >
                        Custom
                      </MenuItem>
                    </MenuList>
                  </Menu>
                </Box>
                <Button
                  onClick={this.downloadRois}
                  width={1 / 2}
                  mx={2}
                  my={2}
                  ml={5}
                  sx={{
                    color: "background",
                    "&:hover": {
                      bg: "highlight",
                      border: 0,
                    },
                  }}
                >
                  <FontAwesomeIcon icon={faDownload} />
                </Button>
              </Flex>
              <LayerPanel
                listrois={listrois}
                selected={selected}
                onEyeClick={this.onEyeClick}
                setSelected={this.setSelected}
                onDeleteClick={this.deleteRoi}
              />
            </Panel>
          </Body>
          <Footer>© IBM {new Date().getFullYear()}</Footer>
        </Layout>
      </ThemeProvider>
    );
  }
Example #5
Source File: Editor.js    From Reactive with MIT License 4 votes vote down vote up
// https://github.com/ffmpegwasm/ffmpeg.wasm/blob/master/docs/api.md


function Editor({videoUrl, timings, setTimings}) {

	//Boolean state to handle video mute
	const [isMuted, setIsMuted] = useState(false)

	//Boolean state to handle whether video is playing or not
	const [playing, setPlaying] = useState(false)

	//Float integer state to help with trimming duration logic
	const [difference, setDifference] = useState(0.2)

	//Boolean state to handle deleting grabber functionality
	const [deletingGrabber, setDeletingGrabber] = useState(false)

	//State for error handling
	const [currentWarning, setCurrentWarning] = useState(null)

	//State for imageUrl
	const [imageUrl, setImageUrl] = useState('')

	//Boolean state handling trimmed video
	const [trimmingDone, setTrimmingDone] = useState(false)

	//Integer state to blue progress bar as video plays
	const [seekerBar, setSeekerBar] = useState(0)


	//Ref handling metadata needed for trim markers
	const currentlyGrabbedRef = useRef({'index': 0, 'type': 'none'})

	//Ref handling the trimmed video element
	const trimmedVidRef = useRef()

	//Ref handling the initial video element for trimming
	const playVideoRef = useRef()

	//Ref handling the progress bar element
	const progressBarRef = useRef()

	//Ref handling the element of the current play time
	const playBackBarRef = useRef()

	//Variable for error handling on the delete grabber functionality
	const warnings = {'delete_grabber': (<div>Please click on the grabber (either start or end) to delete it</div>)}

	//State handling storing of the trimmed video
	const [trimmedVideo, setTrimmedVideo] = useState()

	//Integer state to handle the progress bars numerical incremation
	const [progress, setProgress] = useState(0)

	//Boolean state handling whether ffmpeg has loaded or not
	const [ready, setReady] = useState(false)

	//Ref to handle the current instance of ffmpeg when loaded
	const ffmpeg = useRef(null)


	//Function handling loading in ffmpeg
	const load = async () => {
		try{
			await ffmpeg.current.load()

			setReady(true)
		}
		catch(error) {
			console.log(error)
		}
	}

	//Loading in ffmpeg when this component renders
	useEffect(() => {
		ffmpeg.current = createFFmpeg({
			log: true,
			corePath: 'https://unpkg.com/@ffmpeg/[email protected]/dist/ffmpeg-core.js'
		})
		load()
	// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [])


	//Lifecycle handling the logic needed for the progress bar - displays the blue bar that grows as the video plays
	// eslint-disable-next-line react-hooks/exhaustive-deps
	useEffect(() => {
		if(playVideoRef.current.onloadedmetadata) {
			const currentIndex = currentlyGrabbedRef.current.index
			const seek = (playVideoRef.current.currentTime - timings[0].start) / playVideoRef.current.duration * 100
			setSeekerBar(seek)
			progressBarRef.current.style.width = `${seekerBar}%`
			if((playVideoRef.current.currentTime >= timings[0].end)) {
				playVideoRef.current.pause()
				setPlaying(false)
				currentlyGrabbedRef.current = ({'index': currentIndex + 1, 'type': 'start'})
				progressBarRef.current.style.width = '0%'
				progressBarRef.current.style.left = `${timings[0].start / playVideoRef.current.duration * 100}%`
				playVideoRef.current.currentTime = timings[0].start
			}
		}

		window.addEventListener('keyup', (event) => {
			if(event.key === ' ') {
				playPause()
			}
		})

		//Handles the start and end metadata for the timings state
		const time = timings
		playVideoRef.current.onloadedmetadata = () => {
			if(time.length === 0) {
				time.push({'start': 0, 'end': playVideoRef.current.duration})
				setTimings(time)
				addActiveSegments()
			}
			else{
				addActiveSegments()
			}
		}
	})

	//Lifecycle that handles removing event listener from the mouse event on trimmer - Desktop browser
	useEffect(() => {
		return window.removeEventListener('mouseup', removeMouseMoveEventListener)
	// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [])

	//Lifecycle that handles removing event listener from the touch/pointer event on trimmer - mobile browser
	useEffect(() => {
		return window.removeEventListener('pointerup', removePointerMoveEventListener)
	// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [])

	//Function handling the trimmer movement logic
	const handleMouseMoveWhenGrabbed = (event) => {
		playVideoRef.current.pause()
		addActiveSegments()
		let playbackRect = playBackBarRef.current.getBoundingClientRect()
		let seekRatio = (event.clientX - playbackRect.left) / playbackRect.width
		const index = currentlyGrabbedRef.current.index
		const type = currentlyGrabbedRef.current.type
		let time = timings
		let seek = playVideoRef.current.duration * seekRatio
		if((type === 'start') && (seek > ((index !== 0) ? (time[index - 1].end + difference + 0.2) : 0)) && seek < time[index].end - difference){
			progressBarRef.current.style.left = `${seekRatio * 100}%`
			playVideoRef.current.currentTime = seek
			time[index]['start'] = seek
			setPlaying(false)
			setTimings(time)
		}
		else if((type === 'end') && (seek > time[index].start + difference) && (seek < (index !== (timings.length - 1) ? time[index].start - difference - 0.2 : playVideoRef.current.duration))){
			progressBarRef.current.style.left = `${time[index].start / playVideoRef.current.duration * 100}%`
			playVideoRef.current.currentTime = time[index].start
			time[index]['end'] = seek
			setPlaying(false)
			setTimings(time)
		}
		progressBarRef.current.style.width = '0%'
	}

	//Function that handles removing event listener from the mouse event on trimmer - Desktop browser
	const removeMouseMoveEventListener = () => {
		window.removeEventListener('mousemove', handleMouseMoveWhenGrabbed)
	}

	//Lifecycle that handles removing event listener from the mouse event on trimmer - Mobile browser
	const removePointerMoveEventListener = () => {
		window.removeEventListener('pointermove', handleMouseMoveWhenGrabbed)
	}

	//Function handling reset logic
	const reset = () => {
		playVideoRef.current.pause()

		setIsMuted(false)
		setPlaying(false)
		currentlyGrabbedRef.current = {'index': 0, 'type': 'none'}
		setDifference(0.2)
		setDeletingGrabber(false)
		setCurrentWarning(false)
		setImageUrl('')

		setTimings([{'start': 0, 'end': playVideoRef.current.duration}])
		playVideoRef.current.currentTime = timings[0].start
		progressBarRef.current.style.left = `${timings[0].start / playVideoRef.current.duration * 100}%`
		progressBarRef.current.style.width = '0%'
		addActiveSegments()
	}

	//Function handling thumbnail logic
	const captureSnapshot = () => {
		let video = playVideoRef.current
		const canvas = document.createElement('canvas')
		// scale the canvas accordingly
		canvas.width = video.videoWidth
		canvas.height = video.videoHeight
		// draw the video at that frame
		canvas.getContext('2d')
			.drawImage(video, 0, 0, canvas.width, canvas.height)
		// convert it to a usable data URL
		const dataURL = canvas.toDataURL()
		setImageUrl({imageUrl: dataURL})
	}

	//Function handling download of thumbnail logic
	const downloadSnapshot = () => {
		let a = document.createElement('a') //Create <a>
		a.href = imageUrl //Image Base64 Goes here
		a.download = 'Thumbnail.png' //File name Here
		a.click() //Downloaded file
	}

	//Function handling skip to previous logic
	const skipPrevious = () => {
		if(playing){
			playVideoRef.current.pause()
		}
		// let previousIndex = (currentlyGrabbed.index !== 0) ? (currentlyGrabbed.index - 1) : (timings.length - 1)
		// setCurrentlyGrabbed({currentlyGrabbed: {'index': previousIndex, 'type': 'start'}, playing: false})
		// currentlyGrabbedRef.current = {'index': previousIndex, 'type': 'start'}
		// progressBarRef.current.style.left = `${timings[previousIndex].start / playVideoRef.current.duration * 100}%`
		// progressBarRef.current.style.width = '0%'
		// playVideoRef.current.currentTime = timings[previousIndex].start
	}

	//Function handling play and pause logic
	const playPause = () => {
		if(playing){
			playVideoRef.current.pause()
		}
		else{
			if((playVideoRef.current.currentTime >= timings[0].end)) {
				playVideoRef.current.pause()
				setPlaying(false)
				currentlyGrabbedRef.current = {'index': 0, 'type': 'start'}
				playVideoRef.current.currentTime = timings[0].start
				progressBarRef.current.style.left = `${timings[0].start / playVideoRef.current.duration * 100}%`
				progressBarRef.current.style.width = '0%'
			}
			playVideoRef.current.play()
		}
		setPlaying(!playing)
	}

	//Function handling skip to next logic
	const skipNext = () => {
		if(playing){
			playVideoRef.current.pause()
		}
		// let nextIndex = (currentlyGrabbed.index !== (timings.length - 1)) ? (currentlyGrabbed.index + 1) : 0
		// setCurrentlyGrabbed({currentlyGrabbed: {'index': nextIndex, 'type': 'start'}, playing: false})
		// currentlyGrabbedRef.current = {'index': nextIndex, 'type': 'start'}
		// progressBarRef.current.style.left = `${timings[nextIndex].start / playVideoRef.current.duration * 100}%`
		// progressBarRef.current.style.width = '0%'
		// playVideoRef.current.currentTime = timings[nextIndex].start
	}

	//Function handling updating progress logic (clicking on progress bar to jump to different time durations)
	const updateProgress = (event) => {
		let playbackRect = playBackBarRef.current.getBoundingClientRect()
		let seekTime = ((event.clientX - playbackRect.left) / playbackRect.width) * playVideoRef.current.duration
		playVideoRef.current.pause()
		// find where seekTime is in the segment
		let index = -1
		let counter = 0
		for(let times of timings){
			if(seekTime >= times.start && seekTime <= times.end){
				index = counter
			}
			counter += 1
		}
		if(index === -1) {
			return
		}
		setPlaying(false)
		currentlyGrabbedRef.current = {'index': index, 'type': 'start'}
		progressBarRef.current.style.width = '0%' // Since the width is set later, this is necessary to hide weird UI
		progressBarRef.current.style.left = `${timings[index].start / playVideoRef.current.duration * 100}%`
		playVideoRef.current.currentTime = seekTime
	}

	//Function handling adding new trim markers logic
	const addGrabber = () => {
		const time = timings
		const end = time[time.length - 1].end + difference
		setDeletingGrabber({deletingGrabber: false, currentWarning: null})
		if(end >= playVideoRef.current.duration){
			return
		}
		time.push({'start': end + 0.2, 'end': playVideoRef.current.duration})
		setTimings(time)
		addActiveSegments()
	}

	//Function handling first step of deleting trimmer
	const preDeleteGrabber = () => {
		if(deletingGrabber){
			setDeletingGrabber({deletingGrabber: false, currentWarning: null})
		}
		else{
			setDeletingGrabber({deletingGrabber: true, currentWarning: 'delete_grabber'})
		}
	}

	//Function handling deletion of trimmers logic
	const deleteGrabber = (index) => {
		let time = timings
		setDeletingGrabber({deletingGrabber: false, currentWarning: null, currentlyGrabbed: {'index': 0, 'type': 'start'}})
		setDeletingGrabber({deletingGrabber: false, currentWarning: null, currentlyGrabbed: {'index': 0, 'type': 'start'}})
		if(time.length === 1){
			return
		}
		time.splice(index, 1)
		progressBarRef.current.style.left = `${time[0].start / playVideoRef.current.duration * 100}%`
		playVideoRef.current.currentTime = time[0].start
		progressBarRef.current.style.width = '0%'
		addActiveSegments()
	}

	//Function handling logic of time segments throughout videos duration
	const addActiveSegments = () => {
		let colors = ''
		let counter = 0
		colors += `, rgb(240, 240, 240) 0%, rgb(240, 240, 240) ${timings[0].start / playVideoRef.current.duration * 100}%`
		for(let times of timings) {
			if(counter > 0) {
				colors += `, rgb(240, 240, 240) ${timings[counter].end / playVideoRef.current.duration * 100}%, rgb(240, 240, 240) ${times.start / playVideoRef.current.duration * 100}%`
			}
			colors += `, #ccc ${times.start / playVideoRef.current.duration * 100}%, #ccc ${times.end / playVideoRef.current.duration * 100}%`
			counter += 1
		}
		colors += `, rgb(240, 240, 240) ${timings[counter - 1].end / playVideoRef.current.duration * 100}%, rgb(240, 240, 240) 100%`
		playBackBarRef.current.style.background = `linear-gradient(to right${colors})`
	}

	// Function handling logic for post trimmed video
	const saveVideo = async(fileInput) => {
		let metadata = {
			'trim_times': timings,
			'mute': isMuted
		}
		console.log(metadata.trim_times)
		const trimStart = metadata.trim_times[0].start
		const trimEnd = metadata.trim_times[0].end

		const trimmedVideo = trimEnd - trimStart

		console.log('Trimmed Duration: ', trimmedVideo)
		console.log('Trim End: ', trimEnd)

		try{
			//Disabling new-cap for FS function
			// eslint-disable-next-line new-cap
			ffmpeg.current.FS('writeFile', 'myFile.mp4', await fetchFile(videoUrl))

			ffmpeg.current.setProgress(({ratio}) => {
				console.log('ffmpeg progress: ', ratio)
				if(ratio < 0) {
					setProgress(0)
				}
				setProgress(Math.round(ratio * 100))
			})

			await ffmpeg.current.run('-ss', `${trimStart}`, '-accurate_seek', '-i', 'myFile.mp4', '-to', `${trimmedVideo}`, '-codec', 'copy', 'output.mp4')

			//Disabling new-cap for FS function
			// eslint-disable-next-line new-cap
			const data = ffmpeg.current.FS('readFile', 'output.mp4')

			const url = URL.createObjectURL(new Blob([data.buffer], {type: 'video/mp4'}))

			setTrimmedVideo(url)
			setTrimmingDone(true)
			// setLottiePlaying(false)
		}
		catch(error) {
			console.log(error)
		}
	}

	return (
		<div className='wrapper'>
			{/* Video element for the trimmed video */}
			{trimmingDone ?
				<div
					style={{
						maxHeight: '100vh',
						marginTop: '50vh'
					}}>
					<video
						style={{
							width: '100%',
							marginTop: '100px',
							borderRadius: '20px',
							border: '4px solid #0072cf'
						}}
						ref={trimmedVidRef}
						controls
						autoload='metadata'
						onClick={() => console.log(trimmedVidRef.current.duration)}
					>
						<source src={trimmedVideo} type='video/mp4' />
					</video>
				</div>
				: null
			}
			{/* Main video element for the video editor */}
			<video className='video'
				autoload='metadata'
				muted={isMuted}
				ref={playVideoRef}
				onLoadedData={() => {
					console.log(playVideoRef)
					playPause()
				}}
				onClick={() => {
					playPause()
				}}
				onTimeUpdate={() => {
					setSeekerBar(progressBarRef.current.style.width)
				}}
			>
				<source src={videoUrl} type='video/mp4' />
			</video>
			<div className='playback'>
				{/* If there is an instance of the playVideoRef, render the trimmer markers */}
				{playVideoRef.current ?
					Array.from(timings).map((timing, index) => (
						<div key={index}
						>
							<div key={'grabber_' + index}>
								{/* Markup and logic for the start trim marker */}
								<div id='grabberStart' className='grabber start'
									style={{left: `${timings[0].start / playVideoRef.current.duration * 100}%`}}
									// Events for desktop - Start marker
									onMouseDown={(event) => {
										if(deletingGrabber){
											deleteGrabber(index)
										}
										else{
											currentlyGrabbedRef.current = {'index': index, 'type': 'start'}
											window.addEventListener('mousemove', handleMouseMoveWhenGrabbed)
											window.addEventListener('mouseup', removeMouseMoveEventListener)
										}
									}}
									//Events for mobile - Start marker
									onPointerDown={() => {
										if(deletingGrabber){
											deleteGrabber(index)
										}
										else{
											currentlyGrabbedRef.current = {'index': index, 'type': 'start'}
											window.addEventListener('pointermove', handleMouseMoveWhenGrabbed)
											window.addEventListener('pointerup', removePointerMoveEventListener)
										}
									}}
								>
									<svg version='1.1' xmlns='http://www.w3.org/2000/svg' x='0' y='0' width='10' height='14' viewBox='0 0 10 14' xmlSpace='preserve'>
										<path className='st0' d='M1 14L1 14c-0.6 0-1-0.4-1-1V1c0-0.6 0.4-1 1-1h0c0.6 0 1 0.4 1 1v12C2 13.6 1.6 14 1 14zM5 14L5 14c-0.6 0-1-0.4-1-1V1c0-0.6 0.4-1 1-1h0c0.6 0 1 0.4 1 1v12C6 13.6 5.6 14 5 14zM9 14L9 14c-0.6 0-1-0.4-1-1V1c0-0.6 0.4-1 1-1h0c0.6 0 1 0.4 1 1v12C10 13.6 9.6 14 9 14z'/>
									</svg>
								</div>
								{/* Markup and logic for the end trim marker */}
								<div id='grabberEnd' className='grabber end'
									style={{left: `${timings[0].end / playVideoRef.current.duration * 100}%`}}
									//Events for desktop - End marker
									onMouseDown={(event) => {
										if(deletingGrabber){
											deleteGrabber(index)
										}
										else{
											currentlyGrabbedRef.current = {'index': index, 'type': 'end'}
											window.addEventListener('mousemove', handleMouseMoveWhenGrabbed)
											window.addEventListener('mouseup', removeMouseMoveEventListener)
										}
									}}
									//Events for mobile - End marker
									onPointerDown={() => {
										if(deletingGrabber){
											deleteGrabber(index)
										}
										else{
											currentlyGrabbedRef.current = {'index': index, 'type': 'end'}
											window.addEventListener('pointermove', handleMouseMoveWhenGrabbed)
											window.addEventListener('pointerup', removePointerMoveEventListener)
										}
									}}
								>
									<svg version='1.1' xmlns='http://www.w3.org/2000/svg' x='0' y='0' width='10' height='14' viewBox='0 0 10 14' xmlSpace='preserve'>
										<path className='st0' d='M1 14L1 14c-0.6 0-1-0.4-1-1V1c0-0.6 0.4-1 1-1h0c0.6 0 1 0.4 1 1v12C2 13.6 1.6 14 1 14zM5 14L5 14c-0.6 0-1-0.4-1-1V1c0-0.6 0.4-1 1-1h0c0.6 0 1 0.4 1 1v12C6 13.6 5.6 14 5 14zM9 14L9 14c-0.6 0-1-0.4-1-1V1c0-0.6 0.4-1 1-1h0c0.6 0 1 0.4 1 1v12C10 13.6 9.6 14 9 14z'/>
									</svg>
								</div>
							</div>
						</div>
					))
					: []}
				<div className='seekable' ref={playBackBarRef} onClick={updateProgress}></div>
				<div className='progress' ref={progressBarRef}></div>
			</div>

			<div className='controls'>
				<div className='player-controls'>
					<button className='settings-control' title='Reset Video' onClick={reset}><FontAwesomeIcon icon={faSync} /></button>
					<button className='settings-control' title='Mute/Unmute Video' onClick={() => setIsMuted({isMuted: !isMuted})}>{isMuted ? <FontAwesomeIcon icon={faVolumeMute} /> : <FontAwesomeIcon icon={faVolumeUp} />}</button>
					<button className='settings-control' title='Capture Thumbnail' onClick={captureSnapshot}><FontAwesomeIcon icon={faCamera} /></button>
				</div>
				<div className='player-controls'>
					<button className='seek-start' title='Skip to previous clip' onClick={skipPrevious}><FontAwesomeIcon icon={faStepBackward} /></button>
					<button className='play-control' title='Play/Pause' onClick={playPause} >{playing ? <FontAwesomeIcon icon={faPause} /> : <FontAwesomeIcon icon={faPlay} /> }</button>
					<button className='seek-end' title='Skip to next clip' onClick={skipNext}><FontAwesomeIcon icon={faStepForward} /></button>
				</div>
				<div>
					<button title='Add grabber' className='trim-control margined' onClick={addGrabber}>Add <FontAwesomeIcon icon={faGripLinesVertical} /></button>
					<button title='Delete grabber' className='trim-control margined' onClick={preDeleteGrabber}>Delete <FontAwesomeIcon icon={faGripLinesVertical} /></button>
					<button title='Save changes' className='trim-control' onClick={saveVideo}>Save</button>
				</div>
			</div>
			{ready ?
				<div></div>
				:
				<div>Loading...</div>
			}
			{currentWarning != null ? <div className={'warning'}>{warnings[currentWarning]}</div> : ''}
			{(imageUrl !== '') ?
				<div className={'marginVertical'}>
					<img src={imageUrl} className={'thumbnail'} alt='Photos' />
					<div className='controls'>
						<div className='player-controls'>
							<button className='settings-control' title='Reset Video' onClick={downloadSnapshot}><FontAwesomeIcon icon={faDownload} /></button>
							<button className='settings-control' title='Save Video' onClick={() => {
								setImageUrl('')
							}}><FontAwesomeIcon icon={faEraser} /></button>
						</div>
					</div>
				</div>
				: ''}
		</div>
	)
}
Example #6
Source File: DemoDashboard.jsx    From react-lte with MIT License 4 votes vote down vote up
export default function DemoDashboard() {
  return (
    <>
      <LteContentHeader title='Dashboard' />
      <LteContent>
        <Row>
          <Col xs='12' sm='6' md='3'>
            <LteInfoBox icon={faCog} text='CPU Traffic' number='10%' iconColor='info' />
          </Col>
          <Col xs='12' sm='6' md='3'>
            <LteInfoBox icon={faThumbsUp} text='Likes' number='41,410' iconColor='danger' />
          </Col>
          <div className='clearfix hidden-md-up' />
          <Col xs='12' sm='6' md='3'>
            <LteInfoBox icon={faShoppingCart} text='Sales' number='760' iconColor='success' />
          </Col>
          <Col xs='12' sm='6' md='3'>
            <LteInfoBox icon={faUsers} text='New Members' number='2,000' iconColor='warning' />
          </Col>
        </Row>

        <Row>
          <Col lg='3' xs='6'>
            <LteSmallBox title='150' message='New Orders' href='/info' icon={faShoppingBasket} color='info' />
          </Col>
          <Col lg='3' xs='6'>
            <LteSmallBox title='53%' message='Bounce Rate' href='/info' icon={faChartBar} color='success' />
          </Col>
          <Col lg='3' xs='6'>
            <LteSmallBox title='44' message='User Registrations' href='/info' icon={faUserPlus} color='warning' />
          </Col>
          <Col lg='3' xs='6'>
            <LteSmallBox title='65' message='Unique Visitors' href='/info' icon={faChartPie} color='danger' />
          </Col>
        </Row>

        <Row>
          <Col lg='8'>
            <Card>
              <CardHeader className='border-transparent'>
                <CardTitle>Latest Orders</CardTitle>
                <LteCardTools>
                  <Button color='' className='btn-tool' data-card-widget='collapse'>
                    <FontAwesomeIcon icon={faMinus} />
                  </Button>
                  <Button color='' className='btn-tool' data-card-widget='remove'>
                    <FontAwesomeIcon icon={faTimes} />
                  </Button>
                </LteCardTools>
              </CardHeader>
              <CardBody className='p-0'>
                <Table responsive>
                  <thead>
                    <tr>
                      <th>Order ID</th>
                      <th>Item</th>
                      <th>Status</th>
                      <th>Popularity</th>
                    </tr>
                  </thead>

                  <tbody>
                    <tr>
                      <td>OR9842</td>
                      <td>Call of Duty IV</td>
                      <td>
                        <Badge tag='span' color='success'>
                          Shipped
                        </Badge>
                      </td>
                      <td>
                        <div className='sparkbar' data-color='#00a65a' data-height='20'>
                          90,80,90,-70,61,-83,63
                        </div>
                      </td>
                    </tr>
                    <tr>
                      <td>OR1848</td>
                      <td>Samsung Smart TV</td>
                      <td>
                        <Badge tag='span' color='warning'>
                          Pending
                        </Badge>
                      </td>
                      <td>
                        <div className='sparkbar' data-color='#f39c12' data-height='20'>
                          90,80,-90,70,61,-83,68
                        </div>
                      </td>
                    </tr>
                    <tr>
                      <td>OR7429</td>
                      <td>iPhone 6 Plus</td>
                      <td>
                        <Badge tag='span' color='danger'>
                          Delivered
                        </Badge>
                      </td>
                      <td>
                        <div className='sparkbar' data-color='#f56954' data-height='20'>
                          90,-80,90,70,-61,83,63
                        </div>
                      </td>
                    </tr>
                    <tr>
                      <td>OR7429</td>
                      <td>Samsung Smart TV</td>
                      <td>
                        <Badge tag='span' color='info'>
                          Processing
                        </Badge>
                      </td>
                      <td>
                        <div className='sparkbar' data-color='#00c0ef' data-height='20'>
                          90,80,-90,70,-61,83,63
                        </div>
                      </td>
                    </tr>
                    <tr>
                      <td>OR1848</td>
                      <td>Samsung Smart TV</td>
                      <td>
                        <Badge tag='span' color='warning'>
                          Pending
                        </Badge>
                      </td>
                      <td>
                        <div className='sparkbar' data-color='#f39c12' data-height='20'>
                          90,80,-90,70,61,-83,68
                        </div>
                      </td>
                    </tr>
                    <tr>
                      <td>OR7429</td>
                      <td>iPhone 6 Plus</td>
                      <td>
                        <Badge tag='span' color='danger'>
                          Delivered
                        </Badge>
                      </td>
                      <td>
                        <div className='sparkbar' data-color='#f56954' data-height='20'>
                          90,-80,90,70,-61,83,63
                        </div>
                      </td>
                    </tr>
                    <tr>
                      <td>OR9842</td>
                      <td>Call of Duty IV</td>
                      <td>
                        <Badge tag='span' color='success'>
                          Shipped
                        </Badge>
                      </td>
                      <td>
                        <div className='sparkbar' data-color='#00a65a' data-height='20'>
                          90,80,90,-70,61,-83,63
                        </div>
                      </td>
                    </tr>
                  </tbody>
                </Table>
              </CardBody>
            </Card>

            <Row>
              <Col lg='6'>
                <LteDirectChat color='warning'>
                  <CardHeader>
                    <CardTitle>Direct Chat</CardTitle>
                    <LteCardTools>
                      <Badge color='warning' data-toggle='tooltip' title='3 New Messages'>
                        3
                      </Badge>
                      <Button className='btn-tool' color='' data-card-widget='collapse'>
                        <FontAwesomeIcon icon={faMinus} />
                      </Button>
                      <Button
                        color=''
                        className='btn-tool'
                        data-toggle='tooltip'
                        title='Contacts'
                        data-widget='chat-pane-toggle'
                      >
                        <FontAwesomeIcon icon={faComments} />
                      </Button>
                      <Button color='' className='btn-tool' data-card-widget='remove'>
                        <FontAwesomeIcon icon={faTimes} />
                      </Button>
                    </LteCardTools>
                  </CardHeader>
                  <CardBody>
                    <LteDirectChatMessages>
                      <LteDirectChatMsg
                        name='Alexander Pierce'
                        date='23 Jan 2:00 pm'
                        image={user1}
                        message="Is this template really for free? That's unbelievable!"
                      />
                      <LteDirectChatMsg
                        right
                        name='Sarah Bullock'
                        date='23 Jan 2:05 pm'
                        image={user3}
                        message='You better believe it!'
                      />
                      <LteDirectChatMsg
                        name='Alexander Pierce'
                        date='23 Jan 5:37 pm'
                        image={user1}
                        message='Working with AdminLTE on a great new app! Wanna join?'
                      />
                      <LteDirectChatMsg
                        right
                        name='Sarah Bullock'
                        date='23 Jan 6:10 pm'
                        image={user3}
                        message='I would love to.'
                      />
                    </LteDirectChatMessages>
                    <LteDirectChatContacts>
                      <LteContactsList>
                        <LteContactsListItem
                          href='/contacts'
                          image={user1}
                          name='Count Dracula'
                          date='2/28/2015'
                          message='How have you been? I was...'
                        />
                        <LteContactsListItem
                          href='/contacts'
                          image={user7}
                          name='Sarah Doe'
                          date='2/23/2015'
                          message='I will be waiting for...'
                        />
                        <LteContactsListItem
                          href='/contacts'
                          image={user3}
                          name='Nadia Jolie'
                          date='2/20/2015'
                          message="I'll call you back at..."
                        />
                        <LteContactsListItem
                          href='/contacts'
                          image={user5}
                          name='Nora S. Vans'
                          date='2/10/2015'
                          message='Where is your new...'
                        />
                        <LteContactsListItem
                          href='/contacts'
                          image={user6}
                          name='John K.'
                          date='1/27/2015'
                          message='Can I take a look at...'
                        />
                        <LteContactsListItem
                          href='/contacts'
                          image={user8}
                          name='Kenneth M.'
                          date='1/4/2015'
                          message='Never mind I found...'
                        />
                      </LteContactsList>
                    </LteDirectChatContacts>
                  </CardBody>
                  <CardFooter>
                    <Form>
                      <InputGroup>
                        <Input placeholder='Type Message ...' />
                        <InputGroupAddon addonType='append'>
                          <Button color='warning'>Send</Button>
                        </InputGroupAddon>
                      </InputGroup>
                    </Form>
                  </CardFooter>
                </LteDirectChat>
              </Col>
              <Col lg='6'>
                <Card>
                  <CardHeader>
                    <CardTitle>Latest Members</CardTitle>
                    <LteCardTools>
                      <Badge color='danger'>8 New Members</Badge>
                      <Button className='btn-tool' color='' data-card-widget='collapse'>
                        <FontAwesomeIcon icon={faMinus} />
                      </Button>
                      <Button color='' className='btn-tool' data-card-widget='remove'>
                        <FontAwesomeIcon icon={faTimes} />
                      </Button>
                    </LteCardTools>
                  </CardHeader>
                  <CardBody className='p-0'>
                    <LteUsersList>
                      <LteUsersListItem image={user1} href='/users' name='Alexander Pierce' date='Today' />
                      <LteUsersListItem image={user8} href='/users' name='Norman' date='Yesterday' />
                      <LteUsersListItem image={user7} href='/users' name='Jane' date='12 Jan' />
                      <LteUsersListItem image={user6} href='/users' name='John' date='12 Jan' />
                      <LteUsersListItem image={user2} href='/users' name='Alexander' date='13 Jan' />
                      <LteUsersListItem image={user5} href='/users' name='Sarah' date='14 Jan' />
                      <LteUsersListItem image={user4} href='/users' name='Nora' date='15 Jan' />
                      <LteUsersListItem image={user3} href='/users' name='Nadia' date='15 Jan' />
                    </LteUsersList>
                  </CardBody>
                </Card>
              </Col>
            </Row>
          </Col>
          <Col lg='4'>
            <LteInfoBox icon={faTag} text='Inventory' number='5,200' bgColor='warning' />
            <LteInfoBox icon={faHeart} text='Mentions' number='92,050' bgColor='success' />
            <LteInfoBox icon={faCloudDownloadAlt} text='Downloads' number='114,381' bgColor='danger' />
            <LteInfoBox icon={faComment} text='Direct Messages' number='163,921' bgColor='info' />
            <Card>
              <CardHeader className='border-0'>
                <CardTitle>Online Store Overview</CardTitle>
                <LteCardTools>
                  <Button className='btn-tool' color=''>
                    <FontAwesomeIcon icon={faDownload} />
                  </Button>
                  <Button color='' className='btn-tool'>
                    <FontAwesomeIcon icon={faBars} />
                  </Button>
                </LteCardTools>
              </CardHeader>
              <CardBody>
                <div className='d-flex justify-content-between align-items-center border-bottom mb-3'>
                  <p className='text-success text-xl'>
                    <FontAwesomeIcon icon={faRedo} />
                  </p>
                  <p className='d-flex flex-column text-right'>
                    <span className='font-weight-bold'>
                      <FontAwesomeIcon icon={faArrowUp} className='text-success' />
                      12%
                    </span>
                    <span className='text-muted'>CONVERSION RATE</span>
                  </p>
                </div>
                <div className='d-flex justify-content-between align-items-center border-bottom mb-3'>
                  <p className='text-warning text-xl'>
                    <FontAwesomeIcon icon={faShoppingCart} />
                  </p>
                  <p className='d-flex flex-column text-right'>
                    <span className='font-weight-bold'>
                      <FontAwesomeIcon icon={faArrowUp} className='text-warning' /> 0.8%
                    </span>
                    <span className='text-muted'>SALES RATE</span>
                  </p>
                </div>
                <div className='d-flex justify-content-between align-items-center mb-0'>
                  <p className='text-danger text-xl'>
                    <FontAwesomeIcon icon={faUsers} />
                  </p>
                  <p className='d-flex flex-column text-right'>
                    <span className='font-weight-bold'>
                      <FontAwesomeIcon icon={faArrowUp} className='text-danger' /> 1%
                    </span>
                    <span className='text-muted'>REGISTRATION RATE</span>
                  </p>
                </div>
              </CardBody>
            </Card>
          </Col>
        </Row>
      </LteContent>
    </>
  );
}
Example #7
Source File: App.js    From Sketchify with MIT License 4 votes vote down vote up
function App() {
    const [html, setHtml] = useLocalStorage("html", "");
    const [css, setCss] = useLocalStorage("css", "");
    const [js, setJs] = useLocalStorage("js", "");
    const [title, setTitle] = useLocalStorage("title", "");
    const [srcDoc, setSrcDoc] = useState("");
    // HTML
    const downloadHtml = () => {
        let htmlContent = `
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <title>${title}</title>
        <link rel="stylesheet" href="./styles.css">
    </head>
    <body>${html}</body>
    <script src="./script.js"></script>
</html>
            `;
        let link = document.getElementById("download-btn-html");
        let file = new Blob([htmlContent], { type: "html" });
        let downloadFile = "index.html";
        link.target = "_blank";
        link.href = URL.createObjectURL(file);
        link.download = downloadFile;
    };
    const downloadCss = () => {
        // CSS
        let cssLink = document.getElementById("download-btn-css");
        let cssFile = new Blob([css], { type: "css" });
        let cssDownloadFile = "styles.css";
        cssLink.target = "_blank";
        cssLink.href = URL.createObjectURL(cssFile);
        cssLink.download = cssDownloadFile;
    };
    const downloadJs = () => {
        // JS
        let jsLink = document.getElementById("download-btn-js");
        let jsFile = new Blob([js], { type: "js" });
        let jsDownloadFile = "script.js";
        jsLink.target = "_blank";
        jsLink.href = URL.createObjectURL(jsFile);
        jsLink.download = jsDownloadFile;
    };

    const clearEditor = () => {
        setHtml("");
        setCss("");
        setJs("");
    };

    useEffect(() => {
        if (title === "") {
            document.title = "Sketchify - Untitled";
        } else {
            document.title = "Sketchify - " + title;
        }

        if (!(html === "" && css === "" && js === "")) {
            document.getElementById("iframe").classList.remove("disblock");
            document.getElementById("intro").classList.add("disblock");
        }

        const timeout = setTimeout(() => {
            setSrcDoc(`
        <html>
          <body>${html}</body>
          <style>${css}</style>
          <script>${js}</script>
        </html>
      `);
        }, 250);

        return () => clearTimeout(timeout);
    }, [html, css, js, title]);

    useEffect(() => {
        window.addEventListener("beforeunload", (ev) => {
            ev.preventDefault();
            return (ev.returnValue = "Changes you made will not be saved.");
        });
    });

    return (
        <div className="wrap-box">
            <nav className="nav-bar box1">
                <div className="logo">Sketchify</div>
                <input
                    className="title"
                    id="title-input"
                    placeholder="Untitled"
                    required="required"
                    value={title}
                    onChange={() =>
                        setTitle(document.getElementById("title-input").value)
                    }
                    autoComplete="off"
                />
                <div className="btn-container">
                    <div className="clearCode" onClick={clearEditor}>
                        <FontAwesomeIcon icon={faEraser} />
                        <div>Clear Code</div>
                    </div>
                    <a
                        href=" "
                        id="download-btn-html"
                        title="Download HTML file"
                        onClick={downloadHtml}>
                        <FontAwesomeIcon icon={faDownload} />
                        <div>HTML</div>
                    </a>
                    <a
                        href=" "
                        id="download-btn-css"
                        title="Download CSS file"
                        onClick={downloadCss}>
                        <FontAwesomeIcon icon={faDownload} />
                        <div>CSS</div>
                    </a>
                    <a
                        href=" "
                        id="download-btn-js"
                        title="Download JS file"
                        onClick={downloadJs}>
                        <FontAwesomeIcon icon={faDownload} />
                        <div>JS</div>
                    </a>
                    <a
                        href="/colabDetails"
                        id="collaborate-btn"
                        title="Collaborate">
                        <FontAwesomeIcon icon={faUsers} />
                        <div>Collaborate</div>
                    </a>
                </div>
            </nav>
            <Split sizes={[50, 50]} direction="vertical" className="box2">
                <Split className="pane top-pane box21" sizes={[33, 34, 33]}>
                    <Editor
                        language="text/html"
                        displayName="HTML"
                        value={html}
                        onChange={setHtml}
                    />
                    <Editor
                        language="css"
                        displayName="CSS"
                        value={css}
                        onChange={setCss}
                    />
                    <Editor
                        language="javascript"
                        displayName="JS"
                        value={js}
                        onChange={setJs}
                    />
                </Split>
                <div className="pane box22">
                    <iframe
                        srcDoc={srcDoc}
                        title="output"
                        id="iframe"
                        sandbox="allow-scripts"
                        frameBorder="0"
                        width="100%"
                        height="100%"
                        className="disblock"
                    />
                    <iframe
                        srcDoc={introDoc}
                        title="intro"
                        id="intro"
                        sandbox="allow-scripts"
                        frameBorder="0"
                        width="100%"
                        height="100%"
                    />
                </div>
            </Split>
            <a
                href="https://github.com/s-katte/Sketchify"
                target="_blank"
                rel="noopener noreferrer"
                id="github-link"
                className="text-center">
                <FontAwesomeIcon icon={faGithub} />
                <span>&nbsp;GitHub</span>
            </a>
        </div>
    );
}
Example #8
Source File: ColabApp.js    From Sketchify with MIT License 4 votes vote down vote up
function ColabApp() {
    // const [html, setHtml] = useLocalStorage("html", "");
    // const [css, setCss] = useLocalStorage("css", "");
    // const [js, setJs] = useLocalStorage("js", "");
    // const [title, setTitle] = useLocalStorage("title", "");
    const [username] = useLocalStorage("username", "");
    const [roomname] = useLocalStorage("roomname", "");
    const [html, setHtml] = useState("");
    const [css, setCss] = useState("");
    const [js, setJs] = useState("");
    const [title, setTitle] = useState("");
    const [srcDoc, setSrcDoc] = useState("");
    const { socket } = useSocket();
    const htmlEditor = useRef(null);
    const cssEditor = useRef(null);
    const jsEditor = useRef(null);
    // HTML
    const downloadHtml = () => {
        let htmlContent = `
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
        <title>${title}</title>
        <link rel="stylesheet" href="./styles.css">
    </head>
    <body>${html}</body>
    <script src="./script.js"></script>
</html>
            `;
        let link = document.getElementById("download-btn-html");
        let file = new Blob([htmlContent], { type: "html" });
        let downloadFile = "index.html";
        link.target = "_blank";
        link.href = URL.createObjectURL(file);
        link.download = downloadFile;
    };
    const downloadCss = () => {
        // CSS
        let cssLink = document.getElementById("download-btn-css");
        let cssFile = new Blob([css], { type: "css" });
        let cssDownloadFile = "styles.css";
        cssLink.target = "_blank";
        cssLink.href = URL.createObjectURL(cssFile);
        cssLink.download = cssDownloadFile;
    };
    const downloadJs = () => {
        // JS
        let jsLink = document.getElementById("download-btn-js");
        let jsFile = new Blob([js], { type: "js" });
        let jsDownloadFile = "script.js";
        jsLink.target = "_blank";
        jsLink.href = URL.createObjectURL(jsFile);
        jsLink.download = jsDownloadFile;
    };

    const clearEditor = () => {
        setHtml("");
        setCss("");
        setJs("");
    };

    socket.on("msg", (data) => {
        setHtml(data.html);
        setCss(data.css);
        setJs(data.js);
        setTitle(data.title);
        console.log("FROM", data.username);
    });

    useEffect(() => {
        if (title === "") {
            document.title = "Sketchify - Untitled";
        } else {
            document.title = "Sketchify - " + title;
        }

        if (!(html === "" && css === "" && js === "")) {
            document.getElementById("iframe").classList.remove("disblock");
            document.getElementById("intro").classList.add("disblock");
        }
        const timeout = setTimeout(() => {
            setSrcDoc(`
        <html>
          <body>${html}</body>
          <style>${css}</style>
          <script>${js}</script>
        </html>
      `);
        }, 250);

        return () => clearTimeout(timeout);
    }, [html, css, js, title]);

    useEffect(() => {
        window.addEventListener("beforeunload", (ev) => {
            ev.preventDefault();
            return (
                (ev.returnValue = "Changes you made will not be saved."),
                socket.emit("leave-room", { roomname })
            );
        });
    });

    const sendData = () => {
        console.log("sending", htmlEditor.current.props.value);

        socket.emit("data-to-room", {
            roomname,
            username,
            title,
            html: htmlEditor.current.props.value,
            css: cssEditor.current.props.value,
            js: jsEditor.current.props.value,
        });
    };
    return (
        <div className="wrap-box">
            <nav className="nav-bar box1">
                <div className="logo">Sketchify</div>
                <input
                    className="title"
                    id="title-input"
                    placeholder="Untitled"
                    required="required"
                    value={title}
                    onChange={() =>
                        setTitle(document.getElementById("title-input").value)
                    }
                    autoComplete="off"
                />
                <div className="btn-container">
                    <div className="clearCode" onClick={clearEditor}>
                        <FontAwesomeIcon icon={faEraser} />
                        <div>Clear Code</div>
                    </div>
                    <a
                        href=" "
                        id="download-btn-html"
                        title="Download HTML file"
                        onClick={downloadHtml}>
                        <FontAwesomeIcon icon={faDownload} />
                        <div>HTML</div>
                    </a>
                    <a
                        href=" "
                        id="download-btn-css"
                        title="Download CSS file"
                        onClick={downloadCss}>
                        <FontAwesomeIcon icon={faDownload} />
                        <div>CSS</div>
                    </a>
                    <a
                        href=" "
                        id="download-btn-js"
                        title="Download JS file"
                        onClick={downloadJs}>
                        <FontAwesomeIcon icon={faDownload} />
                        <div>JS</div>
                    </a>
                    <a
                        href="/colabDetails"
                        id="collaborate-btn"
                        title="Collaborate">
                        <FontAwesomeIcon icon={faUsers} />
                        <div>Collaborate</div>
                    </a>
                </div>
            </nav>
            <Split sizes={[50, 50]} direction="vertical" className="box2">
                <Split className="pane top-pane box21" sizes={[33, 34, 33]}>
                    <Editor
                        language="text/html"
                        displayName="HTML"
                        refer={htmlEditor}
                        value={html}
                        onChange={setHtml}
                        performSend={sendData}
                    />
                    <Editor
                        language="css"
                        displayName="CSS"
                        value={css}
                        onChange={setCss}
                        performSend={sendData}
                        refer={cssEditor}
                    />
                    <Editor
                        language="javascript"
                        displayName="JS"
                        value={js}
                        onChange={setJs}
                        performSend={sendData}
                        refer={jsEditor}
                    />
                </Split>
                <div className="pane box22">
                    <iframe
                        srcDoc={srcDoc}
                        title="output"
                        id="iframe"
                        sandbox="allow-scripts"
                        frameBorder="0"
                        width="100%"
                        height="100%"
                        className="disblock"
                    />
                    <iframe
                        srcDoc={introDoc}
                        title="intro"
                        id="intro"
                        sandbox="allow-scripts"
                        frameBorder="0"
                        width="100%"
                        height="100%"
                    />
                </div>
            </Split>
            <a
                href="https://github.com/s-katte/Sketchify"
                target="_blank"
                rel="noopener noreferrer"
                id="github-link"
                className="text-center">
                <FontAwesomeIcon icon={faGithub} />
                <span>&nbsp;GitHub</span>
            </a>
        </div>
    );
}