diff --git a/.gitignore b/.gitignore index 37b63648..faf39252 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,4 @@ npm-debug.log test/unit/coverage test/e2e/reports selenium-debug.log - -npm-debug.log.3732580485 -npm-debug.log.2139949888 \ No newline at end of file +.idea/ diff --git a/package.json b/package.json index 895541b8..3385d9d0 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "scripts": { "dev": "node build/dev-server.js", "build": "node build/build.js", - "webapp": "node webapp.js", + "webapp": "node webapp.js -- ", "server": "node server.js", "unit": "karma start test/unit/karma.conf.js --single-run", "e2e": "node test/e2e/runner.js", @@ -15,6 +15,7 @@ "lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs" }, "dependencies": { + "args-parser": "^1.1.0", "bootstrap-sass": "^3.3.7", "connect-history-api-fallback": "^1.3.0", "cors": "^2.8.3", diff --git a/src/App.vue b/src/App.vue index 93469202..e24f68fe 100644 --- a/src/App.vue +++ b/src/App.vue @@ -7,13 +7,14 @@ \ No newline at end of file + diff --git a/src/components/application/plexbrowser/plexserver.vue b/src/components/application/plexbrowser/plexserver.vue index 626d067a..1868a803 100644 --- a/src/components/application/plexbrowser/plexserver.vue +++ b/src/components/application/plexbrowser/plexserver.vue @@ -7,7 +7,7 @@

Libraries

- +
diff --git a/src/components/join.vue b/src/components/join.vue index 422b612f..e03b1b98 100644 --- a/src/components/join.vue +++ b/src/components/join.vue @@ -1,7 +1,7 @@ - + diff --git a/src/components/signin.vue b/src/components/signin.vue index 1a9f5116..12f27012 100644 --- a/src/components/signin.vue +++ b/src/components/signin.vue @@ -1,5 +1,5 @@ @@ -142,13 +140,13 @@ export default { } request(options, callback); },2000) - } + } }) return }) } getPin() - + }, methods: { signout: function(){ @@ -161,7 +159,7 @@ export default { var that = this var base64encoded = new Buffer(this.user + ":" + this.pass).toString('base64') - + } } } diff --git a/src/store.js b/src/store.js index d7633df9..c37f6a6d 100644 --- a/src/store.js +++ b/src/store.js @@ -28,7 +28,7 @@ if(!getSetting('INIT')){ setSetting('CLIENTPOLLINTERVAL',1000) setSetting('DARKMODE',false) setSetting('SYNCMODE','cleanseek') - setSetting('SYNCFLEXABILITY',4000) + setSetting('SYNCFLEXABILITY',3000) setSetting('CUSTOMSERVER','http://') setSetting('INIT',true) } @@ -36,20 +36,20 @@ if(!getSetting('INIT')){ let _webapp_socket = null if (process.env.NODE_ENV == 'development'){ console.log('running in development') - /* + _webapp_socket = socketio.connect(''+window.location.hostname+':8088',{'forceNew':true,'connect timeout': 1000,path: '/ptweb/socket.io'}) _webapp_socket.on('connection',function(){ - }) + }) _webapp_socket.on('connect_error',function(){ - }) - */ + }) + } else { _webapp_socket = socketio.connect({'forceNew':true, - 'connect timeout': 1000,path: '/ptweb/socket.io'}) + 'connect timeout': 1000, path: '/ptweb/socket.io'}) _webapp_socket.on('connection',function(){ - }) + }) _webapp_socket.on('connect_error',function(){ - }) + }) } const state = { @@ -57,7 +57,7 @@ const state = { appTitle: 'PlexTogether', appVersion: '1.0.0', shownChat: false, - plex: null, + plex: null, chosenClient: null, chosenClientTimeSet: (new Date).getTime(), plexuser: JSON.parse(window['localStorage'].getItem('plexuser')), @@ -79,10 +79,10 @@ const state = { } const mutations = { - SET_CHOSENCLIENT(state,client){ + SET_CHOSENCLIENT(state,client){ function playbackChange(ratingKey){ console.log('Playback change!') - if (ratingKey != null) { + if (ratingKey != null) { // Playing something different! let server = state.plex.getServerById(state.chosenClient.lastTimelineObject.machineIdentifier) if (!server){ @@ -96,9 +96,9 @@ const mutations = { } if (metadata.type == 'movie'){ sendNotification('Now Playing: ' + metadata.title + ' from ' + state.plex.getServerById(metadata.machineIdentifier).name ) - } + } if (metadata.type == 'episode'){ - sendNotification('Now Playing: ' + metadata.grandparentTitle + ' S' + metadata.parentIndex + 'E' + metadata.index + ' from ' + state.plex.getServerById(metadata.machineIdentifier).name ) + sendNotification('Now Playing: ' + metadata.grandparentTitle + ' S' + metadata.parentIndex + 'E' + metadata.index + ' from ' + state.plex.getServerById(metadata.machineIdentifier).name) } state.chosenClient.clientPlayingMetadata = metadata }) @@ -106,7 +106,7 @@ const mutations = { state.chosenClient.clientPlayingMetadata = null } } - function newTimeline(timeline){ + function newTimeline(timeline){ console.log('Got timeline') if (!state.plextogether.connected){ return @@ -140,15 +140,15 @@ const mutations = { state.plextogether._socket.pollStartTime = (new Date).getTime() state.plextogether._socket.emit('poll',end_obj) } - - // Set up our client poller + + // Set up our client poller function clientPoller(time){ if (state.chosenClient == null){ return } if (state.chosenClientTimeSet != time){ - // We have a new chosen client, we need to stop - return + // We have a new chosen client, we need to stop + return } state.chosenClient.getTimeline(function(timeline){ //console.log(timeline) @@ -156,43 +156,43 @@ const mutations = { setTimeout(function(){ clientPoller(time) },state.CLIENTPOLLINTERVAL) - } + } // Check if we need to remove old handlers if (state.chosenClient){ - state.chosenClient.events.removeAllListeners(); + state.chosenClient.events.removeAllListeners(); } - state.chosenClient = client + state.chosenClient = client if (state.chosenClient && state.chosenClient.lastTimelineObject){ state.chosenClient.lastTimelineObject.ratingKey = -1 - } + } if (state.chosenClient == null){ return } - state.chosenClient.events.on('new_timeline',newTimeline) - state.chosenClient.events.on('playback_change',playbackChange) + state.chosenClient.events.on('new_timeline',newTimeline) + state.chosenClient.events.on('playback_change',playbackChange) state.chosenClientTimeSet = (new Date).getTime() clientPoller(state.chosenClientTimeSet) - state.chosenClient.getTimeline(function(timeline){}) - + state.chosenClient.getTimeline(function(timeline){}) + + - }, SET_PLEX(state,value){ state.plex = value - }, + }, SET_AUTOJOIN(state,value){ state.autoJoin = value - }, + }, SET_AUTOJOINROOM(state,value){ state.autoJoinRoom = value - }, + }, SET_AUTOJOINPASSWORD(state,value){ state.autoJoinPassword = value - }, + }, SET_AUTOJOINURL(state,value){ state.autoJoinUrl = value - }, + }, SET_SHORTLINK(state,value){ state.shortLink = value }, @@ -208,11 +208,11 @@ const mutations = { setSettingSYNCMODE(state,data){ setSetting('SYNCMODE',data) state.SYNCMODE = data - }, + }, setSettingSYNCFLEXABILITY(state,data){ setSetting('SYNCFLEXABILITY',data) state.SYNCFLEXABILITY = data - }, + }, setSettingCUSTOMSERVER(state,data){ setSetting('CUSTOMSERVER',data) state.CUSTOMSERVER = data @@ -220,7 +220,7 @@ const mutations = { setSettingDARKMODE(state,data){ setSetting('DARKMODE',data) state.DARKMODE = data - }, + }, setSettingHOMEINIT(state,data){ setSetting('HOMEINIT',data) state.HOMEINIT = data @@ -230,13 +230,13 @@ const mutations = { }, SET_BLOCKAUTOPLAY(state,value){ state.blockAutoPlay = value - }, + }, SET_DECISIONBLOCKED(state,value){ state.decisionBlocked = value - }, + }, REFRESH_PLEXDEVICES(state){ store.state.plex.getDevices(function(){ - + }) }, @@ -273,36 +273,36 @@ const getters = { }, getBlockAutoPlay: state => { return state.blockAutoPlay - }, + }, getAutoJoin: state => { return state.autoJoin - }, + }, getAutoJoinRoom: state => { return state.autoJoinRoom - }, + }, getAutoJoinPassword: state => { return state.autoJoinPassword - }, + }, getAutoJoinUrl: state => { return state.autoJoinUrl - }, + }, getShortLink: state => { return state.shortLink }, - // SETTINGS + // SETTINGS getSettingCLIENTPOLLINTERVAL: state => { return state.CLIENTPOLLINTERVAL - }, + }, getSettingSYNCMODE: state => { return state.SYNCMODE - }, + }, getSettingSYNCFLEXABILITY: state => { return state.SYNCFLEXABILITY - }, + }, getSettingCUSTOMSERVER: state => { return state.CUSTOMSERVER - }, + }, getSettingDARKMODE: state => { return state.DARKMODE }, @@ -325,8 +325,8 @@ const actions = { } const plexTogether = { - state: { - _io: require('socket.io-client'), + state: { + _io: require('socket.io-client'), _socket:null, ptevents: new EventEmitter(), ptservers: [], @@ -342,13 +342,13 @@ const plexTogether = { getters: { getServer: state => { return state.server - }, + }, getMe: state => { return state.me }, getRoom: state => { return state.room - }, + }, getPassword: state => { return state.password }, @@ -365,7 +365,7 @@ const plexTogether = { return state._socket } }, - mutations: { + mutations: { SET_CONNECTED(state, value) { state.connected = value }, @@ -389,14 +389,14 @@ const plexTogether = { }, ADD_MESSAGE(state,msg){ msg.time = moment().format('h:mm A') - state.messages.push(msg) + state.messages.push(msg) }, CLEAR_MESSAGES(state,msg){ state.messages = [] } }, - actions: { + actions: { autoJoin({ state, commit, rootState, dispatch }, data){ console.log('Attempting to auto join..') console.log(rootState) @@ -420,7 +420,7 @@ const plexTogether = { } } }) - }, + }, socketConnect({ state, commit, rootState },data) { let address = data.address let callback = data.callback @@ -474,8 +474,8 @@ const plexTogether = { sendNotification('Joined room: ' + _data.room) - // Generate our short url/invite link - console.log('generating our invite link') + // Generate our short url/invite link + console.log('generating our invite link') console.log(state) let webapp_socket = rootState.webapp_socket let url = window.location.origin @@ -487,7 +487,7 @@ const plexTogether = { ptserver: state.server, ptroom: state.room, ptpassword: state.password - + } var that = this if (process.env.NODE_ENV != 'development'){ @@ -506,16 +506,16 @@ const plexTogether = { state._socket.on('poll-result',function(users){ commit('SET_OURCLIENTRESPONSETIME', Math.abs((new Date().getTime()) - state._socket.pollStartTime)) commit('SET_USERS',users) - }) + }) state._socket.on('user-joined',function(users,user){ - commit('SET_USERS',users) + commit('SET_USERS',users) commit('ADD_MESSAGE',{ msg: user.username + ' joined', user: user, type: 'alert' }) console.log(users) - }) + }) state._socket.on('user-left',function(users,user){ commit('SET_USERS',users) commit('ADD_MESSAGE',{ @@ -523,7 +523,7 @@ const plexTogether = { user: user, type: 'alert' }) - }) + }) state._socket.on('host-swap',function(user){ if (!user){ return @@ -540,8 +540,8 @@ const plexTogether = { We need to limit how ourself to make sure we dont hit the client too hard. We'll only fetch new data if our data is older than 1000ms. - If we need to fetch new data, we'll do that and then decide - if we need to seek or start playing something. + If we need to fetch new data, we'll do that and then decide + if we need to seek or start playing something. */ rootState.hostClientResponseTime = data.clientResponseTime if (state.decisionBlocked){ @@ -557,7 +557,7 @@ const plexTogether = { console.log('Dont have our first timeline data yet.') return } - // Check previous timeline data age + // Check previous timeline data age let timelineAge = new Date().getTime() - rootState.chosenClient.lastTimelineObject.recievedAt if (timelineAge > 1000){ rootState.chosenClient.getTimeline(function(newtimeline){ @@ -591,7 +591,7 @@ const plexTogether = { } // Check if we need to autoplay if ((ourTimeline.state == 'stopped' || !ourTimeline.state) && (hostTimeline.playerState != 'stopped')){ - if (rootState.blockAutoPlay){ + if (rootState.blockAutoPlay || !hostTimeline.rawTitle){ return } // We need to autoplay! @@ -629,7 +629,7 @@ const plexTogether = { checkForSeek() function checkForSeek(){ if (parseInt(difference) > parseInt(rootState.SYNCFLEXABILITY) ){ - // We need to seek! + // We need to seek! console.log('STORE: we need to seek') // Decide what seeking method we want to use if (rootState.SYNCMODE == 'cleanseek'){ @@ -672,7 +672,7 @@ const plexTogether = { },difference) } rootState.chosenClient.pressPause(function(result,responseTime){ - }) + }) } else { state.decisionBlocked = true rootState.chosenClient.seekTo(parseInt(hostTimeline.time) + 10000,function(){ @@ -686,7 +686,7 @@ const plexTogether = { rootState.chosenClient.seekTo(parseInt(hostTimeline.time),function(result){ console.log('Result from within store for seek was ' + result) console.log('Setting decision blocked to false ') - state.decisionBlocked = false + state.decisionBlocked = false }) } } @@ -696,10 +696,10 @@ const plexTogether = { state._socket.on('disconnect',function(data){ sendNotification('Disconnected from the PlexTogether server') if (data == 'io client disconnect'){ - console.log('We disconnected from the server') + console.log('We disconnected from the server') commit('SET_ROOM',null) commit('SET_PASSWORD',null) - commit('SET_USERS',[]) + commit('SET_USERS',[]) commit('SET_CONNECTED',false) commit('SET_SERVER',null) commit('SET_CHAT',false) @@ -712,22 +712,22 @@ const plexTogether = { state._socket.on('new_message',function(msgObj){ commit('ADD_MESSAGE',msgObj) }) - + } else { - commit('SET_ME',null) + commit('SET_ME',null) commit('SET_ROOM',null) commit('SET_PASSWORD',null) commit('SET_USERS',[]) commit('SET_CHAT',false) - } - return data.callback(result) + } + return data.callback(result) }) }, disconnectServer({state, commit, rootState}){ - state._socket.disconnect() + state._socket.disconnect() commit('SET_ROOM',null) commit('SET_PASSWORD',null) - commit('SET_USERS',[]) + commit('SET_USERS',[]) commit('SET_CONNECTED',false) commit('SET_SERVER',null) commit('SET_CHAT',false) @@ -749,7 +749,7 @@ const plexTogether = { } }, getServerList(){ - }, + }, } } function getHandshakeUser(user,room,password){ @@ -760,7 +760,7 @@ function getHandshakeUser(user,room,password){ 'avatarUrl':user.thumb } return tempUser -} +} const store = new Vuex.Store({ state, mutations, diff --git a/webapp.js b/webapp.js index dc8e893d..2e8f319a 100644 --- a/webapp.js +++ b/webapp.js @@ -1,15 +1,24 @@ // ABOUT // Runs the Plex Together Web App - handles serving the static web content and link shortening services -// Defaults to 8088 +// Port defaults to 8088 +// REQUIRED: --url argument - -// USER CONFIG +const args = require("args-parser")(process.argv) +if (!args['url']){ + console.log('Missing required argument -url. EG. "node webapp.js --url=http://example.com/ptweb". This URL is used for redirecting invite links.') + return +} +var accessIp = args['url'] // EG 'http://95.231.444.12:8088/ptweb' or 'http://example.com/ptweb' +if (accessIp.indexOf('/ptweb') == -1){ + console.log('WARNING: /ptweb was not found in your url. Unless you have changed the URL Base make sure to include this.') +} var PORT = 8088 -var accessIp = 'http://ip:port/ptweb' // EG 'http://95.231.444.12:8088/ptweb' or 'http://example.com/ptweb' - - - - +if (args['port']){ + PORT = parseInt(args['port']) +} else { + console.log('Defaulting to port 8088') +} +// USER CONFIG // END USER CONFIG var express = require('express'); @@ -34,14 +43,15 @@ webapp.get('/invite/:id',function(req,res){ console.log('handling an invite') let shortObj = shortenedLinks[req.params.id] if (!shortObj){ - return res.send('Whoops, looks like youve made a wrong turn..') + return res.send('Invite expired') } console.log('Redirecting an invite link') + console.log(JSON.stringify(shortObj,null,4)) return res.redirect(shortObj.fullUrl) }) root.use('/ptweb',webapp) root.get('*',function(req,res){ - console.log('Catch all') + console.log('Catch all - have you run `npm run build`?') return res.redirect('/ptweb') }) @@ -56,7 +66,7 @@ var webapp_io = require('socket.io')(rootserver,{path: '/ptweb/socket.io'}); var shortenedLinks = {} -function getUniqueId(){ +function getUniqueId(){ while (true){ let testId = (0|Math.random()*9e6).toString(36) if (!shortenedLinks[testId]){ // Check if we already have a shortURL using that id @@ -91,14 +101,14 @@ function shortenObj(data){ for (let key in params) { query += encodeURIComponent(key)+'='+encodeURIComponent(params[key])+'&'; } - returnable.fullUrl = accessIp + '/#/?' + query + returnable.fullUrl = accessIp + '/#/join?' + query shortenedLinks[returnable.id] = returnable return returnable.shortUrl -} +} webapp_io.on('connection', function(socket){ - console.log('Someone connected to the webapp socket') + console.log('New connection to the webapp socket') socket.on('shorten',function(data){ console.log('Creating a shortened link') socket.emit('shorten-result',shortenObj(data))