diff --git a/renderer/lib/cast.js b/renderer/lib/cast.js index 0a01c6cf..1ae11044 100644 --- a/renderer/lib/cast.js +++ b/renderer/lib/cast.js @@ -3,14 +3,14 @@ // * Starts and stops casting, provides remote video controls module.exports = { init, - open, - close, + toggleMenu, + selectDevice, + stop, play, pause, seek, setVolume, - setRate, - selectDevice + setRate } var airplayer = require('airplayer')() @@ -48,8 +48,8 @@ function init (appState, callback) { state.devices.dlna.addDevice(device) }) - airplayer.on('update', function (player) { - state.devices.airplay.addDevice(player) + airplayer.on('update', function (device) { + state.devices.airplay.addDevice(device) }) } @@ -332,24 +332,30 @@ function startStatusInterval () { }, 1000) } -function open (location) { +/* + * Shows the device menu for a given cast type ('chromecast', 'airplay', etc) + * The menu lists eg. all Chromecasts detected; the user can click one to cast. + * If the menu was already showing for that type, hides the menu. + */ +function toggleMenu (location) { + // If the menu is already showing, hide it + if (state.devices.castMenu && state.devices.castMenu.location === location) { + state.devices.castMenu = null + return + } + + // Never cast to two devices at the same time if (state.playing.location !== 'local') { throw new Error('You can\'t connect to ' + location + ' when already connected to another device') } + // Find all cast devices of the given type var player = getPlayer(location) var devices = player ? player.getDevices() : [] if (devices.length === 0) throw new Error('No ' + location + ' devices available') // Show a menu state.devices.castMenu = {location, devices} - - /* if (devices.length === 1) { - // Start casting to the only available Chromecast, Airplay, or DNLA device - openDevice(location, devices[0]) - } else { - // Show a menu - } */ } function selectDevice (index) { @@ -370,10 +376,13 @@ function selectDevice (index) { } // Stops casting, move video back to local screen -function close () { +function stop () { var player = getPlayer() if (player) { - player.stop(stoppedCasting) + player.stop(function () { + player.device = null + stoppedCasting() + }) clearInterval(statusInterval) } else { stoppedCasting() diff --git a/renderer/lib/state.js b/renderer/lib/state.js index 7d88ae40..a52849f5 100644 --- a/renderer/lib/state.js +++ b/renderer/lib/state.js @@ -32,10 +32,7 @@ function getDefaultState () { }, selectedInfoHash: null, /* the torrent we've selected to view details. see state.torrents */ playing: getDefaultPlayState(), /* the media (audio or video) that we're currently playing */ - devices: { /* playback devices like Chromecast and AppleTV */ - airplay: null, /* airplay client. finds and manages AppleTVs */ - chromecast: null /* chromecast client. finds and manages Chromecasts */ - }, + devices: {}, /* playback devices like Chromecast and AppleTV */ dock: { badge: 0, progress: 0 diff --git a/renderer/main.css b/renderer/main.css index 195b1748..9f64c957 100644 --- a/renderer/main.css +++ b/renderer/main.css @@ -848,7 +848,7 @@ body.drag .app::after { height: 14px; } -.player .controls .subtitles-list { +.player .controls .options-list { position: fixed; background: rgba(40, 40, 40, 0.8); min-width: 100px; @@ -862,7 +862,7 @@ body.drag .app::after { color: rgba(255, 255, 255, 0.8); } -.player .controls .subtitles-list .icon { +.player .controls .options-list .icon { display: inline; font-size: 17px; vertical-align: bottom; diff --git a/renderer/main.js b/renderer/main.js index a5988416..00285762 100644 --- a/renderer/main.js +++ b/renderer/main.js @@ -197,14 +197,14 @@ function dispatch (action, ...args) { if (action === 'openTorrentContextMenu') { openTorrentContextMenu(args[0] /* infoHash */) } - if (action === 'startCasting') { - lazyLoadCast().open(args[0] /* deviceType */) + if (action === 'toggleCastMenu') { + lazyLoadCast().toggleMenu(args[0] /* deviceType */) } if (action === 'selectCastDevice') { lazyLoadCast().selectDevice(args[0] /* index */) } - if (action === 'closeDevice') { - lazyLoadCast().close() + if (action === 'stopCasting') { + lazyLoadCast().stop() } if (action === 'setDimensions') { setDimensions(args[0] /* dimensions */) diff --git a/renderer/views/player.js b/renderer/views/player.js index b9e2bb37..757cc192 100644 --- a/renderer/views/player.js +++ b/renderer/views/player.js @@ -309,10 +309,6 @@ function renderCastOptions (state) { var items = devices.map(function (device, ix) { var isSelected = player.device === device var name = device.name - // Workaround: the Airplay module produces ugly names - if (name.endsWith('._airplay._tcp.local')) { - name = name.substring(0, name.length - '._airplay._tcp.local'.length) - } return hx`