UNPKG

@mirrormedia/lilith-draft-editor

Version:
432 lines (389 loc) 15.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.VideoSelector = VideoSelector; var _react = _interopRequireWildcard(require("react")); var _debounce = _interopRequireDefault(require("lodash/debounce")); var _styledComponents = _interopRequireDefault(require("styled-components")); var _modals = require("@keystone-ui/modals"); var _apollo = require("@keystone-6/core/admin-ui/apollo"); var _searchBox = require("./search-box"); var _pagination = require("./pagination"); var _fields = require("@keystone-ui/fields"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } const videosQuery = (0, _apollo.gql)` query Videos($searchText: String!, $take: Int, $skip: Int) { videosCount(where: { name: { contains: $searchText } }) videos( where: { name: { contains: $searchText } } orderBy: { id: desc } take: $take skip: $skip ) { id name videoSrc file { filename filesize url } coverPhoto { id name resized { original } } } } `; const _ = { debounce: _debounce.default }; const VideoSearchBox = (0, _styledComponents.default)(_searchBox.SearchBox)` margin-top: 10px; `; const VideoSelectionWrapper = _styledComponents.default.div` overflow: auto; margin-top: 10px; `; const VideoGridsWrapper = _styledComponents.default.div` display: flex; flex-wrap: wrap; overflow: auto; `; const VideoGridWrapper = _styledComponents.default.div` flex: 0 0 33.3333%; cursor: pointer; padding: 0 10px 10px; `; const VideoMetaGridsWrapper = _styledComponents.default.div` display: flex; flex-wrap: wrap; overflow: auto; `; const VideoMetaGridWrapper = _styledComponents.default.div` flex: 0 0 33.3333%; cursor: pointer; padding: 0 10px 10px; `; const Video = _styledComponents.default.video` display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; `; const SeparationLine = _styledComponents.default.div` border: #e1e5e9 1px solid; margin-top: 10px; margin-bottom: 10px; `; const VideoSelected = _styledComponents.default.div` height: 1.4rem; `; const ErrorWrapper = _styledComponents.default.div` & * { margin: 0; } `; const VideoName = _styledComponents.default.p` text-align: center; `; const Label = _styledComponents.default.label` display: block; margin: 10px 0; font-weight: 600; `; const getYoutubeId = url => { if (!url) return null; const match = url.match(/(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/\s]{11})/); return match ? match[1] : null; }; function VideosGrids(props) { const { videos, selected, onSelect } = props; return /*#__PURE__*/_react.default.createElement(VideoGridsWrapper, null, videos.map(video => { return /*#__PURE__*/_react.default.createElement(VideoGrid, { key: video.id, isSelected: selected === null || selected === void 0 ? void 0 : selected.some(s => s.id === video.id), onSelect: () => onSelect(video), video: video }); })); } function VideoGrid(props) { var _video$file, _video$coverPhoto, _video$coverPhoto$res; const { video, onSelect, isSelected } = props; const [isPlaying, setIsPlaying] = (0, _react.useState)(false); (0, _react.useEffect)(() => { setIsPlaying(false); }, [video.id]); const youtubeId = getYoutubeId(video === null || video === void 0 ? void 0 : video.videoSrc); const fileUrl = video === null || video === void 0 ? void 0 : (_video$file = video.file) === null || _video$file === void 0 ? void 0 : _video$file.url; const posterUrl = (video === null || video === void 0 ? void 0 : (_video$coverPhoto = video.coverPhoto) === null || _video$coverPhoto === void 0 ? void 0 : (_video$coverPhoto$res = _video$coverPhoto.resized) === null || _video$coverPhoto$res === void 0 ? void 0 : _video$coverPhoto$res.original) || (youtubeId ? `https://img.youtube.com/vi/${encodeURIComponent(youtubeId)}/hqdefault.jpg` : ""); const handlePlayAndSelect = e => { e.stopPropagation(); if (isPlaying) { setIsPlaying(false); } else { setIsPlaying(true); onSelect(video); } }; return /*#__PURE__*/_react.default.createElement(VideoGridWrapper, { key: video === null || video === void 0 ? void 0 : video.id, onClick: () => onSelect(video) }, /*#__PURE__*/_react.default.createElement(VideoSelected, { style: { height: '24px', marginBottom: '4px' } }, isSelected ? /*#__PURE__*/_react.default.createElement("i", { className: "fas fa-check-circle", style: { color: '#007bff' } }) : null), /*#__PURE__*/_react.default.createElement("div", { onClick: handlePlayAndSelect, style: { width: '100%', aspectRatio: '16/9', position: 'relative', backgroundColor: '#000', borderRadius: '4px', overflow: 'hidden' } }, isPlaying ? youtubeId ? /*#__PURE__*/_react.default.createElement("iframe", { style: { width: '100%', height: '100%', border: 'none', display: 'block' }, src: `https://www.youtube.com/embed/${youtubeId}?autoplay=1&mute=1&rel=0`, allow: "autoplay; encrypted-media", allowFullScreen: true }) : /*#__PURE__*/_react.default.createElement(Video, { autoPlay: true, controls: true, muted: true, style: { width: '100%', height: '100%', objectFit: 'cover' } }, (fileUrl || (video === null || video === void 0 ? void 0 : video.videoSrc)) && /*#__PURE__*/_react.default.createElement("source", { src: fileUrl || (video === null || video === void 0 ? void 0 : video.videoSrc) })) : /*#__PURE__*/_react.default.createElement("div", { style: { width: '100%', height: '100%', backgroundImage: `url(${posterUrl})`, backgroundSize: 'cover', backgroundPosition: 'center', display: 'flex', alignItems: 'center', justifyContent: 'center' } }, /*#__PURE__*/_react.default.createElement("i", { className: youtubeId ? "fab fa-youtube" : "fas fa-play-circle", style: { color: 'white', fontSize: '2.5rem', opacity: 0.8 } }))), /*#__PURE__*/_react.default.createElement(VideoName, { style: { marginTop: '8px', fontSize: '14px', height: '1.2em', lineHeight: '1.2', whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', color: isSelected ? '#007bff' : 'inherit' } }, (video === null || video === void 0 ? void 0 : video.name) || "Untitled")); } function VideoMetaGrids(props) { const { videoMetas, onChange } = props; return /*#__PURE__*/_react.default.createElement(VideoMetaGridsWrapper, null, videoMetas.map(videoMeta => { var _videoMeta$video; return /*#__PURE__*/_react.default.createElement(VideoMetaGrid, { key: videoMeta === null || videoMeta === void 0 ? void 0 : (_videoMeta$video = videoMeta.video) === null || _videoMeta$video === void 0 ? void 0 : _videoMeta$video.id, videoMeta: videoMeta, onChange: onChange }); })); } function VideoMetaGrid(props) { var _video$coverPhoto2, _video$coverPhoto2$re, _video$file2, _video$file3; const { videoMeta, onChange } = props; const { video, desc } = videoMeta; const youtubeId = getYoutubeId(video === null || video === void 0 ? void 0 : video.videoSrc); const posterUrl = (video === null || video === void 0 ? void 0 : (_video$coverPhoto2 = video.coverPhoto) === null || _video$coverPhoto2 === void 0 ? void 0 : (_video$coverPhoto2$re = _video$coverPhoto2.resized) === null || _video$coverPhoto2$re === void 0 ? void 0 : _video$coverPhoto2$re.original) || (youtubeId ? `https://img.youtube.com/vi/${youtubeId}/hqdefault.jpg` : ""); const onVideoDescriptionChange = e => { onChange({ video, desc: e.target.value }); }; return /*#__PURE__*/_react.default.createElement(VideoMetaGridWrapper, null, youtubeId ? /*#__PURE__*/_react.default.createElement("iframe", { width: "100%", style: { aspectRatio: '16/9', border: 'none', backgroundColor: '#000' }, src: `https://www.youtube.com/embed/${youtubeId}?rel=0&autoplay=0`, allow: "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture", allowFullScreen: true, loading: "lazy" }) : /*#__PURE__*/_react.default.createElement(Video, { muted: true, autoPlay: true, loop: true, controls: true, poster: posterUrl, style: { width: '100%', aspectRatio: '16/9' } }, ((video === null || video === void 0 ? void 0 : video.videoSrc) || (video === null || video === void 0 ? void 0 : (_video$file2 = video.file) === null || _video$file2 === void 0 ? void 0 : _video$file2.url)) && /*#__PURE__*/_react.default.createElement("source", { src: (video === null || video === void 0 ? void 0 : video.videoSrc) || (video === null || video === void 0 ? void 0 : (_video$file3 = video.file) === null || _video$file3 === void 0 ? void 0 : _video$file3.url) })), /*#__PURE__*/_react.default.createElement(Label, null, "Video Name"), /*#__PURE__*/_react.default.createElement(VideoName, { style: { textAlign: 'left', fontSize: '14px', fontWeight: '500' } }, (video === null || video === void 0 ? void 0 : video.name) || 'Untitled'), /*#__PURE__*/_react.default.createElement(Label, { htmlFor: "description" }, "Video Description"), /*#__PURE__*/_react.default.createElement(_fields.TextInput, { id: "description", type: "text", placeholder: "(Optional)", defaultValue: desc, onChange: _.debounce(onVideoDescriptionChange, 300) })); } function VideoSelector(props) { const [queryVideos, { loading, error, data: { videos = [], videosCount = 0 } = {} }] = (0, _apollo.useLazyQuery)(videosQuery, { fetchPolicy: 'no-cache' }); const [currentPage, setCurrentPage] = (0, _react.useState)(0); // page starts with 1, 0 is used to detect initialization const [searchText, setSearchText] = (0, _react.useState)(''); const [selected, setSelected] = (0, _react.useState)([]); const pageSize = 6; const { onChange } = props; const onSave = () => { onChange(selected); }; const onCancel = () => { onChange([]); }; const onSearchBoxChange = async searchInput => { setSearchText(searchInput); setCurrentPage(1); }; const onVideoMetaChange = videoEntityWithMeta => { setSelected([videoEntityWithMeta]); }; const onVideosGridSelect = videoEntity => { setSelected(selected => { const filterdSelected = selected.filter(ele => { var _ele$video; return ((_ele$video = ele.video) === null || _ele$video === void 0 ? void 0 : _ele$video.id) !== videoEntity.id; }); // deselect the video if (filterdSelected.length !== selected.length) { return filterdSelected; } // single select return [{ video: videoEntity, desc: '' }]; }); }; const selectedVideos = selected.map(ele => { return ele.video; }); (0, _react.useEffect)(() => { if (currentPage !== 0) { queryVideos({ variables: { searchText: searchText, skip: (currentPage - 1) * pageSize, take: pageSize } }); } }, [currentPage, searchText]); let searchResult = /*#__PURE__*/_react.default.createElement(_react.Fragment, null, /*#__PURE__*/_react.default.createElement(VideosGrids, { videos: videos, selected: selectedVideos, onSelect: onVideosGridSelect }), /*#__PURE__*/_react.default.createElement(_pagination.Pagination, { currentPage: currentPage, total: videosCount, pageSize: pageSize, onChange: pageIndex => { setCurrentPage(pageIndex); } })); if (loading) { searchResult = /*#__PURE__*/_react.default.createElement("p", null, "searching..."); } if (error) { var _videosQuery$loc; searchResult = /*#__PURE__*/_react.default.createElement(ErrorWrapper, null, /*#__PURE__*/_react.default.createElement("h3", null, "Errors occurs in the `videos` query"), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement("b", null, "Message:"), /*#__PURE__*/_react.default.createElement("div", null, error.message), /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement("b", null, "Stack:"), /*#__PURE__*/_react.default.createElement("div", null, error.stack), /*#__PURE__*/_react.default.createElement("br", null), /*#__PURE__*/_react.default.createElement("b", null, "Query:"), /*#__PURE__*/_react.default.createElement("pre", null, (_videosQuery$loc = videosQuery.loc) === null || _videosQuery$loc === void 0 ? void 0 : _videosQuery$loc.source.body))); } return /*#__PURE__*/_react.default.createElement(_modals.DrawerController, { isOpen: true }, /*#__PURE__*/_react.default.createElement(_modals.Drawer, { title: "Select video", actions: { cancel: { label: 'Cancel', action: onCancel }, confirm: { label: 'Confirm', action: onSave } } }, /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement(VideoSearchBox, { onChange: onSearchBoxChange }), /*#__PURE__*/_react.default.createElement(VideoSelectionWrapper, null, /*#__PURE__*/_react.default.createElement("div", null, searchResult), !!selected.length && /*#__PURE__*/_react.default.createElement(SeparationLine, null), /*#__PURE__*/_react.default.createElement(VideoMetaGrids, { videoMetas: selected, onChange: onVideoMetaChange }))))); }