show notifications while processing a dropped torrent file

This commit is contained in:
nklhrstv 2022-10-18 13:39:02 +03:00
parent f8303c1be9
commit da1db50108
6 changed files with 165 additions and 39 deletions

View file

@ -3,10 +3,10 @@
require('spatial-navigation-polyfill');
const React = require('react');
const { Router } = require('stremio-router');
const { Core, Shell, Chromecast, KeyboardShortcuts, ServicesProvider } = require('stremio/services');
const { Core, Shell, Chromecast, DragAndDrop, KeyboardShortcuts, ServicesProvider } = require('stremio/services');
const { NotFound } = require('stremio/routes');
const { ToastProvider, CONSTANTS } = require('stremio/common');
const CoreEventsToaster = require('./CoreEventsToaster');
const ServicesToaster = require('./ServicesToaster');
const ErrorDialog = require('./ErrorDialog');
const routerViewsConfig = require('./routerViewsConfig');
const styles = require('./styles');
@ -15,15 +15,19 @@ const App = () => {
const onPathNotMatch = React.useCallback(() => {
return NotFound;
}, []);
const services = React.useMemo(() => ({
core: new Core({
const services = React.useMemo(() => {
const core = new Core({
appVersion: process.env.VERSION,
shellVersion: null
}),
shell: new Shell(),
chromecast: new Chromecast(),
keyboardShortcuts: new KeyboardShortcuts()
}), []);
});
return {
core,
shell: new Shell(),
chromecast: new Chromecast(),
keyboardShortcuts: new KeyboardShortcuts(),
dragAndDrop: new DragAndDrop({ core })
};
}, []);
const [initialized, setInitialized] = React.useState(false);
React.useEffect(() => {
let prevPath = window.location.hash.slice(1);
@ -71,12 +75,14 @@ const App = () => {
services.shell.start();
services.chromecast.start();
services.keyboardShortcuts.start();
services.dragAndDrop.start();
window.services = services;
return () => {
services.core.stop();
services.shell.stop();
services.chromecast.stop();
services.keyboardShortcuts.stop();
services.dragAndDrop.stop();
services.core.off('stateChanged', onCoreStateChanged);
services.shell.off('stateChanged', onShellStateChanged);
services.chromecast.off('stateChanged', onChromecastStateChange);
@ -107,7 +113,7 @@ const App = () => {
<ErrorDialog className={styles['error-container']} />
:
<ToastProvider className={styles['toasts-container']}>
<CoreEventsToaster />
<ServicesToaster />
<Router
className={styles['router']}
viewsConfig={routerViewsConfig}

View file

@ -1,29 +0,0 @@
// Copyright (C) 2017-2022 Smart code 203358507
const React = require('react');
const { useServices } = require('stremio/services');
const { useToast } = require('stremio/common');
const CoreEventsToaster = () => {
const { core } = useServices();
const toast = useToast();
React.useEffect(() => {
const onCoreEvent = ({ event, args }) => {
if (event === 'Error') {
toast.show({
type: 'error',
title: args.source.event,
message: args.error.message,
timeout: 4000
});
}
};
core.transport.on('CoreEvent', onCoreEvent);
return () => {
core.transport.off('CoreEvent', onCoreEvent);
};
}, []);
return null;
};
module.exports = CoreEventsToaster;

View file

@ -0,0 +1,49 @@
// Copyright (C) 2017-2022 Smart code 203358507
const React = require('react');
const { useServices } = require('stremio/services');
const { useToast } = require('stremio/common');
const ServicesToaster = () => {
const { core, dragAndDrop } = useServices();
const toast = useToast();
React.useEffect(() => {
const onCoreEvent = ({ event, args }) => {
if (event === 'Error') {
toast.show({
type: 'error',
title: args.source.event,
message: args.error.message,
timeout: 4000
});
}
};
const onDrop = (file) => {
toast.show({
type: 'alert',
title: 'Processing file',
message: file.name,
timeout: 4000
});
};
const onDragAndDropError = (error) => {
toast.show({
type: 'error',
title: error.message,
message: error.file?.name,
timeout: 4000
});
};
core.transport.on('CoreEvent', onCoreEvent);
dragAndDrop.on('drop', onDrop);
dragAndDrop.on('error', onDragAndDropError);
return () => {
core.transport.off('CoreEvent', onCoreEvent);
dragAndDrop.off('drop', onDrop);
dragAndDrop.off('error', onDragAndDropError);
};
}, []);
return null;
};
module.exports = ServicesToaster;

View file

@ -0,0 +1,93 @@
// Copyright (C) 2017-2022 Smart code 203358507
const EventEmitter = require('eventemitter3');
function DragAndDrop({ core }) {
let active = false;
const events = new EventEmitter();
function onDragOver(event) {
event.preventDefault();
}
async function onDrop(event) {
event.preventDefault();
if (event.dataTransfer.files instanceof FileList && event.dataTransfer.files.length > 0) {
const file = event.dataTransfer.files[0];
switch (file.type) {
case 'application/x-bittorrent': {
events.emit('drop', {
name: file.name,
type: file.type
});
try {
const torrent = await file.arrayBuffer();
core.transport.dispatch({
action: 'StreamingServer',
args: {
action: 'CreateTorrent',
args: Array.from(new Uint8Array(torrent))
}
});
} catch (error) {
events.emit('error', {
message: 'Failed to process file',
file: {
name: file.name,
type: file.type
}
});
}
break;
}
default: {
events.emit('error', {
message: 'Unsupported file',
file: {
name: file.name,
type: file.type
}
});
}
}
}
}
function onStateChanged() {
events.emit('stateChanged');
}
Object.defineProperties(this, {
active: {
configurable: false,
enumerable: true,
get: function() {
return active;
}
}
});
this.start = function() {
if (active) {
return;
}
window.addEventListener('dragover', onDragOver);
window.addEventListener('drop', onDrop);
active = true;
onStateChanged();
};
this.stop = function() {
window.removeEventListener('dragover', onDragOver);
window.removeEventListener('drop', onDrop);
active = false;
onStateChanged();
};
this.on = function(name, listener) {
events.on(name, listener);
};
this.off = function(name, listener) {
events.off(name, listener);
};
}
module.exports = DragAndDrop;

View file

@ -0,0 +1,5 @@
// Copyright (C) 2017-2022 Smart code 203358507
const DragAndDrop = require('./DragAndDrop');
module.exports = DragAndDrop;

View file

@ -2,6 +2,7 @@
const Chromecast = require('./Chromecast');
const Core = require('./Core');
const DragAndDrop = require('./DragAndDrop');
const KeyboardShortcuts = require('./KeyboardShortcuts');
const { ServicesProvider, useServices } = require('./ServicesContext');
const Shell = require('./Shell');
@ -9,6 +10,7 @@ const Shell = require('./Shell');
module.exports = {
Chromecast,
Core,
DragAndDrop,
KeyboardShortcuts,
ServicesProvider,
useServices,