mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-05 20:59:49 +00:00
180 lines
6.4 KiB
JavaScript
180 lines
6.4 KiB
JavaScript
// Copyright (C) 2017-2023 Smart code 203358507
|
|
|
|
const React = require('react');
|
|
const PropTypes = require('prop-types');
|
|
const classnames = require('classnames');
|
|
const { useTranslation } = require('react-i18next');
|
|
const { usePlatform, useToast } = require('stremio/common');
|
|
const { useServices } = require('stremio/services');
|
|
const Option = require('./Option');
|
|
const styles = require('./styles');
|
|
|
|
const OptionsMenu = React.memo(React.forwardRef(({ className, stream, playbackDevices, extraSubtitlesTracks, selectedExtraSubtitlesTrackId }, ref) => {
|
|
const { t } = useTranslation();
|
|
const { core } = useServices();
|
|
const platform = usePlatform();
|
|
const toast = useToast();
|
|
const [streamingUrl, downloadUrl, magnetUrl] = React.useMemo(() => {
|
|
return stream !== null ?
|
|
stream.deepLinks &&
|
|
stream.deepLinks.externalPlayer &&
|
|
[
|
|
stream.deepLinks.externalPlayer.streaming,
|
|
stream.deepLinks.externalPlayer.download,
|
|
stream.deepLinks.externalPlayer.magnet,
|
|
]
|
|
:
|
|
[null, null, null];
|
|
}, [stream]);
|
|
const externalDevices = React.useMemo(() => {
|
|
return playbackDevices.filter(({ type }) => type === 'external');
|
|
}, [playbackDevices]);
|
|
|
|
const subtitlesTrackUrl = React.useMemo(() => {
|
|
const track = extraSubtitlesTracks?.find(({ id }) => id === selectedExtraSubtitlesTrackId);
|
|
return track?.fallbackUrl ?? track?.url ?? null;
|
|
}, [extraSubtitlesTracks, selectedExtraSubtitlesTrackId]);
|
|
|
|
const onCopyStreamButtonClick = React.useCallback(() => {
|
|
if (streamingUrl || downloadUrl) {
|
|
navigator.clipboard.writeText(streamingUrl || downloadUrl)
|
|
.then(() => {
|
|
toast.show({
|
|
type: 'success',
|
|
title: 'Copied',
|
|
message: t('PLAYER_COPY_STREAM_SUCCESS'),
|
|
timeout: 3000
|
|
});
|
|
})
|
|
.catch((e) => {
|
|
console.error(e);
|
|
toast.show({
|
|
type: 'error',
|
|
title: t('ERROR'),
|
|
message: `${t('PLAYER_COPY_STREAM_ERROR')}: ${streamingUrl || downloadUrl}`,
|
|
timeout: 3000
|
|
});
|
|
});
|
|
}
|
|
}, [streamingUrl, downloadUrl]);
|
|
const onCopyMagnetButtonClick = React.useCallback(() => {
|
|
if (magnetUrl) {
|
|
navigator.clipboard.writeText(magnetUrl)
|
|
.then(() => {
|
|
toast.show({
|
|
type: 'success',
|
|
title: 'Copied',
|
|
message: t('PLAYER_COPY_MAGNET_LINK_SUCCESS'),
|
|
timeout: 3000
|
|
});
|
|
})
|
|
.catch((e) => {
|
|
console.error(e);
|
|
toast.show({
|
|
type: 'error',
|
|
title: t('Error'),
|
|
message: `${t('PLAYER_COPY_MAGNET_LINK_ERROR')}: ${magnetUrl}`,
|
|
timeout: 3000
|
|
});
|
|
});
|
|
}
|
|
}, [magnetUrl]);
|
|
const onDownloadVideoButtonClick = React.useCallback(() => {
|
|
if (downloadUrl) {
|
|
platform.openExternal(downloadUrl);
|
|
}
|
|
}, [downloadUrl]);
|
|
|
|
const onDownloadSubtitlesClick = React.useCallback(() => {
|
|
subtitlesTrackUrl && platform.openExternal(subtitlesTrackUrl);
|
|
}, [subtitlesTrackUrl]);
|
|
|
|
const onExternalDeviceRequested = React.useCallback((deviceId) => {
|
|
if (streamingUrl) {
|
|
core.transport.dispatch({
|
|
action: 'StreamingServer',
|
|
args: {
|
|
action: 'PlayOnDevice',
|
|
args: {
|
|
device: deviceId,
|
|
source: streamingUrl,
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}, [streamingUrl]);
|
|
const onMouseDown = React.useCallback((event) => {
|
|
event.nativeEvent.optionsMenuClosePrevented = true;
|
|
}, []);
|
|
|
|
return (
|
|
<div ref={ref} className={classnames(className, styles['options-menu-container'])} onMouseDown={onMouseDown}>
|
|
{
|
|
streamingUrl || downloadUrl ?
|
|
<Option
|
|
icon={'link'}
|
|
label={t('CTX_COPY_STREAM_LINK')}
|
|
disabled={stream === null}
|
|
onClick={onCopyStreamButtonClick}
|
|
/>
|
|
:
|
|
null
|
|
}
|
|
{
|
|
magnetUrl ?
|
|
<Option
|
|
icon={'magnet-link'}
|
|
label={t('CTX_COPY_MAGNET_LINK')}
|
|
disabled={stream === null}
|
|
onClick={onCopyMagnetButtonClick}
|
|
/>
|
|
:
|
|
null
|
|
}
|
|
{
|
|
downloadUrl ?
|
|
<Option
|
|
icon={'download'}
|
|
label={t('CTX_DOWNLOAD_VIDEO')}
|
|
disabled={stream === null}
|
|
onClick={onDownloadVideoButtonClick}
|
|
/>
|
|
:
|
|
null
|
|
}
|
|
{
|
|
subtitlesTrackUrl ?
|
|
<Option
|
|
icon={'download'}
|
|
label={t('CTX_DOWNLOAD_SUBS')}
|
|
disabled={stream === null}
|
|
onClick={onDownloadSubtitlesClick}
|
|
/>
|
|
:
|
|
null
|
|
}
|
|
{
|
|
streamingUrl && externalDevices.map(({ id, name }) => (
|
|
<Option
|
|
key={id}
|
|
icon={'vlc'}
|
|
label={t('PLAYER_PLAY_IN', { device: name })}
|
|
deviceId={id}
|
|
disabled={stream === null}
|
|
onClick={onExternalDeviceRequested}
|
|
/>
|
|
))
|
|
}
|
|
</div>
|
|
);
|
|
}));
|
|
|
|
OptionsMenu.propTypes = {
|
|
className: PropTypes.string,
|
|
stream: PropTypes.object,
|
|
playbackDevices: PropTypes.array,
|
|
extraSubtitlesTracks: PropTypes.array,
|
|
selectedExtraSubtitlesTrackId: PropTypes.string,
|
|
};
|
|
|
|
module.exports = OptionsMenu;
|