mirror of
https://github.com/mediacms-io/mediacms.git
synced 2025-12-07 20:52:30 -05:00
* Test
Messing around to figure out docker and whatnot
* Revert "Test"
This reverts commit 43b76932c5.
* Update docker dev yaml
Update the docker to the environement with the latest version of selenium (and their new arguments), and to be on firefox
* Timestamp on play
Adds the a one time event that jumps to a timestamp if there is a t parameter in the URL
* Timestamp when sharing DRAFT
First draft to show the timestamp when sharing. Missing checkbox and appending the get param to shown link
* Checkbox and update share url
Checkbox show a clean timestamp and the media URL updates with the correct timestamp upon selection
* Cleaning before PR
removing un-necessary modified files
* Clean up before PR - remove statics
* Timestamp in comments
Parse the comments to wrap timestamps with an appropriate anchor
* Forgotten comments and console.logs
* Last touch for PR
- Cleaning media.js for PR
- Using MediaPageStore instead of window.location when wrapping the timestamp in comments
* Screenshot
Adding the screenshot for the user_docs
* PR amends
Amending VideoPlayer componnent to take check if the Get param 't' is a number, and to keep it within the duration of the video.
Required to change the listener from 'play' to 'loadedmetadata' to have access to the video duration (otherwise it was too early)
Also changed the User_doc file to inform users of the timestamp function
333 lines
9.9 KiB
JavaScript
333 lines
9.9 KiB
JavaScript
import React, { useRef, useState, useEffect } from 'react';
|
|
import { ShareOptionsContext } from '../../utils/contexts/';
|
|
import { PageStore, MediaPageStore } from '../../utils/stores/';
|
|
import { PageActions, MediaPageActions } from '../../utils/actions/';
|
|
import ItemsInlineSlider from '../item-list/includes/itemLists/ItemsInlineSlider';
|
|
import { CircleIconButton } from '../_shared/';
|
|
|
|
function shareOptionsList() {
|
|
const socialMedia = ShareOptionsContext._currentValue;
|
|
const mediaUrl = MediaPageStore.get('media-url');
|
|
const mediaTitle = MediaPageStore.get('media-data').title;
|
|
|
|
const ret = {};
|
|
|
|
let i = 0;
|
|
|
|
while (i < socialMedia.length) {
|
|
switch (socialMedia[i]) {
|
|
case 'embed':
|
|
if ('video' === MediaPageStore.get('media-data').media_type) {
|
|
ret[socialMedia[i]] = {};
|
|
}
|
|
break;
|
|
case 'email':
|
|
ret[socialMedia[i]] = {
|
|
title: 'Email',
|
|
shareUrl: 'mailto:?body=' + mediaUrl,
|
|
};
|
|
break;
|
|
case 'fb':
|
|
ret[socialMedia[i]] = {
|
|
title: 'Facebook',
|
|
shareUrl: 'https://www.facebook.com/sharer.php?u=' + mediaUrl,
|
|
};
|
|
break;
|
|
case 'tw':
|
|
ret[socialMedia[i]] = {
|
|
title: 'Twitter',
|
|
shareUrl: 'https://twitter.com/intent/tweet?url=' + mediaUrl,
|
|
};
|
|
break;
|
|
case 'reddit':
|
|
ret[socialMedia[i]] = {
|
|
title: 'reddit',
|
|
shareUrl: 'https://reddit.com/submit?url=' + mediaUrl + '&title=' + mediaTitle,
|
|
};
|
|
break;
|
|
case 'tumblr':
|
|
ret[socialMedia[i]] = {
|
|
title: 'Tumblr',
|
|
shareUrl: 'https://www.tumblr.com/widgets/share/tool?canonicalUrl=' + mediaUrl + '&title=' + mediaTitle,
|
|
};
|
|
break;
|
|
case 'pinterest':
|
|
ret[socialMedia[i]] = {
|
|
title: 'Pinterest',
|
|
shareUrl: 'http://pinterest.com/pin/create/link/?url=' + mediaUrl,
|
|
};
|
|
break;
|
|
case 'vk':
|
|
ret[socialMedia[i]] = {
|
|
title: 'ВКонтакте',
|
|
shareUrl: 'http://vk.com/share.php?url=' + mediaUrl + '&title=' + mediaTitle,
|
|
};
|
|
break;
|
|
case 'linkedin':
|
|
ret[socialMedia[i]] = {
|
|
title: 'LinkedIn',
|
|
shareUrl: 'https://www.linkedin.com/shareArticle?mini=true&url=' + mediaUrl,
|
|
};
|
|
break;
|
|
case 'mix':
|
|
ret[socialMedia[i]] = {
|
|
title: 'Mix',
|
|
shareUrl: 'https://mix.com/add?url=' + mediaUrl,
|
|
};
|
|
break;
|
|
case 'whatsapp':
|
|
ret[socialMedia[i]] = {
|
|
title: 'WhatsApp',
|
|
shareUrl: 'whatsapp://send?text=' + mediaUrl,
|
|
};
|
|
break;
|
|
case 'telegram':
|
|
ret[socialMedia[i]] = {
|
|
title: 'Telegram',
|
|
shareUrl: 'https://t.me/share/url?url=' + mediaUrl + '&text=' + mediaTitle,
|
|
};
|
|
break;
|
|
}
|
|
|
|
i += 1;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
function ShareOptions() {
|
|
const shareOptions = shareOptionsList();
|
|
|
|
const compList = [];
|
|
|
|
for (let k in shareOptions) {
|
|
if (shareOptions.hasOwnProperty(k)) {
|
|
if (k === 'embed') {
|
|
compList.push(
|
|
<div key={'share-' + k} className={'sh-option share-' + k + '-opt'}>
|
|
<button className="sh-option change-page" data-page-id="shareEmbed">
|
|
<span>
|
|
<i className="material-icons">code</i>
|
|
</span>
|
|
<span>Embed</span>
|
|
</button>
|
|
</div>
|
|
);
|
|
} else if (k === 'whatsapp') {
|
|
compList.push(
|
|
<div key={'share-' + k} className={'sh-option share-' + k}>
|
|
<a
|
|
href={shareOptions[k].shareUrl}
|
|
title=""
|
|
target="_blank"
|
|
data-action="share/whatsapp/share"
|
|
rel="noreferrer"
|
|
>
|
|
<span></span>
|
|
<span>{shareOptions[k].title}</span>
|
|
</a>
|
|
</div>
|
|
);
|
|
} else if (k === 'email') {
|
|
compList.push(
|
|
<div key="share-email" className="sh-option share-email">
|
|
<a href={shareOptions[k].shareUrl} title="">
|
|
<span>
|
|
<i className="material-icons">email</i>
|
|
</span>
|
|
<span>{shareOptions[k].title}</span>
|
|
</a>
|
|
</div>
|
|
);
|
|
} else {
|
|
compList.push(
|
|
<div key={'share-' + k} className={'sh-option share-' + k}>
|
|
<a href={shareOptions[k].shareUrl} title="" target="_blank" rel="noreferrer">
|
|
<span></span>
|
|
<span>{shareOptions[k].title}</span>
|
|
</a>
|
|
</div>
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
return compList;
|
|
}
|
|
|
|
function NextSlideButton({ onClick }) {
|
|
return (
|
|
<span className="next-slide">
|
|
<CircleIconButton buttonShadow={true} onClick={onClick}>
|
|
<i className="material-icons">keyboard_arrow_right</i>
|
|
</CircleIconButton>
|
|
</span>
|
|
);
|
|
}
|
|
|
|
function PreviousSlideButton({ onClick }) {
|
|
return (
|
|
<span className="previous-slide">
|
|
<CircleIconButton buttonShadow={true} onClick={onClick}>
|
|
<i className="material-icons">keyboard_arrow_left</i>
|
|
</CircleIconButton>
|
|
</span>
|
|
);
|
|
}
|
|
|
|
function updateDimensions() {
|
|
return {
|
|
maxFormContentHeight: window.innerHeight - (56 + 4 * 24 + 44),
|
|
maxPopupWidth: 518 > window.innerWidth - 2 * 40 ? window.innerWidth - 2 * 40 : null,
|
|
};
|
|
}
|
|
|
|
function getTimestamp() {
|
|
const videoPlayer = document.getElementsByTagName("video");
|
|
return videoPlayer[0]?.currentTime;
|
|
}
|
|
|
|
function ToHHMMSS (timeInt) {
|
|
let sec_num = parseInt(timeInt, 10);
|
|
let hours = Math.floor(sec_num / 3600);
|
|
let minutes = Math.floor((sec_num - (hours * 3600)) / 60);
|
|
let seconds = sec_num - (hours * 3600) - (minutes * 60);
|
|
|
|
if (hours < 10) {hours = "0"+hours;}
|
|
if (minutes < 10) {minutes = "0"+minutes;}
|
|
if (seconds < 10) {seconds = "0"+seconds;}
|
|
return hours >= 1 ? hours + ':' + minutes + ':' + seconds : minutes + ':' + seconds;
|
|
}
|
|
|
|
export function MediaShareOptions(props) {
|
|
const containerRef = useRef(null);
|
|
const shareOptionsInnerRef = useRef(null);
|
|
const mediaUrl = MediaPageStore.get('media-url');
|
|
|
|
const [inlineSlider, setInlineSlider] = useState(null);
|
|
const [sliderButtonsVisible, setSliderButtonsVisible] = useState({ prev: false, next: false });
|
|
|
|
const [dimensions, setDimensions] = useState(updateDimensions());
|
|
const [shareOptions] = useState(ShareOptions());
|
|
|
|
const [timestamp, setTimestamp] = useState(0);
|
|
const [formattedTimestamp, setFormattedTimestamp] = useState(0);
|
|
const [startAtSelected, setStartAtSelected] = useState(false);
|
|
|
|
const [shareMediaLink, setShareMediaLink] = useState(mediaUrl);
|
|
|
|
function onWindowResize() {
|
|
setDimensions(updateDimensions());
|
|
}
|
|
|
|
function onClickCopyMediaLink() {
|
|
MediaPageActions.copyShareLink(containerRef.current.querySelector('.copy-field input'));
|
|
}
|
|
|
|
function onCompleteCopyMediaLink() {
|
|
// FIXME: Without delay throws conflict error [ Uncaught Error: Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch. ].
|
|
setTimeout(function () {
|
|
PageActions.addNotification('Link copied to clipboard', 'clipboardLinkCopy');
|
|
}, 100);
|
|
}
|
|
|
|
function updateSlider() {
|
|
inlineSlider.scrollToCurrentSlide();
|
|
updateSliderButtonsView();
|
|
}
|
|
|
|
function updateSliderButtonsView() {
|
|
setSliderButtonsVisible({
|
|
prev: inlineSlider.hasPreviousSlide(),
|
|
next: inlineSlider.hasNextSlide(),
|
|
});
|
|
}
|
|
|
|
function updateStartAtCheckbox() {
|
|
setStartAtSelected(!startAtSelected);
|
|
updateShareMediaLink();
|
|
}
|
|
|
|
function updateShareMediaLink()
|
|
{
|
|
const newLink = startAtSelected ? mediaUrl : mediaUrl + "&t=" + Math.trunc(timestamp);
|
|
setShareMediaLink(newLink);
|
|
}
|
|
|
|
function nextSlide() {
|
|
inlineSlider.nextSlide();
|
|
updateSlider();
|
|
}
|
|
|
|
function prevSlide() {
|
|
inlineSlider.previousSlide();
|
|
updateSlider();
|
|
}
|
|
|
|
useEffect(() => {
|
|
setInlineSlider(new ItemsInlineSlider(shareOptionsInnerRef.current, '.sh-option'));
|
|
}, [shareOptions]);
|
|
|
|
useEffect(() => {
|
|
if (inlineSlider) {
|
|
inlineSlider.updateDataStateOnResize(shareOptions.length, true, true);
|
|
updateSlider();
|
|
}
|
|
}, [dimensions, inlineSlider]);
|
|
|
|
useEffect(() => {
|
|
PageStore.on('window_resize', onWindowResize);
|
|
MediaPageStore.on('copied_media_link', onCompleteCopyMediaLink);
|
|
|
|
const localTimestamp = getTimestamp();
|
|
setTimestamp(localTimestamp);
|
|
setFormattedTimestamp(ToHHMMSS(localTimestamp));
|
|
|
|
return () => {
|
|
PageStore.removeListener('window_resize', onWindowResize);
|
|
MediaPageStore.removeListener('copied_media_link', onCompleteCopyMediaLink);
|
|
setInlineSlider(null);
|
|
};
|
|
}, []);
|
|
|
|
return (
|
|
<div
|
|
ref={containerRef}
|
|
style={null !== dimensions.maxPopupWidth ? { maxWidth: dimensions.maxPopupWidth + 'px' } : null}
|
|
>
|
|
<div
|
|
className="scrollable-content"
|
|
style={null !== dimensions.maxFormContentHeight ? { maxHeight: dimensions.maxFormContentHeight + 'px' } : null}
|
|
>
|
|
<div className="share-popup-title">Share media</div>
|
|
{shareOptions.length ? (
|
|
<div className="share-options">
|
|
{sliderButtonsVisible.prev ? <PreviousSlideButton onClick={prevSlide} /> : null}
|
|
<div ref={shareOptionsInnerRef} className="share-options-inner">
|
|
{shareOptions}
|
|
</div>
|
|
{sliderButtonsVisible.next ? <NextSlideButton onClick={nextSlide} /> : null}
|
|
</div>
|
|
) : null}
|
|
</div>
|
|
<div className="copy-field">
|
|
<div>
|
|
<input type="text" readOnly value={shareMediaLink} />
|
|
<button onClick={onClickCopyMediaLink}>COPY</button>
|
|
</div>
|
|
</div>
|
|
<div className="start-at">
|
|
<label>
|
|
<input
|
|
type="checkbox"
|
|
name="start-at-checkbox"
|
|
id="id-start-at-checkbox"
|
|
checked={startAtSelected}
|
|
onChange={updateStartAtCheckbox}
|
|
/>
|
|
Start at {formattedTimestamp}
|
|
</label>
|
|
</div>
|
|
</div>
|
|
);
|
|
} |