Skip to content

Commit

Permalink
allow video selection
Browse files Browse the repository at this point in the history
  • Loading branch information
abovedave committed Aug 2, 2023
1 parent ce8af17 commit 70db9bf
Show file tree
Hide file tree
Showing 8 changed files with 235 additions and 70 deletions.
49 changes: 49 additions & 0 deletions src/components/AssetMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Button, MenuButton, Menu, MenuItem, MenuDivider } from '@sanity/ui'
import { EllipsisVerticalIcon, ResetIcon, ClipboardIcon, SearchIcon } from '@sanity/icons'

export function AssetMenu({
onAction,
}: {
onAction: (action) => void
}) {
return (
<MenuButton
button={
<Button
padding={2}
mode="ghost"
icon={EllipsisVerticalIcon}
tone="default"
/>
}
id="asset-menu"
menu={
<Menu>
<MenuItem
text="Replace media"
icon={SearchIcon}
onClick={() => {
onAction({ type: 'select' })
}}
/>
<MenuItem
text="Copy emebd URL"
icon={ClipboardIcon}
onClick={() => {
onAction({ type: 'copyUrl' })
}}
/>
<MenuDivider />
<MenuItem
text="Clear field"
icon={ResetIcon}
tone="critical"
onClick={() => {
onAction({ type: 'delete' })
}}
/>
</Menu>
}
/>
)
}
108 changes: 77 additions & 31 deletions src/components/Input.tsx
Original file line number Diff line number Diff line change
@@ -1,70 +1,116 @@
import { useEffect, useState } from 'react'
import { Button, Dialog, Card, Flex, Text, Box, Menu, MenuItem, Tooltip } from '@sanity/ui'
import { DocumentVideoIcon, ChevronLeftIcon } from '@sanity/icons'
import { useState, useCallback } from 'react'
import { Button, Dialog, Card, Flex, Text, useToast } from '@sanity/ui'
import { DocumentVideoIcon, ChevronLeftIcon, PlayIcon, ShareIcon } from '@sanity/icons'
import { set, unset } from 'sanity'

import Projects from './Projects'
import Videos from './Videos'

import { Player } from './Player'
import { AssetMenu } from './AssetMenu'

const WistiaInputComponent = (props) => {
const { value, onChange, config } = props

const [isModalOpen, setIsModalOpen] = useState(false)
const [selectedProjectId, setSelectedProjectId] = useState(null)
const [selectedVideoId, setSelectedVideoId] = useState(null)
const [selectedProjectId, setSelectedProjectId] = useState(0)

const handleChange = useCallback((newValue) => {
setIsModalOpen(false)
onChange(newValue ? set(newValue) : unset())
}, [onChange])

const handleProjectClick = (projectId) => {
const handleProjectClick = (projectId: number) => {
setSelectedProjectId(projectId)
}

const handleVideoClick = (videoId) => {
setSelectedVideoId(videoId)
const handleAssetMenu = (action) => {
switch (action?.type) {
case 'copyUrl': handleCopyURL(); break;
case 'delete': handleChange({}); break;
case 'select': setIsModalOpen(true); break;
}
}

const videoUrl = value?.hashed_id
? `https://fast.wistia.net/embed/iframe/${value.hashed_id}` : null

const { push: pushToast } = useToast()

const handleCopyURL = useCallback(() => {
navigator.clipboard.writeText(videoUrl || '')
pushToast({ closable: true, status: 'success', title: 'The URL is copied to the clipboard' })
}, [pushToast, videoUrl])

const toggleModal = () => {
setIsModalOpen(!isModalOpen)
}

return (
<div style={{padding: 1}}>
<Card
tone={'inherit'}
border
padding={3}
style={{borderStyle: 'dashed'}}
>
<Flex
align={'center'}
direction={'row'}
gap={4}
justify="space-between"
{videoUrl ? (
<Card
radius={2}
shadow={1}
padding={2}
>
<Flex align={'center'} flex={1} gap={2} justify="center">
<Flex
justify='space-between'
align='center'
gap={2}
marginBottom={2}
>
<Text size={1} weight='semibold' cellPadding={2}>
<PlayIcon style={{marginLeft: 3, marginRight: 3}} />
Wistia video ID: <a href="" target="_blank">
{value?.id}
<ShareIcon style={{marginLeft: 1}} />
</a>
</Text>
<AssetMenu onAction={handleAssetMenu} />
</Flex>

<Player videoUrl={videoUrl || ''} />
</Card>
)
: (
<Card
tone={'inherit'}
border
padding={[3,5]}
style={{borderStyle: 'dashed'}}
>
<Flex
align={'center'}
direction={'column'}
gap={4}
>
<Text muted><DocumentVideoIcon /></Text>

<Text size={1} muted>
Select a video from Wistia
Select a media from Wistia
</Text>
</Flex>

<Flex align="center" gap={2} justify="center" wrap="wrap">
<Button
mode="ghost"
text="Select video"
text="Select media"
onClick={toggleModal}
/>
</Flex>
</Flex>
</Card>
</Card>
)}

{
isModalOpen && (
<Dialog
header={selectedProjectId ? 'Select a video' : 'Select a project'}
header={selectedProjectId ? 'Select media' : 'Select project'}
id="wistia-projects"
onClose={toggleModal}
width={1}
>
{!selectedProjectId ?
<Projects
config={props.config}
config={config}
onProjectClick={handleProjectClick}
/>
:
Expand All @@ -77,15 +123,15 @@ const WistiaInputComponent = (props) => {
>
<Button
icon={ChevronLeftIcon}
onClick={() => handleProjectClick(null)}
onClick={() => handleProjectClick(0)}
mode="ghost"
text="Back to projects"
/>
</Card>
<Videos
config={props.config}
config={config}
projectId={selectedProjectId}
onVideoClick={handleVideoClick}
onVideoClick={handleChange}
/>
</div>
)
Expand Down
54 changes: 54 additions & 0 deletions src/components/Player.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
const playerUrl = (videoUrl: string) => {
let params = new URLSearchParams()

// https://wistia.com/support/developers/embed-options#options
let wistiaSettings = {
playbar: true,
playButton: true,
seo: false,
controlsVisibleOnLoad: true,
autoPlay: false,
doNotTrack: true,
preload: 'none',
volumeControl: true,
copyLinkAndThumbnailEnabled: true,
fullscreenButton: true,
}

for (let key in wistiaSettings) {
params.append(key, wistiaSettings[key])
}

return `${videoUrl}?${params.toString()}`
}

export function Player({
videoUrl,
}: {
videoUrl: string
}) {
return (
<div style={{
position: 'relative',
paddingTop: '56.25%',
height: '0',
}}>
<iframe
allow="autoplay; fullscreen"
style={{
width: '100%',
height: '100%',
position: 'absolute',
top: '0',
right: '0',
bottom: '0',
left: '0',
border: '0',
display: 'block',
borderRadius: '3px'
}}
src={playerUrl(videoUrl) || ''}
/>
</div>
)
}
13 changes: 10 additions & 3 deletions src/components/Projects.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,16 @@ import { LockIcon } from '@sanity/icons'

const WistiaProjectsComponent = ({ onProjectClick, config }) => {
const [wistiaProjects, setWistiaProjects] = useState([])
const [loading, setLoading] = useState(false)

const handleProjectClick = (projectId: string) => {
onProjectClick(projectId)
}

useEffect(() => {
const apiUrl = 'https://api.wistia.com/v1/projects.json'
setLoading(true)

const apiUrl = 'https://api.wistia.com/v1/projects.json?sort_by=updated&sort_direction=0'

const headers = new Headers({
Authorization: `Bearer ${config.token}`,
Expand All @@ -20,15 +23,18 @@ const WistiaProjectsComponent = ({ onProjectClick, config }) => {
method: 'GET',
headers: headers,
})
.then((response) => response.json())
.then((response) => {
setLoading(false)
return response.json()
})
.then((data) => setWistiaProjects(data))
.catch((error) => console.error(error))
}, [])

return (
<Box padding={1}>
<Menu>
{!wistiaProjects.length &&
{loading &&
<Card padding={4}>
<Flex
align="center"
Expand All @@ -44,6 +50,7 @@ const WistiaProjectsComponent = ({ onProjectClick, config }) => {
</Flex>
</Card>
}

{wistiaProjects?.map((project) => (
<MenuItem
key={project.id}
Expand Down
Loading

0 comments on commit 70db9bf

Please sign in to comment.