v1.6.2/release

-website update
-dynamic showName and video element
-time update on playing
This commit is contained in:
2020-08-14 00:36:44 -04:00
parent 3c4fffe598
commit aaf2506f78
14 changed files with 582 additions and 338 deletions
+213 -115
View File
@@ -10,7 +10,7 @@ CITED ARE THE SOLE INTELECTUAL PROPERTY OF AYUSHYA AMITABH, AND MAY NOT BE
COPIED, EDITED, OR REPRODUCED WITHOUT PERMISSION.
************************************************************************/
/*global chrome */
import React, { Component } from 'react';
import React, { Component } from "react";
import {
Typography,
TextField,
@@ -31,8 +31,8 @@ import {
Paper,
Grid,
Slider,
} from '@material-ui/core';
import Thread from './Thread';
} from "@material-ui/core";
import Thread from "./Thread";
import {
SendMessageApi,
LeaveRoomApi,
@@ -46,7 +46,7 @@ import {
UpdateAdminOnly,
scrollThread,
removeLocalData,
} from './Api';
} from "./Api";
import {
Send,
ExitToApp as Exit,
@@ -68,21 +68,21 @@ import {
VolumeDown,
VolumeUp,
CancelRounded,
} from '@material-ui/icons';
import Create from './Create';
import { goTo } from 'route-lite';
import CallManager from './CallManager';
import VideoListener from './VideoListener';
import ReactGiphySearchbox from 'react-giphy-searchbox';
} from "@material-ui/icons";
import Create from "./Create";
import { goTo } from "route-lite";
import CallManager from "./CallManager";
import VideoListener from "./VideoListener";
import ReactGiphySearchbox from "react-giphy-searchbox";
// const giphyFetch = new GiphyFetch('ojJbIMUN6XRMn4mHiFFav3rMCpXUg8sq');
export default class Chat extends Component {
constructor(props) {
super(props);
this.state = {
name: '',
name: "",
messages: [],
newMessage: '',
newMessage: "",
admin: null,
adminOnly: false,
adminModeUpdate: false,
@@ -94,10 +94,14 @@ export default class Chat extends Component {
callActionPending: false,
menuPopover: true,
allowChatNotification:
LocalData().allowChatNotification !== undefined ? LocalData().allowChatNotification : true,
LocalData().allowChatNotification !== undefined
? LocalData().allowChatNotification
: true,
isFullscreen: document.fullscreen,
allowAutoRejoin:
LocalData().allowAutoRejoin !== undefined ? LocalData().allowAutoRejoin : true,
LocalData().allowAutoRejoin !== undefined
? LocalData().allowAutoRejoin
: true,
replyTo: null,
sendingMessages: [],
volumes: {},
@@ -117,17 +121,27 @@ export default class Chat extends Component {
this.callEventListener = this.callEventListener.bind(this);
this.sendMessageInvoker = this.sendMessageInvoker.bind(this);
this.videoEventListener = this.videoEventListener.bind(this);
this.mVideoListener = new VideoListener(this.videoEventListener, props.selectors);
this.mVideoListener = new VideoListener(
this.videoEventListener,
props.selectors,
props.nameSelectors
);
this.updateAllowAutoRejoin = this.updateAllowAutoRejoin.bind(this);
this.updateAllowChatNotification = this.updateAllowChatNotification.bind(this);
this.mCallManager = new CallManager(this.callEventListener, this.props.notify);
this.updateAllowChatNotification = this.updateAllowChatNotification.bind(
this
);
this.mCallManager = new CallManager(
this.callEventListener,
this.props.notify
);
}
componentDidMount() {
// EVENT CAPTURE FOR ENTER TO SEND
window.onkeypress = (ev) => {
if (ev.code === 'Enter') {
if (ev.target === document.getElementById('chat-message-box-input')) {
if (ev.shiftKey === false && this.state.gif === true) ev.preventDefault();
if (ev.code === "Enter") {
if (ev.target === document.getElementById("chat-message-box-input")) {
if (ev.shiftKey === false && this.state.gif === true)
ev.preventDefault();
if (ev.shiftKey === false && this.state.gif === false) {
ev.preventDefault();
this.sendMessageInvoker();
@@ -137,12 +151,15 @@ export default class Chat extends Component {
};
// FULLSCREEN LISTENER
document.addEventListener('fullscreenchange', (ev) => {
document.addEventListener("fullscreenchange", (ev) => {
this.setState({ isFullscreen: document.fullscreen });
});
// ACTIVE TRACKER
if (LocalData().allowAutoRejoin === undefined || LocalData().allowAutoRejoin === null) {
if (
LocalData().allowAutoRejoin === undefined ||
LocalData().allowAutoRejoin === null
) {
updateLocalData({ allowAutoRejoin: this.state.allowAutoRejoin });
}
if (this.state.allowAutoRejoin === true) {
@@ -161,14 +178,14 @@ export default class Chat extends Component {
this.port = chrome.runtime.connect({ name: LocalData().partyName });
// Initialize listener
this.port.postMessage({
type: 'INIT',
type: "INIT",
roomId: LocalData().partyName,
roomPin: LocalData().partyPin,
});
// Listener
this.port.onMessage.addListener((response) => {
if (response.isError === true) {
this.props.notify('Uh oh. Got lost from the party.');
this.props.notify("Uh oh. Got lost from the party.");
goTo(Create, this.props);
return;
}
@@ -178,13 +195,21 @@ export default class Chat extends Component {
}
// IF CHAT IS HIDDEN AND ALLOWS NOTIFICATION
if (!document.querySelector('body.visible') && this.state.allowChatNotification === true) {
if (response.messages && response.messages.length !== this.state.messages.length) {
if (
!document.querySelector("body.visible") &&
this.state.allowChatNotification === true
) {
if (
response.messages &&
response.messages.length !== this.state.messages.length
) {
const lastMessage = response.messages[response.messages.length - 1];
if (lastMessage.uid !== '<system>') {
if (lastMessage.uid !== "<system>") {
this.props.notify(
`${lastMessage.name}${
lastMessage.type === 'giphy' ? ' sent a gif.' : ': ' + lastMessage.text
lastMessage.type === "giphy"
? " sent a gif."
: ": " + lastMessage.text
}`
);
}
@@ -200,12 +225,26 @@ export default class Chat extends Component {
// GIPHY IPC
const giphyInject = `var giphySearchInteraction=function(e){if(e.source===window){const{data}=e;if(data.watchPartyDirection==='TO_SCRIPT'){if(data.type==='WATCH_PARTY_SEARCH_GIF'){const giphyInput=document.querySelector('.giphy-search-form input');if(giphyInput){giphyInput.value=data.value;giphyInput.dispatchEvent(new Event('change',{bubbles:true}))}}}}};window.addEventListener("message",giphySearchInteraction);`;
const giphyInjectScript = document.createElement('script');
const giphyInjectScript = document.createElement("script");
giphyInjectScript.text = giphyInject;
document.head.appendChild(giphyInjectScript);
// DONE WITH MOUNTING TASKS
this.props.updateLoading(false);
setInterval(() => {
if (
this.state.player &&
this.state.player.time &&
this.state.player.status === PLAYER_STATUS.PLAYING
) {
const oldPlayer = this.state.player;
oldPlayer.time += 1;
this.setState({
player: oldPlayer,
});
}
}, 1000);
}
componentWillUnmount() {
this.mVideoListener.end();
@@ -238,14 +277,14 @@ export default class Chat extends Component {
}).catch((err) => {
this.props.updateLoading(false);
this.props.notify(err.message || err.statusText);
console.error('Sync Party API error', err);
console.error("Sync Party API error", err);
});
} else {
this.mVideoListener.start();
}
}
endParty() {
this.props.notify('Ending party...');
this.props.notify("Ending party...");
this.props.updateLoading(true);
const data = {
partyName: LocalData().partyName,
@@ -259,20 +298,20 @@ export default class Chat extends Component {
);
DeleteRoomApi(data)
.then((res) => {
this.props.notify('Ended party');
removeLocalData('partyPin');
removeLocalData('partyName');
this.props.notify("Ended party");
removeLocalData("partyPin");
removeLocalData("partyName");
goTo(Create, this.props);
this.props.updateLoading(false);
})
.catch((err) => {
this.props.updateLoading(false);
this.props.notify(err.message || err.statusText);
console.error('End Party API error', err);
console.error("End Party API error", err);
});
}
leaveParty() {
this.props.notify('Leaving party...');
this.props.notify("Leaving party...");
this.props.updateLoading(true);
const data = {
partyName: LocalData().partyName,
@@ -287,28 +326,30 @@ export default class Chat extends Component {
);
LeaveRoomApi(data)
.then((res) => {
this.props.notify('Left party');
removeLocalData('partyPin');
removeLocalData('partyName');
this.props.notify("Left party");
removeLocalData("partyPin");
removeLocalData("partyName");
goTo(Create, this.props);
this.props.updateLoading(false);
})
.catch((err) => {
this.props.updateLoading(false);
this.props.notify(err.message || err.statusText);
console.error('End Party API error', err);
console.error("End Party API error", err);
});
}
shareParty() {
const el = document.createElement('textarea');
el.value = `Join my party on Watch Party!\nParty Name: ${LocalData().partyName}\nParty Pin: ${
LocalData().partyPin
}\n${window.location.href}\n---\nGet Watch Party at https:\\\\get.chromewatchparty.com`;
const el = document.createElement("textarea");
el.value = `Join my party on Watch Party!\nParty Name: ${
LocalData().partyName
}\nParty Pin: ${LocalData().partyPin}\n${
window.location.href
}\n---\nGet Watch Party at https:\\\\get.chromewatchparty.com`;
document.body.appendChild(el);
el.select();
document.execCommand('copy');
document.execCommand("copy");
document.body.removeChild(el);
this.props.notify('Copied party invitation');
this.props.notify("Copied party invitation");
}
sendMessage(message) {
const { sendingMessages } = this.state;
@@ -319,9 +360,9 @@ export default class Chat extends Component {
uid: LocalData().userUid,
text: message,
time: new Date(),
type: '',
type: "",
};
if (this.state.gif === true) data.type = 'giphy';
if (this.state.gif === true) data.type = "giphy";
if (this.state.replyTo !== null) data.replyTo = this.state.replyTo.id;
sendingMessages.push(data);
this.setState({
@@ -342,7 +383,7 @@ export default class Chat extends Component {
this.setState({ sendingMessages: sm });
scrollThread();
this.props.notify(err.message || err.statusText);
console.error('Send Message API error', err);
console.error("Send Message API error", err);
});
this.setState({ replyTo: null });
scrollThread();
@@ -350,10 +391,10 @@ export default class Chat extends Component {
sendMessageInvoker(overrideMessage) {
if (overrideMessage) this.sendMessage(overrideMessage);
else {
const trim = this.state.newMessage.replace(/^\s+|\s+$/g, '');
if (trim !== '') this.sendMessage(trim);
const trim = this.state.newMessage.replace(/^\s+|\s+$/g, "");
if (trim !== "") this.sendMessage(trim);
}
this.setState({ newMessage: '' });
this.setState({ newMessage: "" });
}
gifClick(iGif) {
this.sendMessageInvoker(iGif.images.original.url);
@@ -362,29 +403,29 @@ export default class Chat extends Component {
const { onCall, conference, admin, adminOnly } = this.state;
if (window.navigator && onCall === false) {
try {
const overlay = document.createElement('div');
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';
overlay.id = "mic-permission-overlay";
document.body.appendChild(overlay);
window.navigator
.getUserMedia({
audio: true,
})
.then(() => {
document.getElementById('mic-permission-overlay').remove();
document.getElementById("mic-permission-overlay").remove();
this.mCallManager.toggleCall(onCall, conference, admin, adminOnly);
})
.catch(() => {
document.getElementById('mic-permission-overlay').remove();
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.'
"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.error('Handle Phone Call Error', err);
console.error("Handle Phone Call Error", err);
}
} else this.mCallManager.toggleCall(onCall, conference, admin, adminOnly);
}
@@ -397,7 +438,9 @@ export default class Chat extends Component {
: new Date(t * 1000).toISOString().substr(14, 5);
}
updateAllowChatNotification() {
updateLocalData({ allowChatNotification: !this.state.allowChatNotification });
updateLocalData({
allowChatNotification: !this.state.allowChatNotification,
});
this.setState({ allowChatNotification: !this.state.allowChatNotification });
}
updateAllowAutoRejoin() {
@@ -418,7 +461,7 @@ export default class Chat extends Component {
adminOnly: !this.state.adminOnly,
}).catch((err) => {
this.props.notify(err.message || err.statusText);
console.error('Update Admin Only API error', err);
console.error("Update Admin Only API error", err);
});
}
setReplyTo(message) {
@@ -430,7 +473,7 @@ export default class Chat extends Component {
getReplyToContent() {
const { replyTo } = this.state;
if (replyTo) {
if (replyTo.type === 'giphy') {
if (replyTo.type === "giphy") {
return <img alt="gif" src={replyTo.text} />;
}
return (
@@ -442,7 +485,7 @@ export default class Chat extends Component {
return null;
}
setVideoVolume(v, id) {
const audioOuts = document.querySelectorAll('audio.vxt-audio');
const audioOuts = document.querySelectorAll("audio.vxt-audio");
if (audioOuts.length > 0) {
audioOuts.forEach((el) => {
if (el.id === `audio-${id}`) {
@@ -479,20 +522,23 @@ export default class Chat extends Component {
const alerts = [
{
condition: () =>
getPlayerSource() === PLAYER_SOURCE.HBOMAX || getPlayerSource() === PLAYER_SOURCE.HBONOW,
message: 'Functionality may be buggy, HBO has a horrible design.',
getPlayerSource() === PLAYER_SOURCE.HBOMAX ||
getPlayerSource() === PLAYER_SOURCE.HBONOW,
message: "Functionality may be buggy, HBO has a horrible design.",
},
{
condition: () => getPlayerSource() === PLAYER_SOURCE.GOOGLEPLAY,
message: 'Functionality may be buggy, support on this site is in testing.',
message:
"Functionality may be buggy, support on this site is in testing.",
},
{
condition: () => getPlayerSource() === PLAYER_SOURCE.CRUNCHYROLL,
message: 'Functionality may be buggy, support on this site is in testing.',
message:
"Functionality may be buggy, support on this site is in testing.",
},
{
condition: () => adminOnly,
message: 'Party is currently in admin only mode.',
message: "Party is currently in admin only mode.",
},
];
return (
@@ -519,7 +565,12 @@ export default class Chat extends Component {
>
WATCH PARTY
</Typography>
<Typography color="textPrimary" className="room-title" variant="h4" gutterBottom>
<Typography
color="textPrimary"
className="room-title"
variant="h4"
gutterBottom
>
{name}
</Typography>
</div>
@@ -528,9 +579,9 @@ export default class Chat extends Component {
<TextField
className="share-textbox"
label="Party Details"
value={`Party Name: ${LocalData().partyName}\nParty Pin: ${LocalData().partyPin}\n${
window.location.href
}`}
value={`Party Name: ${LocalData().partyName}\nParty Pin: ${
LocalData().partyPin
}\n${window.location.href}`}
multiline
rowsMax={2}
variant="outlined"
@@ -557,13 +608,19 @@ export default class Chat extends Component {
color="secondary"
>
<Button onClick={this.leaveParty} startIcon={<Exit />}>
<Typography variant="caption" className="party-control-button-text">
<Typography
variant="caption"
className="party-control-button-text"
>
Leave
</Typography>
</Button>
{admin && (
<Button onClick={this.endParty} startIcon={<Delete />}>
<Typography variant="caption" className="party-control-button-text">
<Typography
variant="caption"
className="party-control-button-text"
>
End
</Typography>
</Button>
@@ -576,15 +633,17 @@ export default class Chat extends Component {
checked={allowChatNotification}
onChange={this.updateAllowChatNotification}
name="allowChatNotification"
color={allowChatNotification ? 'secondary' : 'primary'}
color={allowChatNotification ? "secondary" : "primary"}
/>
}
label={
<span>
Allow chat notification when side panel is closed
<br />
<span style={{ color: '#8a8a8a' }}>
{allowChatNotification ? 'Notifications Enabled' : 'Notifications Disabled'}
<span style={{ color: "#8a8a8a" }}>
{allowChatNotification
? "Notifications Enabled"
: "Notifications Disabled"}
</span>
</span>
}
@@ -597,15 +656,17 @@ export default class Chat extends Component {
checked={allowAutoRejoin}
onChange={this.updateAllowAutoRejoin}
name="allowAutoRejoin"
color={allowAutoRejoin ? 'secondary' : 'primary'}
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 style={{ color: "#8a8a8a" }}>
{allowAutoRejoin
? "Auto Rejoin Enabled"
: "Auto Rejoin Disabled"}
</span>
</span>
}
@@ -619,7 +680,7 @@ export default class Chat extends Component {
checked={adminOnly}
onChange={this.updateAdminOnly}
name="adminOnly"
color={adminOnly ? 'secondary' : 'primary'}
color={adminOnly ? "secondary" : "primary"}
disabled={adminModeUpdate}
/>
}
@@ -627,38 +688,53 @@ export default class Chat extends Component {
<span>
Admin Only Mode
<br />
<span style={{ color: '#8a8a8a' }}>
<span style={{ color: "#8a8a8a" }}>
{adminOnly
? 'Only admin can update player and start calls right now'
: 'All party members can update player and start calls right now'}
? "Only admin can update player and start calls right now"
: "All party members can update player and start calls right now"}
</span>
</span>
}
labelPlacement="end"
/>
) : null}
<Typography className="party-controls-users-title" variant="overline">
<Typography
className="party-controls-users-title"
variant="overline"
>
PARTY MEMBERS
</Typography>
<div className="party-controls-users-container">
{users.map((user) => (
<Chip className="party-controls-users-chip" clickable size="small" label={user} />
<Chip
className="party-controls-users-chip"
clickable
size="small"
label={user}
/>
))}
</div>
{Object.keys(usersOnCall).length > 0 ? (
<Typography className="party-controls-users-title" variant="overline">
<Typography
className="party-controls-users-title"
variant="overline"
>
MEMBERS IN CALL
</Typography>
) : null}
{Object.keys(usersOnCall).length > 0 ? (
<div className="party-controls-users-container">
{Object.keys(usersOnCall).map((id) => {
return usersOnCall[id].status === 'Connected' ||
usersOnCall[id].status === 'Connecting' ? (
return usersOnCall[id].status === "Connected" ||
usersOnCall[id].status === "Connecting" ? (
<Tooltip
interactive
title={
<Grid className="party-controls-users-volume" container spacing={2}>
<Grid
className="party-controls-users-volume"
container
spacing={2}
>
<Grid item>
<VolumeDown />
</Grid>
@@ -669,7 +745,9 @@ export default class Chat extends Component {
step={1}
color="secondary"
value={volumes[id] || 10}
onChangeCommitted={(e, v) => this.setVideoVolume(v, id)}
onChangeCommitted={(e, v) =>
this.setVideoVolume(v, id)
}
/>
</Grid>
<Grid item>
@@ -680,14 +758,15 @@ export default class Chat extends Component {
>
<Chip
color={
usersOnCall[id].info.externalId === LocalData().userUid
? 'secondary'
: 'default'
usersOnCall[id].info.externalId ===
LocalData().userUid
? "secondary"
: "default"
}
className="party-controls-users-chip"
clickable
size="small"
label={usersOnCall[id].info.name || ' '}
label={usersOnCall[id].info.name || " "}
/>
</Tooltip>
) : null;
@@ -698,13 +777,14 @@ export default class Chat extends Component {
</ExpansionPanel>
{player ? (
<Card elevation={0} className="media-info-card">
{player.showName && player.status !== PLAYER_STATUS.NOT_PLAYING ? (
{player.showName &&
player.status !== PLAYER_STATUS.NOT_PLAYING ? (
<CardContent>
<Typography className="media-info-at" variant="overline">
{player.status === PLAYER_STATUS.PAUSED
? `PAUSED AT ${this.getPrettyTime(player.time)}`
: player.status === PLAYER_STATUS.PLAYING
? `STARTED PLAYING FROM ${this.getPrettyTime(player.time)}`
? `CURRENTLY PLAYING (${this.getPrettyTime(player.time)})`
: `SHOW IS AT ${this.getPrettyTime(player.time)}`}
</Typography>
<div className="media-info-container">
@@ -723,12 +803,17 @@ export default class Chat extends Component {
) : (
<CardContent>
<Typography className="media-info-at" variant="caption">
Nothing playing right now
Nothing playing right now, pause or play once after starting
a show to start sync.
</Typography>
</CardContent>
)}
{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 currently playing
</Button>
) : null}
@@ -759,7 +844,9 @@ export default class Chat extends Component {
<Paper
square
variant="outlined"
className={`replying-to-card ${replyTo !== null ? 'replying-to-card-up' : ''}`}
className={`replying-to-card ${
replyTo !== null ? "replying-to-card-up" : ""
}`}
>
<div className="replying-to-content">
<Typography variant="overline" display="block" gutterBottom>
@@ -773,8 +860,15 @@ export default class Chat extends Component {
</Paper>
<div className="text-phone-panel">
{gif || newMessage ? null : (
<Tooltip title="Fullscreen with Watch Party" aria-label="Fullscreen">
<IconButton className="icon-button" color="secondary" onClick={this.toggleFullscreen}>
<Tooltip
title="Fullscreen with Watch Party"
aria-label="Fullscreen"
>
<IconButton
className="icon-button"
color="secondary"
onClick={this.toggleFullscreen}
>
{isFullscreen ? <FullscreenExit /> : <Fullscreen />}
</IconButton>
</Tooltip>
@@ -785,7 +879,7 @@ export default class Chat extends Component {
<IconButton
disabled={callActionPending}
onClick={this.handlePhoneCall}
color={!onCall ? 'secondary' : 'primary'}
color={!onCall ? "secondary" : "primary"}
className="icon-button"
>
{onCall ? (
@@ -827,12 +921,14 @@ export default class Chat extends Component {
multiline
rowsMax="3"
size="small"
placeholder={this.state.gif ? 'Search something...' : 'Say something...'}
placeholder={
this.state.gif ? "Search something..." : "Say something..."
}
helperText={
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
? 'Click on gif to send / Scroll to load more'
? "Click on gif to send / Scroll to load more"
: null
}
variant="outlined"
@@ -843,19 +939,19 @@ export default class Chat extends Component {
scrollThread();
if (gif) {
window.postMessage({
watchPartyDirection: 'TO_SCRIPT',
type: 'WATCH_PARTY_SEARCH_GIF',
watchPartyDirection: "TO_SCRIPT",
type: "WATCH_PARTY_SEARCH_GIF",
value: e.target.value,
});
}
}}
InputProps={{
id: 'chat-message-box-input',
id: "chat-message-box-input",
endAdornment: (
<InputAdornment position="end">
<IconButton
className={`${this.state.gif ? 'gif-active' : ''} ${
this.state.newMessage ? 'message-active' : ''
className={`${this.state.gif ? "gif-active" : ""} ${
this.state.newMessage ? "message-active" : ""
} message-send`}
size="small"
onClick={() => this.sendMessageInvoker(newMessage)}
@@ -868,13 +964,15 @@ export default class Chat extends Component {
startAdornment: (
<InputAdornment position="start">
<IconButton
className={`gif-button ${this.state.gif ? 'gif-close' : ''}`}
className={`gif-button ${
this.state.gif ? "gif-close" : ""
}`}
onClick={() => {
this.setState({ gif: !gif });
if (!gif) {
window.postMessage({
watchPartyDirection: 'TO_SCRIPT',
type: 'WATCH_PARTY_SEARCH_GIF',
watchPartyDirection: "TO_SCRIPT",
type: "WATCH_PARTY_SEARCH_GIF",
value: newMessage,
});
scrollThread();
@@ -892,9 +990,9 @@ export default class Chat extends Component {
<ReactGiphySearchbox
apiKey="ojJbIMUN6XRMn4mHiFFav3rMCpXUg8sq"
onSelect={this.gifClick}
masonryConfig={[{ columns: 2, imageWidth: '50%', gutter: 5 }]}
masonryConfig={[{ columns: 2, imageWidth: "50%", gutter: 5 }]}
searchFormClassName="giphy-search-form"
wrapperClassName={`giphy-wrapper ${gif ? '' : 'giphy-wrapper-down'}`}
wrapperClassName={`giphy-wrapper ${gif ? "" : "giphy-wrapper-down"}`}
listWrapperClassName="giphy-list-wrapper"
listItemClassName="giphy-list-item"
poweredByGiphy