v1.5.2/release

- notification timer
- auto rejoin
- mic permission overlay
- fullscreen support
- loading for call
- gif ui update
- netflix player listener update
- room migrate fix
- update player fix
This commit is contained in:
2020-07-28 20:10:03 -04:00
parent a3750859e3
commit d127a6398e
7 changed files with 187 additions and 51 deletions
+1 -2
View File
@@ -110,8 +110,7 @@ const App = () => {
open={notification.open} open={notification.open}
onClose={() => setNotification(closedNotification)} onClose={() => setNotification(closedNotification)}
message={notification.message} message={notification.message}
resumeHideDuration={1000} autoHideDuration={6000}
autoHideDuration={3000}
/> />
<div className="party-content-wrapper"> <div className="party-content-wrapper">
<div id="party-routes-wrapper"> <div id="party-routes-wrapper">
+99 -12
View File
@@ -34,6 +34,7 @@ import {
Switch, Switch,
FormControlLabel, FormControlLabel,
Chip, Chip,
CircularProgress,
} from '@material-ui/core'; } from '@material-ui/core';
import Thread from './Thread'; import Thread from './Thread';
import { Carousel } from '@giphy/react-components'; import { Carousel } from '@giphy/react-components';
@@ -104,6 +105,8 @@ export default class Chat extends Component {
allowChatNotification: allowChatNotification:
LocalData().allowChatNotification !== undefined ? LocalData().allowChatNotification : true, LocalData().allowChatNotification !== undefined ? LocalData().allowChatNotification : true,
isFullscreen: document.fullscreen, isFullscreen: document.fullscreen,
allowAutoRejoin:
LocalData().allowAutoRejoin !== undefined ? LocalData().allowAutoRejoin : true,
}; };
this.port = null; this.port = null;
this.gifClick = this.gifClick.bind(this); this.gifClick = this.gifClick.bind(this);
@@ -119,6 +122,7 @@ export default class Chat extends Component {
this.sendMessageInvoker = this.sendMessageInvoker.bind(this); this.sendMessageInvoker = this.sendMessageInvoker.bind(this);
this.videoEventListener = this.videoEventListener.bind(this); this.videoEventListener = this.videoEventListener.bind(this);
this.mVideoListener = new VideoListener(this.videoEventListener); this.mVideoListener = new VideoListener(this.videoEventListener);
this.updateAllowAutoRejoin = this.updateAllowAutoRejoin.bind(this);
this.updateAllowChatNotification = this.updateAllowChatNotification.bind(this); this.updateAllowChatNotification = this.updateAllowChatNotification.bind(this);
this.mCallManager = new CallManager(this.callEventListener, this.props.notify); this.mCallManager = new CallManager(this.callEventListener, this.props.notify);
} }
@@ -142,9 +146,16 @@ export default class Chat extends Component {
}); });
// ACTIVE TRACKER // ACTIVE TRACKER
updateLocalData({ lastActive: new Date().getTime() }); if (LocalData().allowAutoRejoin === undefined || LocalData().allowAutoRejoin === null) {
setInterval(() => { updateLocalData({ allowAutoRejoin: this.state.allowAutoRejoin });
}
if (this.state.allowAutoRejoin === true) {
updateLocalData({ lastActive: new Date().getTime() }); updateLocalData({ lastActive: new Date().getTime() });
}
setInterval(() => {
if (this.state.allowAutoRejoin === true) {
updateLocalData({ lastActive: new Date().getTime() });
}
}, 60000); }, 60000);
// VIDEO LISTENER START // VIDEO LISTENER START
@@ -301,7 +312,33 @@ export default class Chat extends Component {
} }
handlePhoneCall() { handlePhoneCall() {
const { onCall, conference, admin } = this.state; const { onCall, conference, admin } = this.state;
this.mCallManager.toggleCall(onCall, conference, admin); if (window.navigator && onCall === false) {
try {
const overlay = document.createElement('div');
overlay.innerHTML = `
<div id="mic-highlight"></div>
<h4 id="mic-text">Grant Mic Permission</h4>
`;
overlay.id = 'mic-permission-overlay';
document.body.appendChild(overlay);
window.navigator
.getUserMedia({
audio: true,
})
.then(() => {
document.getElementById('mic-permission-overlay').remove();
this.mCallManager.toggleCall(onCall, conference, admin);
})
.catch(() => {
document.getElementById('mic-permission-overlay').remove();
this.props.notify(
'Check your mic permission for this website. You can modify site permission by clicking on the lock icon in the top left.'
);
});
} catch (err) {
console.log(err);
}
} else this.mCallManager.toggleCall(onCall, conference, admin);
} }
handleMute() { handleMute() {
this.mCallManager.toggleMute(this.state.muted); this.mCallManager.toggleMute(this.state.muted);
@@ -315,6 +352,10 @@ export default class Chat extends Component {
updateLocalData({ allowChatNotification: !this.state.allowChatNotification }); updateLocalData({ allowChatNotification: !this.state.allowChatNotification });
this.setState({ allowChatNotification: !this.state.allowChatNotification }); this.setState({ allowChatNotification: !this.state.allowChatNotification });
} }
updateAllowAutoRejoin() {
updateLocalData({ allowAutoRejoin: !this.state.allowAutoRejoin });
this.setState({ allowAutoRejoin: !this.state.allowAutoRejoin });
}
toggleFullscreen() { toggleFullscreen() {
if (document.fullscreen) { if (document.fullscreen) {
document.exitFullscreen(); document.exitFullscreen();
@@ -335,6 +376,7 @@ export default class Chat extends Component {
allowChatNotification, allowChatNotification,
users, users,
callActionPending, callActionPending,
allowAutoRejoin,
usersOnCall, usersOnCall,
isFullscreen, isFullscreen,
} = this.state; } = this.state;
@@ -391,7 +433,14 @@ export default class Chat extends Component {
), ),
}} }}
/> />
<ButtonGroup fullWidth className="party-controls" size="small"> <ButtonGroup
fullWidth
className="party-controls"
size="small"
disableElevation
variant="contained"
color="secondary"
>
<Button onClick={this.leaveParty} startIcon={<Exit />}> <Button onClick={this.leaveParty} startIcon={<Exit />}>
<Typography variant="caption" className="party-control-button-text"> <Typography variant="caption" className="party-control-button-text">
Leave Leave
@@ -420,7 +469,28 @@ export default class Chat extends Component {
Allow chat notification when side panel is closed Allow chat notification when side panel is closed
<br /> <br />
<span style={{ color: '#8a8a8a' }}> <span style={{ color: '#8a8a8a' }}>
{allowChatNotification ? 'Currently Enabled' : 'Currently Disabled'} {allowChatNotification ? 'Notifications Enabled' : 'Notifications Disabled'}
</span>
</span>
}
labelPlacement="end"
/>
<FormControlLabel
className="notification-switch"
control={
<Switch
checked={allowAutoRejoin}
onChange={this.updateAllowAutoRejoin}
name="allowAutoRejoin"
color={allowAutoRejoin ? 'secondary' : 'primary'}
/>
}
label={
<span>
Allow Watch Party to auto rejoin (within 1 minute)
<br />
<span style={{ color: '#8a8a8a' }}>
{allowAutoRejoin ? 'Auto Rejoin Enabled' : 'Auto Rejoin Disabled'}
</span> </span>
</span> </span>
} }
@@ -494,7 +564,7 @@ export default class Chat extends Component {
)} )}
{player && player.showName && player.status ? ( {player && player.showName && player.status ? (
<Button className="media-info-link" href={player.url} startIcon={<LinkOutlined />}> <Button className="media-info-link" href={player.url} startIcon={<LinkOutlined />}>
Link to show Link to currently playing
</Button> </Button>
) : null} ) : null}
</Card> </Card>
@@ -520,16 +590,19 @@ export default class Chat extends Component {
<div className="text-phone-panel"> <div className="text-phone-panel">
{gif || newMessage ? null : ( {gif || newMessage ? null : (
<Tooltip title="Fullscreen with Watch Party" aria-label="Fullscreen"> <Tooltip title="Fullscreen with Watch Party" aria-label="Fullscreen">
<IconButton color="secondary" onClick={this.toggleFullscreen}> <IconButton className="icon-button" color="secondary" onClick={this.toggleFullscreen}>
{isFullscreen ? <FullscreenExit /> : <Fullscreen />} {isFullscreen ? <FullscreenExit /> : <Fullscreen />}
</IconButton> </IconButton>
</Tooltip> </Tooltip>
)} )}
{gif || newMessage ? null : ( {gif || newMessage ? null : callActionPending ? (
<CircularProgress className="icon-button" color="secondary" />
) : (
<IconButton <IconButton
disabled={callActionPending} disabled={callActionPending}
onClick={this.handlePhoneCall} onClick={this.handlePhoneCall}
color={!onCall ? 'secondary' : 'primary'} color={!onCall ? 'secondary' : 'primary'}
className="icon-button"
> >
{onCall ? ( {onCall ? (
<Tooltip placement="top" title="Leave Call"> <Tooltip placement="top" title="Leave Call">
@@ -544,13 +617,23 @@ export default class Chat extends Component {
)} )}
{!gif && !newMessage && onCall && !muted ? ( {!gif && !newMessage && onCall && !muted ? (
<Tooltip title="Mute Mic" placement="top"> <Tooltip title="Mute Mic" placement="top">
<IconButton disabled={callActionPending} onClick={this.handleMute} color="primary"> <IconButton
className="icon-button"
disabled={callActionPending}
onClick={this.handleMute}
color="primary"
>
<MicOff /> <MicOff />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
) : !gif && !newMessage && onCall && muted ? ( ) : !gif && !newMessage && onCall && muted ? (
<Tooltip title="Unmute Mic" placement="top"> <Tooltip title="Unmute Mic" placement="top">
<IconButton disabled={callActionPending} onClick={this.handleMute} color="secondary"> <IconButton
className="icon-button"
disabled={callActionPending}
onClick={this.handleMute}
color="secondary"
>
<MicOn /> <MicOn />
</IconButton> </IconButton>
</Tooltip> </Tooltip>
@@ -565,7 +648,7 @@ export default class Chat extends Component {
this.state.newMessage && !this.state.gif this.state.newMessage && !this.state.gif
? 'Enter to send / Shift+Enter for new line' ? 'Enter to send / Shift+Enter for new line'
: this.state.gif : this.state.gif
? 'Click on gif to send' ? 'Click on gif to send / Scroll to load more'
: null : null
} }
variant="outlined" variant="outlined"
@@ -596,7 +679,11 @@ export default class Chat extends Component {
), ),
startAdornment: ( startAdornment: (
<InputAdornment position="start"> <InputAdornment position="start">
<IconButton onClick={() => this.setState({ gif: !gif })} edge="start"> <IconButton
className={`gif-button ${this.state.gif ? 'gif-close' : ''}`}
onClick={() => this.setState({ gif: !gif })}
edge="start"
>
{gif ? <Cancel /> : <Gif />} {gif ? <Cancel /> : <Gif />}
</IconButton> </IconButton>
</InputAdornment> </InputAdornment>
+2 -2
View File
@@ -57,8 +57,8 @@ export default class Create extends Component {
this.success = this.success.bind(this); this.success = this.success.bind(this);
} }
componentDidMount() { componentDidMount() {
const { lastActive, userName, partyName, partyPin } = LocalData(); const { lastActive, userName, partyName, partyPin, allowAutoRejoin } = LocalData();
if (lastActive && userName && partyName && partyPin) { if (allowAutoRejoin === true && lastActive && userName && partyName && partyPin) {
if (Math.abs(new Date(parseInt(lastActive)) - new Date().getTime()) <= 60000) { if (Math.abs(new Date(parseInt(lastActive)) - new Date().getTime()) <= 60000) {
this.props.updateLoading(true); this.props.updateLoading(true);
this.joinCall(userName, partyName, partyPin); this.joinCall(userName, partyName, partyPin);
+31 -17
View File
@@ -264,26 +264,40 @@ export default class VideoListener {
const videoElement = document const videoElement = document
.getElementsByClassName('AkiraPlayer')[0] .getElementsByClassName('AkiraPlayer')[0]
.getElementsByTagName('video')[0]; .getElementsByTagName('video')[0];
if (videoElement) { if (videoElement && !this.video.element) {
this.firstTimeSync(videoElement); this.firstTimeSync(videoElement);
} else {
setInterval(
this.video.element
? null
: () => {
var nve = document
.getElementsByClassName('AkiraPlayer')[0]
.getElementsByTagName('video')[0];
if (
nve !== null &&
(this.video.element !== nve || this.video.element === null)
) {
this.firstTimeSync(nve);
}
},
1000
);
} }
} else { } else {
document.addEventListener('DOMNodeInserted', (e) => { setInterval(
if (e.target) { this.video.element
if (e.target.classList) { ? null
if ( : () => {
e.target.classList.contains('nfp') && var nve = document
e.target.classList.contains('AkiraPlayer') .getElementsByClassName('AkiraPlayer')[0]
) { .getElementsByTagName('video')[0];
e.target.addEventListener('DOMNodeInserted', (ev) => { if (nve !== null && (this.video.element !== nve || this.video.element === null)) {
if (ev.target.children[0].id) { this.firstTimeSync(nve);
this.firstTimeSync(ev.target.children[0].firstChild); }
} },
}); 1000
} );
}
}
});
} }
break; break;
case PLAYER_SOURCE.HULU: case PLAYER_SOURCE.HULU:
+52 -15
View File
@@ -44,6 +44,7 @@ body.visible .watch-party-fab {
} }
body.visible .party-notification-container { body.visible .party-notification-container {
display: block !important; display: block !important;
max-width: var(--party-width);
} }
body.netflix.visible .AkiraPlayer, /* NETFLIX */ body.netflix.visible .AkiraPlayer, /* NETFLIX */
@@ -247,6 +248,7 @@ body.amazon .fyysciv.f1lobqlo.fk0j80b {
} }
.party-create-container .brand-title { .party-create-container .brand-title {
padding: 36px; padding: 36px;
letter-spacing: 3.5px !important;
} }
.party-create-container .create-input-card { .party-create-container .create-input-card {
@@ -364,17 +366,11 @@ textarea::-webkit-scrollbar {
margin-top: 18px; margin-top: 18px;
} }
.party-controls .MuiButton-startIcon { .party-controls .MuiButton-startIcon {
margin-right: 0px !important; margin-right: 8px !important;
} }
.party-control-button-text { .party-control-button-text {
font-size: 10px !important; font-size: 10px !important;
display: none; transition: all ease-out 0.3s;
}
.party-controls button:hover .party-control-button-text {
display: initial;
}
.party-controls button:hover .MuiButton-startIcon {
margin-right: 8px !important;
} }
.party-controls-users-container { .party-controls-users-container {
max-height: 100px; max-height: 100px;
@@ -417,8 +413,8 @@ textarea::-webkit-scrollbar {
flex-direction: row; flex-direction: row;
} }
.media-info-icon { .media-info-icon {
width: 48px !important; width: 2em !important;
height: 48px !important; height: 2em !important;
} }
.media-info-right { .media-info-right {
flex: 1; flex: 1;
@@ -436,12 +432,14 @@ textarea::-webkit-scrollbar {
.giphy-carousel::before { .giphy-carousel::before {
position: relative; position: relative;
bottom: 40%; bottom: 90px;
margin-left: 40px;
content: url('./Giphy.png'); content: url('./Giphy.png');
} }
.giphy-carousel { .giphy-carousel {
margin-top: 1rem; margin-top: 1rem;
min-height: fit-content; min-height: fit-content;
padding-bottom: 3rem;
} }
.giphy-carousel img { .giphy-carousel img {
border-radius: 1rem; border-radius: 1rem;
@@ -456,14 +454,13 @@ textarea::-webkit-scrollbar {
.giphy-carousel::-webkit-scrollbar { .giphy-carousel::-webkit-scrollbar {
width: 5px; width: 5px;
height: 5px; height: 12px;
} }
.giphy-carousel::-webkit-scrollbar-track { .giphy-carousel::-webkit-scrollbar-track {
background-color: rgb(90, 90, 90); background-color: rgb(90, 90, 90);
border-radius: 1rem;
} }
.giphy-carousel::-webkit-scrollbar-thumb { .giphy-carousel::-webkit-scrollbar-thumb {
background-color: rgb(118, 182, 255); background-color: #c0f300;
border-radius: 13px; border-radius: 13px;
} }
.message-send svg { .message-send svg {
@@ -482,6 +479,26 @@ textarea::-webkit-scrollbar {
margin: 0 15px 15px 15px; margin: 0 15px 15px 15px;
border-radius: 26px; border-radius: 26px;
} }
.text-phone-panel .icon-button {
width: 15px !important;
height: 15px !important;
margin: 7.5px !important;
}
.text-phone-panel .gif-button.gif-close {
padding: 12px 0 !important;
}
.text-phone-panel .gif-button {
border-radius: 0 !important;
height: 1.75em !important;
}
.text-phone-panel .gif-button svg {
width: 1.75em !important;
height: 1.75em !important;
}
.text-phone-panel .gif-button.gif-close svg {
width: 0.75em !important;
height: 0.75em !important;
}
.MuiTooltip-popper { .MuiTooltip-popper {
z-index: 99999 !important; z-index: 99999 !important;
@@ -532,7 +549,7 @@ body.amazon-prime .notification-switch .MuiSwitch-thumb {
text-transform: uppercase; text-transform: uppercase;
} }
.mic-permission-overlay { #mic-permission-overlay {
position: fixed; position: fixed;
width: 100%; width: 100%;
height: 100%; height: 100%;
@@ -543,4 +560,24 @@ body.amazon-prime .notification-switch .MuiSwitch-thumb {
z-index: 9999; z-index: 9999;
color: white; color: white;
font-size: 95px; font-size: 95px;
backdrop-filter: blur(10px);
}
#mic-highlight {
width: 320px;
height: 124px;
box-shadow: 0px 0px 520px #c0f300;
left: 107px;
position: absolute;
border: 2px solid #c0f300;
}
#mic-text {
width: 100%;
text-align: center;
font-size: 15px;
font-family: sans-serif;
text-transform: uppercase;
font-weight: 300;
letter-spacing: 1.5px;
position: absolute;
top: 50%;
} }
+1 -2
View File
@@ -1,5 +1,4 @@
const admin = require('firebase-admin'); const admin = require('firebase-admin');
const { firestore } = require('firebase-admin');
module.exports = async (req, res) => { module.exports = async (req, res) => {
const bodydata = JSON.parse(req.body); const bodydata = JSON.parse(req.body);
@@ -137,7 +136,7 @@ module.exports = async (req, res) => {
.update({ .update({
player: { player: {
showName: null, showName: null,
source: null, source: roomSource,
status: 'NOT_PLAYING', status: 'NOT_PLAYING',
time: 0, time: 0,
updatedBy: bodydata.uid, updatedBy: bodydata.uid,
+1 -1
View File
@@ -30,7 +30,7 @@ module.exports = async (req, res) => {
.get() .get()
.then((userSnap) => userSnap.exists); .then((userSnap) => userSnap.exists);
if (userExists) { if (userExists) {
if (showChanged === true) { if (showChanged === true && player.showName) {
await admin await admin
.firestore() .firestore()
.collection('rooms') .collection('rooms')