webapp/src/components/_shared/VideoPlayer/VideoPlayer.tsx

88 lines
2.6 KiB
TypeScript
Raw Normal View History

import { clsx } from 'clsx'
2024-02-04 11:25:21 +00:00
import { Match, Show, Switch, createEffect, createSignal } from 'solid-js'
import { useLocalize } from '~/context/localize'
import { Button } from '../Button'
import { Icon } from '../Icon'
import { Popover } from '../Popover'
import styles from './VideoPlayer.module.scss'
type Props = {
videoUrl: string
title?: string
description?: string
class?: string
onVideoDelete?: () => void
articleView?: boolean
}
2024-09-15 18:47:14 +00:00
const watchPattern = /watch=(\w+)/
const ytPattern = /youtu.be\/(\w+)/
const vimeoPattern = /vimeo.com\/(\d+)/
export const VideoPlayer = (props: Props) => {
const { t } = useLocalize()
const [videoId, setVideoId] = createSignal<string | undefined>()
const [isVimeo, setIsVimeo] = createSignal(false)
createEffect(() => {
const isYoutube = props.videoUrl.includes('youtube.com') || props.videoUrl.includes('youtu.be')
setIsVimeo(!isYoutube)
if (isYoutube) {
if (props.videoUrl.includes('youtube.com')) {
2024-09-15 18:47:14 +00:00
const videoIdMatch = props.videoUrl.match(watchPattern)
2024-02-04 09:03:15 +00:00
setVideoId(videoIdMatch?.[1])
} else {
2024-09-15 18:47:14 +00:00
const videoIdMatch = props.videoUrl.match(ytPattern)
2024-02-04 09:03:15 +00:00
setVideoId(videoIdMatch?.[1])
}
} else {
2024-09-15 18:47:14 +00:00
const videoIdMatch = props.videoUrl.match(vimeoPattern)
2024-02-04 09:03:15 +00:00
setVideoId(videoIdMatch?.[1])
}
})
return (
<div class={clsx(styles.VideoPlayer, props.class, { [styles.articleView]: props.articleView })}>
<Show when={props.onVideoDelete}>
<Popover content={t('Delete')}>
2024-06-24 17:50:27 +00:00
{(triggerRef: (el: HTMLElement) => void) => (
<Button
ref={triggerRef}
size="S"
class={styles.deleteAction}
2024-06-24 17:50:27 +00:00
onClick={() => props.onVideoDelete?.()}
value={<Icon class={styles.deleteIcon} name="delete" />}
/>
)}
</Popover>
</Show>
<Switch>
<Match when={isVimeo()}>
<div class={styles.videoContainer}>
<iframe
2024-02-04 09:03:15 +00:00
title={props.title}
src={`https://player.vimeo.com/video/${videoId()}`}
width="640"
height="360"
allow="autoplay; fullscreen; picture-in-picture"
allowfullscreen
/>
</div>
</Match>
<Match when={!isVimeo()}>
<div class={styles.videoContainer}>
<iframe
2024-02-04 09:03:15 +00:00
title={props.title}
width="560"
height="315"
src={`https://www.youtube.com/embed/${videoId()}`}
allowfullscreen
/>
</div>
</Match>
</Switch>
</div>
)
}