mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-20 10:42:12 +00:00
feat: allow to drop local subtitles
This commit is contained in:
parent
89b6526555
commit
3df8eb65d0
7 changed files with 74 additions and 5 deletions
|
|
@ -41,6 +41,11 @@ const ICON_FOR_TYPE = new Map([
|
|||
['other', 'movies'],
|
||||
]);
|
||||
|
||||
const SUPPORTED_LOCAL_SUBTITLES = [
|
||||
'application/x-subrip',
|
||||
'text/vtt',
|
||||
];
|
||||
|
||||
const EXTERNAL_PLAYERS = [
|
||||
{
|
||||
label: 'EXTERNAL_PLAYER_DISABLED',
|
||||
|
|
@ -113,6 +118,7 @@ module.exports = {
|
|||
WRITERS_LINK_CATEGORY,
|
||||
TYPE_PRIORITIES,
|
||||
ICON_FOR_TYPE,
|
||||
SUPPORTED_LOCAL_SUBTITLES,
|
||||
EXTERNAL_PLAYERS,
|
||||
WHITELISTED_HOSTS,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ const languages = require('./languages');
|
|||
const routesRegexp = require('./routesRegexp');
|
||||
const useAnimationFrame = require('./useAnimationFrame');
|
||||
const useBinaryState = require('./useBinaryState');
|
||||
const { default: onFileDrop } = require('./onFileDrop');
|
||||
const useFullscreen = require('./useFullscreen');
|
||||
const useLiveRef = require('./useLiveRef');
|
||||
const useModelState = require('./useModelState');
|
||||
|
|
@ -41,6 +42,7 @@ module.exports = {
|
|||
routesRegexp,
|
||||
useAnimationFrame,
|
||||
useBinaryState,
|
||||
onFileDrop,
|
||||
useFullscreen,
|
||||
useLiveRef,
|
||||
useModelState,
|
||||
|
|
|
|||
31
src/common/onFileDrop.ts
Normal file
31
src/common/onFileDrop.ts
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
import { useEffect } from 'react';
|
||||
|
||||
const onFileDrop = (types: string[], callback: (file: File) => void) => {
|
||||
const onDragOver = (event: DragEvent) => {
|
||||
event.preventDefault();
|
||||
};
|
||||
|
||||
const onDrop = (event: DragEvent) => {
|
||||
event.preventDefault();
|
||||
|
||||
if (event.dataTransfer && event.dataTransfer.files.length > 0) {
|
||||
const file = event.dataTransfer.files[0];
|
||||
|
||||
if (types.includes(file.type)) {
|
||||
callback(file);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
window.addEventListener('dragover', onDragOver);
|
||||
window.addEventListener('drop', onDrop);
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('dragover', onDragOver);
|
||||
window.removeEventListener('drop', onDrop);
|
||||
};
|
||||
}, []);
|
||||
};
|
||||
|
||||
export default onFileDrop;
|
||||
|
|
@ -8,7 +8,7 @@ const langs = require('langs');
|
|||
const { useTranslation } = require('react-i18next');
|
||||
const { useRouteFocused } = require('stremio-router');
|
||||
const { useServices } = require('stremio/services');
|
||||
const { useFullscreen, useBinaryState, useToast, useStreamingServer, withCoreSuspender } = require('stremio/common');
|
||||
const { onFileDrop, useFullscreen, useBinaryState, useToast, useStreamingServer, withCoreSuspender, CONSTANTS } = require('stremio/common');
|
||||
const { HorizontalNavBar, Transition } = require('stremio/components');
|
||||
const BufferingLoader = require('./BufferingLoader');
|
||||
const VolumeChangeIndicator = require('./VolumeChangeIndicator');
|
||||
|
|
@ -133,7 +133,10 @@ const Player = ({ urlParams, queryParams }) => {
|
|||
toast.show({
|
||||
type: 'success',
|
||||
title: t('PLAYER_SUBTITLES_LOADED'),
|
||||
message: track.exclusive ? t('PLAYER_SUBTITLES_LOADED_EXCLUSIVE') : t('PLAYER_SUBTITLES_LOADED_ORIGIN', { origin: track.origin }),
|
||||
message:
|
||||
track.exclusive ? t('PLAYER_SUBTITLES_LOADED_EXCLUSIVE') :
|
||||
track.local ? t('PLAYER_SUBTITLES_LOADED_LOCAL') :
|
||||
t('PLAYER_SUBTITLES_LOADED_ORIGIN', { origin: track.origin }),
|
||||
timeout: 3000
|
||||
});
|
||||
}, []);
|
||||
|
|
@ -270,6 +273,11 @@ const Player = ({ urlParams, queryParams }) => {
|
|||
event.nativeEvent.immersePrevented = true;
|
||||
}, []);
|
||||
|
||||
onFileDrop(CONSTANTS.SUPPORTED_LOCAL_SUBTITLES, async (file) => {
|
||||
const buffer = await file.arrayBuffer();
|
||||
video.addLocalSubtitles(file.name, buffer);
|
||||
});
|
||||
|
||||
React.useEffect(() => {
|
||||
setError(null);
|
||||
video.unload();
|
||||
|
|
|
|||
|
|
@ -10,11 +10,13 @@ const styles = require('./styles');
|
|||
const { t } = require('i18next');
|
||||
|
||||
const ORIGIN_PRIORITIES = {
|
||||
'LOCAL': 3,
|
||||
'EMBEDDED': 2,
|
||||
'EXCLUSIVE': 1
|
||||
'EXCLUSIVE': 1,
|
||||
};
|
||||
const LANGUAGE_PRIORITIES = {
|
||||
'eng': 1
|
||||
'local': 2,
|
||||
'eng': 1,
|
||||
};
|
||||
|
||||
const SubtitlesMenu = React.memo((props) => {
|
||||
|
|
@ -161,7 +163,11 @@ const SubtitlesMenu = React.memo((props) => {
|
|||
</Button>
|
||||
{subtitlesLanguages.map((lang, index) => (
|
||||
<Button key={index} title={languages.label(lang)} className={classnames(styles['language-option'], { 'selected': selectedSubtitlesLanguage === lang })} data-lang={lang} onClick={subtitlesLanguageOnClick}>
|
||||
<div className={styles['language-label']}>{languages.label(lang)}</div>
|
||||
<div className={styles['language-label']}>
|
||||
{
|
||||
lang === 'local' ? t('LOCAL_SUBTITLES') : languages.label(lang)
|
||||
}
|
||||
</div>
|
||||
{
|
||||
selectedSubtitlesLanguage === lang ?
|
||||
<div className={styles['icon']} />
|
||||
|
|
|
|||
|
|
@ -79,6 +79,17 @@ const useVideo = () => {
|
|||
});
|
||||
};
|
||||
|
||||
const addLocalSubtitles = (filename, buffer) => {
|
||||
dispatch({
|
||||
type: 'command',
|
||||
commandName: 'addLocalSubtitles',
|
||||
commandArgs: {
|
||||
filename,
|
||||
buffer,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const setProp = (name, value) => {
|
||||
dispatch({ type: 'setProp', propName: name, propValue: value });
|
||||
};
|
||||
|
|
@ -136,6 +147,7 @@ const useVideo = () => {
|
|||
load,
|
||||
unload,
|
||||
addExtraSubtitlesTracks,
|
||||
addLocalSubtitles,
|
||||
setProp,
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -36,6 +36,10 @@ function DragAndDrop({ core }) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case 'application/x-subrip':
|
||||
break;
|
||||
case 'text/vtt':
|
||||
break;
|
||||
default: {
|
||||
events.emit('error', {
|
||||
message: 'Unsupported file',
|
||||
|
|
|
|||
Loading…
Reference in a new issue