diff --git a/www/css/channel.css b/www/css/channel.css index dc905db..41eecca 100644 --- a/www/css/channel.css +++ b/www/css/channel.css @@ -264,6 +264,7 @@ span.user-entry{ position: relative; scrollbar-width: thin; flex: 0 0; + width: 50%; } .cpanel-div{ diff --git a/www/js/channel/chat.js b/www/js/channel/chat.js index cbed794..b297963 100644 --- a/www/js/channel/chat.js +++ b/www/js/channel/chat.js @@ -66,7 +66,7 @@ class chatBox{ /** * Click-Dragger Object for handling dynamic chat/video split re-sizing */ - this.clickDragger = new canopyUXUtils.clickDragger("#chat-panel-drag-handle", "#chat-panel-div"); + this.clickDragger = new canopyUXUtils.clickDragger("#chat-panel-drag-handle", "#chat-panel-div", true, undefined, true, 75); /** * Command Pre-Processor Object diff --git a/www/js/channel/cpanel.js b/www/js/channel/cpanel.js index 22d65e7..99172fa 100644 --- a/www/js/channel/cpanel.js +++ b/www/js/channel/cpanel.js @@ -46,12 +46,12 @@ class cPanel{ /** * Click-Dragger object for re-sizable active panel */ - this.activePanelDragger = new canopyUXUtils.clickDragger("#cpanel-active-drag-handle", "#cpanel-active-div", false, null, false); + this.activePanelDragger = new canopyUXUtils.clickDragger("#cpanel-active-drag-handle", "#cpanel-active-div", false, null, false, 75, 1, true); /** * Click-Dragger object for re-sizable pinned panel */ - this.pinnedPanelDragger = new canopyUXUtils.clickDragger("#cpanel-pinned-drag-handle", "#cpanel-pinned-div", false, this.client.chatBox.clickDragger); + this.pinnedPanelDragger = new canopyUXUtils.clickDragger("#cpanel-pinned-drag-handle", "#cpanel-pinned-div", false, this.client.chatBox.clickDragger, true, 50, 1, true, "50%"); //Element Nodes //Active Panel @@ -126,6 +126,10 @@ class cPanel{ this.activePanelCloseIcon.addEventListener("click", this.hideActivePanel.bind(this)); this.activePanelPinIcon.addEventListener("click", this.pinPanel.bind(this)); this.activePanelPopoutIcon.addEventListener("click", this.popActivePanel.bind(this)); + this.client.chatBox.clickDragger.handle.addEventListener("clickdrag", this.handleActivePanelParentDrag.bind(this)); + this.client.chatBox.clickDragger.handle.addEventListener("clickdrag", this.handlePinnedPanelParentDrag.bind(this)); + this.client.chatBox.clickDragger.handle.addEventListener("clickdragend", this.handleActivePanelParentDragEnd.bind(this)); + this.client.chatBox.clickDragger.handle.addEventListener("clickdragend", this.handlePinnedPanelParentDragEnd.bind(this)); this.pinnedPanelCloseIcon.addEventListener("click", this.hidePinnedPanel.bind(this)); this.pinnedPanelUnpinIcon.addEventListener("click", this.unpinPanel.bind(this)); this.pinnedPanelPopoutIcon.addEventListener("click", this.popPinnedPanel.bind(this)); @@ -153,6 +157,33 @@ class cPanel{ this.activePanel.docSwitch(); } + handleActivePanelParentDrag(event){ + //Get parent width from parent click dragger + let parentWidth = event.element.style.width.slice(0,-2); + //Get active panel width + let elementWidth = this.activePanelDiv.style.width.slice(0,-2); + + //If the element is already at 100% + if(elementWidth == "" || elementWidth == 100){ + //Ignore + return; + } + + //If the active panel is bigger than the chat parents width + if(elementWidth >= parentWidth - this.activePanelDragger.limitTolerance){ + //Trick the setElementWidth function into making it fill its container + this.activePanelDragger.setElementWidth(this.activePanelDragger.sizeLimit); + } + } + + handleActivePanelParentDragEnd(event){ + //Get parent width from parent click dragger + let parentWidth = event.element.style.width.slice(0,-2); + + //Set activePanelDragger size limit to parent width + this.activePanelDragger.sizeLimit = Number(parentWidth); + } + /** * Hides active panel * @param {Event} event - Event passed down from Input Handler @@ -244,6 +275,33 @@ class cPanel{ this.hidePinnedPanel(null, true); } + handlePinnedPanelParentDragEnd(event){ + //Get parent width from parent click dragger + let parentWidth = Number(event.element.style.width.slice(0,-2)); + + //Set pinnedPanelDragger size limit to half the parent width + this.pinnedPanelDragger.sizeLimit = Number(parentWidth / 2); + } + + handlePinnedPanelParentDrag(event){ + //Get parent width from parent click dragger + let parentWidth = event.element.style.width.slice(0,-2); + //Get pinned panel width + let elementWidth = this.pinnedPanelDiv.style.width.slice(0,-2); + + //If the element is already at 50% + if(elementWidth == "" || elementWidth == 50){ + //Ignore + return; + } + + //If the pinned panel is bigger than half the parents width + if(elementWidth >= (parentWidth / 2) - this.pinnedPanelDragger.limitTolerance){ + //Trick the setElementWidth function into making it fill its container + this.pinnedPanelDragger.setElementWidth(this.pinnedPanelDragger.sizeLimit); + } + } + /** * Pops a new pop-out panel * @param {panelObj} panel - panelObj to apply to the panel diff --git a/www/js/channel/webRTCHandler.js b/www/js/channel/webRTCHandler.js index 166f306..62a399a 100644 --- a/www/js/channel/webRTCHandler.js +++ b/www/js/channel/webRTCHandler.js @@ -93,13 +93,17 @@ class webRTCHandler{ //If we didn't get any audio tracks from the DisplayMedia portion of the API if(this.broadcastingStream == null || this.broadcastingStream.getAudioTracks().length == 0){ - //Bug user for an audio device - const tempStream = await navigator.mediaDevices.getUserMedia({video: false, audio: true}); + try{ + //Bug user for an audio device + const tempStream = await navigator.mediaDevices.getUserMedia({video: false, audio: true}); - //For each track received from audio device - for(const track of tempStream.getAudioTracks()){ - //Add to existing broadcast stream - this.broadcastingStream.addTrack(track); + //For each track received from audio device + for(const track of tempStream.getAudioTracks()){ + //Add to existing broadcast stream + this.broadcastingStream.addTrack(track); + } + }catch(err){ + console.warn("Unable to get audio for stream!"); } } } @@ -231,7 +235,9 @@ class webRTCHandler{ handleIceCandidate(data){ //If we're broadcasting if(this.isBroadcasting){ + //Find the related user object const user = this.currentViewers.get(data.source.user); + //allow them to handle it user.handleIceCandidate(data); //If we're receiving a stream }else{ @@ -267,7 +273,7 @@ class webRTCHandler{ } handleConnectionState(data){ - if(this.currentStream.connectionState == "failed"){ + if(!this.isBroadcasting && this.currentStream.connectionState == "failed"){ let icon = document.createElement('img'); icon.src = "/img/rtcerror.png"; @@ -355,7 +361,7 @@ class connectedViewer{ await peer.setLocalDescription(answer); //Setup peer ICE Candidate event listner - peer.addEventListener('icecandidate', this.sendIceCandidate.bind(this)); + peer.addEventListener('icecandidate', (event)=>{this.sendIceCandidate(event, socket)}); //Save peer by socket identifier this.peers.set(socket, peer); @@ -368,14 +374,14 @@ class connectedViewer{ }); } - sendIceCandidate(event){ + sendIceCandidate(event, socket){ //If we have a candidate if(event.candidate != null){ //Send that shit off! this.client.socket.emit('relayRTCData',{ type: 'candidate', body: event.candidate, - recipient: this.socket + recipient: socket }); } } diff --git a/www/js/utils.js b/www/js/utils.js index 6485ccf..dda6c03 100644 --- a/www/js/utils.js +++ b/www/js/utils.js @@ -561,7 +561,7 @@ class canopyUXUtils{ } static clickDragger = class{ - constructor(handle, element, leftHandle = true, parent, flex = true){ + constructor(handle, element, leftHandle = true, parent, flex = true, sizeLimit = 100, limitTolerance = 0.1, fillContainer = false, fillAmount = "100%"){ //Pull needed nodes this.handle = document.querySelector(handle); this.element = document.querySelector(element); @@ -584,6 +584,18 @@ class canopyUXUtils{ //Create boolean to allow parent classes to suspend click dragging behavior this.enabled = true; + //Create number to hold size limit of click dragger + this.sizeLimit = sizeLimit; + + //Create number to hold size limit tolerance + this.limitTolerance = limitTolerance; + + //Create boolean to allow dragger element to fill container when size limit is hit + this.fillContainer = fillContainer; + + //Create string to hold amount to fill container by + this.fillAmount = fillAmount; + //Setup our event listeners this.setupInput(); } @@ -602,8 +614,14 @@ class canopyUXUtils{ window.document.body.style.userSelect = "none"; window.document.body.style.cursor = "ew-resize"; - //Dispatch click drag start event through handle - this.handle.dispatchEvent(new CustomEvent("clickdragstart")); + //Create a new event + let endEvent = new CustomEvent("clickdragstart"); + + //Set the element to the drag body + endEvent.element = this.element; + + //Dispatch click drag end event through handle + this.handle.dispatchEvent(endEvent); } endDrag(event){ @@ -616,8 +634,14 @@ class canopyUXUtils{ window.document.body.style.userSelect = "auto"; window.document.body.style.cursor = "auto"; + //Create a new event + let endEvent = new CustomEvent("clickdragend"); + + //Set the element to the drag body + endEvent.element = this.element; + //Dispatch click drag end event through handle - this.handle.dispatchEvent(new CustomEvent("clickdragend")); + this.handle.dispatchEvent(endEvent); } drag(event){ @@ -641,13 +665,8 @@ class canopyUXUtils{ //if we're not breaking the page, or we're moving left if((!this.breakingScreen && pageBreak <= 0) || event.clientX < this.handle.getBoundingClientRect().left){ - //Apply difference to width - if(this.flex){ - this.element.style.flexBasis = `${this.calcWidth(difference)}vw`; - } - //I know it's kludgy to apply this along-side flex basis but it fixes some nasty bugs with nested draggers - //Don't @ me, it's not like i'm an actual web developer anyways :P - this.element.style.width = `${this.calcWidth(difference)}vw`; + //Set element width + this.setElementWidth(this.calcWidth(difference)); //If we let go here, the width isn't breaking anything so there's nothing to fix. this.breakingScreen = false; @@ -658,8 +677,15 @@ class canopyUXUtils{ } } - //Dispatch click drag event through handle - this.handle.dispatchEvent(new CustomEvent("clickdrag")); + + //Create a new event + let endEvent = new CustomEvent("clickdrag"); + + //Set the element to the drag body + endEvent.element = this.element; + + //Dispatch click drag end event through handle + this.handle.dispatchEvent(endEvent); } } @@ -669,7 +695,7 @@ class canopyUXUtils{ //Little hacky but this ensures that if our click dragger tries to do something that it should absolutely never be doing //it'll be told to sit down, shut up, and fuck off. - return width < 100 ? width : 20; + return width < (this.sizeLimit - this.limitTolerance) ? width : this.sizeLimit; } @@ -693,10 +719,7 @@ class canopyUXUtils{ } //Fix the page width - if(this.flex){ - this.element.style.flexBasis = `${this.calcWidth(this.element.getBoundingClientRect().width + pageBreak)}vw`; - } - this.element.style.width = `${this.calcWidth(this.element.getBoundingClientRect().width + pageBreak)}vw`; + this.setElementWidth(this.calcWidth(this.element.getBoundingClientRect().width + pageBreak)); //If we're calling this outside of drag() (regardless of draglock unless set otherwise) if(standalone){ @@ -713,6 +736,21 @@ class canopyUXUtils{ this.parent.fixCutoff(standalone); } } + + setElementWidth(width){ + //If final width is true and we're hitting the size limit set final width to 100%, otherwise just hand it the raw value + let finalWidth = (this.fillContainer && width == this.sizeLimit) ? this.fillAmount : `${width}vw` + + //If this is a flex + if(this.flex){ + //Set basis + this.element.style.flexBasis = finalWidth; + } + + //I know it's kludgy to apply this along-side flex basis but it fixes some nasty bugs with nested draggers + //Don't @ me, it's not like i'm an actual web developer anyways :P + this.element.style.width = finalWidth; + } } }