Created
July 1, 2017 14:17
-
-
Save madhavrathi/cabad481d0519170750965fdb81f6645 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import MessageComposer from '../MessageComposer.react'; | |
import MessageListItem from '../MessageListItem.react'; | |
import MessageStore from '../../../stores/MessageStore'; | |
import React, { Component } from 'react'; | |
import ThreadStore from '../../../stores/ThreadStore'; | |
import * as Actions from '../../../actions/'; | |
import SettingStore from '../../../stores/SettingStore'; | |
import UserPreferencesStore from '../../../stores/UserPreferencesStore'; | |
import MenuItem from 'material-ui/MenuItem'; | |
import IconButton from 'material-ui/IconButton'; | |
import IconMenu from 'material-ui/IconMenu'; | |
import MoreVertIcon from 'material-ui/svg-icons/navigation/more-vert'; | |
import PropTypes from 'prop-types'; | |
import { Link } from 'react-router-dom'; | |
import { addUrlProps, UrlQueryParamTypes } from 'react-url-query'; | |
import loadingGIF from '../../images/loading.gif'; | |
import Cookies from 'universal-cookie'; | |
import DialogSection from './DialogSection'; | |
import RaisedButton from 'material-ui/RaisedButton'; | |
import { CirclePicker } from 'react-color'; | |
import $ from 'jquery'; | |
import { Scrollbars } from 'react-custom-scrollbars'; | |
import {Toolbar, ToolbarGroup} from 'material-ui/Toolbar'; | |
import ExpandingSearchField from '../SearchField.react' | |
const cookies = new Cookies(); | |
function getStateFromStores() { | |
return { | |
messages: MessageStore.getAllForCurrentThread(), | |
thread: ThreadStore.getCurrent(), | |
currTheme: UserPreferencesStore.getTheme(), | |
search: SettingStore.getSearchMode(), | |
showLoading: MessageStore.getLoadStatus(), | |
open: false, | |
showSettings: false, | |
showThemeChanger:false, | |
showHardwareChangeDialog: false, | |
showHardware: false, | |
showServerChangeDialog: false, | |
header: UserPreferencesStore.getTheme()==='light' ? '#607D8B' : '#19314B', | |
pane: '', | |
textarea: '', | |
composer:'', | |
body:'', | |
searchState: { | |
markedMsgs: [], | |
markedIDs: [], | |
markedIndices: [], | |
scrollLimit: 0, | |
scrollIndex: -1, | |
scrollID: null, | |
caseSensitive: false, | |
open: false, | |
searchText:'', | |
} | |
}; | |
} | |
function getMessageListItem(messages, markID) { | |
if(markID){ | |
return messages.map((message) => { | |
return ( | |
<MessageListItem | |
key={message.id} | |
message={message} | |
markID={markID} | |
/> | |
); | |
}); | |
} | |
return messages.map((message) => { | |
return ( | |
<MessageListItem | |
key={message.id} | |
message={message} | |
/> | |
); | |
}); | |
} | |
function searchMsgs(messages, matchString, isCaseSensitive) { | |
let markingData = { | |
allmsgs: [], | |
markedIDs: [], | |
markedIndices: [], | |
}; | |
messages.forEach((msg, id) => { | |
let orgMsgText = msg.text; | |
let msgCopy = $.extend(true, {}, msg); | |
let msgText = orgMsgText; | |
if (orgMsgText) { | |
if (!isCaseSensitive) { | |
matchString = matchString.toLowerCase(); | |
msgText = msgText.toLowerCase(); | |
} | |
let match = msgText.indexOf(matchString); | |
if (match !== -1) { | |
msgCopy.mark = { | |
matchText: matchString, | |
isCaseSensitive: isCaseSensitive | |
}; | |
markingData.markedIDs.unshift(msgCopy.id); | |
markingData.markedIndices.unshift(id); | |
} | |
} | |
markingData.allmsgs.push(msgCopy); | |
}); | |
return markingData; | |
} | |
function getLoadingGIF() { | |
let messageContainerClasses = 'message-container SUSI'; | |
const LoadingComponent = ( | |
<li className='message-list-item'> | |
<section className={messageContainerClasses}> | |
<img src={loadingGIF} | |
style={{ height: '10px', width: 'auto' }} | |
alt='please wait..' /> | |
</section> | |
</li> | |
); | |
return LoadingComponent; | |
} | |
const urlPropsQueryConfig = { | |
dream: { type: UrlQueryParamTypes.string } | |
}; | |
let Logged = (props) => ( | |
<IconMenu | |
{...props} | |
iconButtonElement={ | |
<IconButton | |
iconStyle={{ fill: 'white' }}><MoreVertIcon /></IconButton> | |
} | |
targetOrigin={{ horizontal: 'right', vertical: 'top' }} | |
anchorOrigin={{ horizontal: 'right', vertical: 'top' }} | |
> | |
</IconMenu> | |
) | |
class MessageSection extends Component { | |
static propTypes = { | |
dream: PropTypes.string | |
}; | |
static defaultProps = { | |
dream: '' | |
}; | |
state = { | |
open: false | |
}; | |
constructor(props) { | |
super(props); | |
this.state = getStateFromStores(); | |
} | |
handleColorChange = (name,color) => { | |
// Current Changes | |
} | |
handleChangeComplete = (name, color) => { | |
// Send these Settings to Server | |
let state = this.state; | |
if(name === 'header'){ | |
state.header = color.hex; | |
} | |
else if(name === 'body'){ | |
state.body= color.hex; | |
document.body.style.setProperty('background', color.hex); | |
} | |
else if(name === 'pane') { | |
state.pane = color.hex; | |
} | |
else if(name === 'composer'){ | |
state.composer = color.hex; | |
} | |
else if(name === 'textarea') { | |
state.textarea = color.hex; | |
} | |
this.setState(state); | |
} | |
handleOpen = () => { | |
this.setState({ open: true }); | |
} | |
handleClose = () => { | |
this.setState({ | |
open: false, | |
showSettings: false, | |
showThemeChanger: false, | |
showHardware: false | |
}); | |
} | |
handleThemeChanger = () => { | |
this.setState({showThemeChanger: true}); | |
} | |
handleSettings = () => { | |
this.setState({showSettings: true}); | |
} | |
handleHardwareToggle = () => { | |
this.setState({ | |
showSettings: true, | |
showServerChangeDialog: false, | |
showHardwareChangeDialog: false | |
}); | |
} | |
hardwareSettingChanged = () => { | |
this.setState({ | |
showSettings: false, | |
showServerChangeDialog: false, | |
showHardwareChangeDialog: true | |
}); | |
} | |
changeTheme = (newTheme) => { | |
if(this.state.currTheme !== newTheme){ | |
let headerColor = ''; | |
switch(newTheme){ | |
case 'light': { | |
headerColor = '#607d8b'; | |
break; | |
} | |
case 'dark': { | |
headerColor = '#19324c'; | |
break; | |
} | |
default: { | |
// do nothing | |
} | |
} | |
this.setState({header: headerColor}); | |
Actions.themeChanged(newTheme); | |
} | |
} | |
serverSettingChanged = () => { | |
this.setState({ | |
showSettings: false, | |
showHardware: false, | |
showServerChangeDialog: true | |
}); | |
} | |
handleServerToggle = (changeServer) => { | |
if(changeServer){ | |
// Logout the user and show the login screen again | |
this.props.history.push('/logout'); | |
this.setState({ | |
open:true | |
}); | |
} | |
else{ | |
// Go back to settings dialog | |
this.setState({ | |
showSettings: true, | |
showServerChangeDialog: false, | |
showHardwareChangeDialog: false | |
}); | |
} | |
} | |
implementSettings = (values) => { | |
this.setState({showSettings: false}); | |
this.changeTheme(values.theme); | |
} | |
searchTextChanged = (event) => { | |
let matchString = event.target.value; | |
let messages = this.state.messages; | |
let markingData = searchMsgs(messages, matchString, | |
this.state.searchState.caseSensitive); | |
if(matchString){ | |
let searchState = { | |
markedMsgs: markingData.allmsgs, | |
markedIDs: markingData.markedIDs, | |
markedIndices: markingData.markedIndices, | |
scrollLimit: markingData.markedIDs.length, | |
scrollIndex: 0, | |
scrollID: markingData.markedIDs[0], | |
caseSensitive: this.state.searchState.caseSensitive, | |
open: false, | |
searchText: matchString | |
}; | |
this.setState({ | |
searchState: searchState | |
}); | |
} | |
else { | |
let searchState = { | |
markedMsgs: markingData.allmsgs, | |
markedIDs: markingData.markedIDs, | |
markedIndices: markingData.markedIndices, | |
scrollLimit: markingData.markedIDs.length, | |
scrollIndex: -1, | |
scrollID: null, | |
caseSensitive: this.state.caseSensitive, | |
open: false, | |
searchText: '' | |
} | |
this.setState({ | |
searchState: searchState | |
}); | |
} | |
} | |
componentDidMount() { | |
this._scrollToBottom(); | |
MessageStore.addChangeListener(this._onChange.bind(this)); | |
ThreadStore.addChangeListener(this._onChange.bind(this)); | |
SettingStore.addChangeListener(this._onChange.bind(this)); | |
// Check Logged in | |
if (cookies.get('loggedIn')) { | |
Logged = (props) => ( | |
<IconMenu | |
{...props} | |
iconButtonElement={ | |
<IconButton iconStyle={{ fill: 'white' }}> | |
<MoreVertIcon /></IconButton> | |
} | |
targetOrigin={{ horizontal: 'right', vertical: 'top' }} | |
anchorOrigin={{ horizontal: 'right', vertical: 'top' }} | |
> | |
<MenuItem primaryText="Settings" | |
onClick={this.handleSettings} /> | |
<MenuItem primaryText="Custom Theme" | |
key="custom" | |
onClick={this.handleThemeChanger} /> | |
<MenuItem primaryText="Chat Anonymously" | |
containerElement={<Link to="/logout" />} /> | |
<MenuItem primaryText="Logout" | |
containerElement={<Link to="/logout" />} /> | |
</IconMenu>) | |
return <Logged /> | |
} | |
// If Not Logged In | |
Logged = (props) => ( | |
<IconMenu | |
{...props} | |
iconButtonElement={ | |
<IconButton iconStyle={{ fill: 'white' }}> | |
<MoreVertIcon /></IconButton> | |
} | |
targetOrigin={{ horizontal: 'right', vertical: 'top' }} | |
anchorOrigin={{ horizontal: 'right', vertical: 'top' }} | |
> | |
<MenuItem primaryText="Settings" | |
onClick={this.handleSettings} /> | |
<MenuItem primaryText="Login" onTouchTap={this.handleOpen} /> | |
<MenuItem primaryText="Sign Up" | |
containerElement={<Link to="/signup" />} /> | |
</IconMenu>) | |
return <Logged /> | |
} | |
componentWillUnmount() { | |
MessageStore.removeChangeListener(this._onChange.bind(this)); | |
ThreadStore.removeChangeListener(this._onChange.bind(this)); | |
SettingStore.removeChangeListener(this._onChange.bind(this)); | |
} | |
componentWillMount() { | |
if (this.props.location) { | |
if (this.props.location.state) { | |
if (this.props.location.state.hasOwnProperty('showLogin')) { | |
let showLogin = this.props.location.state.showLogin; | |
this.setState({ open: showLogin }); | |
} | |
} | |
} | |
UserPreferencesStore.on('change', () => { | |
this.setState({ | |
currTheme: UserPreferencesStore.getTheme() | |
}) | |
switch(this.state.currTheme){ | |
case 'light':{ | |
document.body.className = 'white-body'; | |
break; | |
} | |
case 'dark':{ | |
document.body.className = 'dark-body'; | |
break; | |
} | |
default: { | |
// do nothing | |
} | |
} | |
}) | |
} | |
render() { | |
const bodyStyle = { | |
'padding': 0, | |
textAlign: 'center' | |
} | |
const { | |
dream | |
} = this.props; | |
var backgroundCol; | |
let topBackground = this.state.currTheme; | |
switch(topBackground){ | |
case 'light':{ | |
backgroundCol = '#607d8b'; | |
break; | |
} | |
case 'dark':{ | |
backgroundCol = '#19324c'; | |
break; | |
} | |
default: { | |
// do nothing | |
} | |
} | |
const actions = <RaisedButton | |
label="Cancel" | |
backgroundColor={ | |
UserPreferencesStore.getTheme()==='light' ? '#607D8B' : '#19314B'} | |
labelColor="#fff" | |
width='200px' | |
keyboardFocused={true} | |
onTouchTap={this.handleClose} | |
/>; | |
const serverDialogActions = [ | |
<RaisedButton | |
key={'Cancel'} | |
label="Cancel" | |
backgroundColor={ | |
UserPreferencesStore.getTheme()==='light' ? '#607D8B' : '#19314B'} | |
labelColor="#fff" | |
width='200px' | |
keyboardFocused={false} | |
onTouchTap={this.handleServerToggle.bind(this,false)} | |
style={{margin: '6px'}} | |
/>, | |
<RaisedButton | |
key={'OK'} | |
label="OK" | |
backgroundColor={ | |
UserPreferencesStore.getTheme()==='light' ? '#607D8B' : '#19314B'} | |
labelColor="#fff" | |
width='200px' | |
keyboardFocused={false} | |
onTouchTap={this.handleServerToggle.bind(this,true)} | |
/>]; | |
const hardwareActions = [ | |
<RaisedButton | |
key={'Cancel'} | |
label="Cancel" | |
backgroundColor={ | |
UserPreferencesStore.getTheme()==='light' ? '#607D8B' : '#19314B'} | |
labelColor="#fff" | |
width='200px' | |
keyboardFocused={false} | |
onTouchTap={this.handleHardwareToggle} | |
style={{margin: '6px'}} | |
/> | |
] | |
const componentsList = [ | |
{'id':1, 'component':'header', 'name': 'Header'}, | |
{'id':2, 'component': 'pane', 'name': 'Message Pane'}, | |
{'id':3, 'component':'body', 'name': 'Body'}, | |
{'id':4, 'component':'composer', 'name': 'Composer'}, | |
{'id':5, 'component':'textarea', 'name': 'Textarea'} | |
]; | |
const components = componentsList.map((component) => { | |
return <div key={component.id} className='circleChoose'> | |
<h4>Change color of {component.name}:</h4> | |
<CirclePicker color={component} width={'100%'} | |
onChangeComplete={ this.handleChangeComplete.bind(this,component.component) } | |
onChange={this.handleColorChange.bind(this,component.id)}> | |
</CirclePicker></div> | |
}) | |
var body = this.state.body; | |
var pane = this.state.pane; | |
var composer = this.state.composer; | |
let messageListItems = []; | |
if(this.state.search){ | |
let markID = this.state.searchState.scrollID; | |
let markedMessages = this.state.searchState.markedMsgs; | |
messageListItems = getMessageListItem(markedMessages,markID); | |
} | |
else{ | |
messageListItems = getMessageListItem(this.state.messages); | |
} | |
if (this.state.thread) { | |
let appBarClass = 'app-bar'; | |
if(this.state.search){ | |
appBarClass = 'app-bar-search'; | |
} | |
return ( | |
<div className={topBackground} style={{background:body}}> | |
<header className='message-thread-heading' | |
style={{ backgroundColor: backgroundCol }}> | |
<Toolbar | |
className={appBarClass} | |
style={{ backgroundColor: backgroundCol, | |
height: '46px' }}> | |
<ToolbarGroup > | |
</ToolbarGroup> | |
<ToolbarGroup lastChild={true}> | |
<div style={{marginTop:'-7px'}}> | |
<ExpandingSearchField | |
onTextChange={this.searchTextChanged} | |
activateSearch={this._onClickSearch.bind(this)} | |
exitSearch={this._onClickExit.bind(this)} | |
scrollRecent={this._onClickRecent.bind(this)} | |
scrollPrev={this._onClickPrev.bind(this)}/> | |
</div> | |
<Logged /> | |
</ToolbarGroup> | |
</Toolbar> | |
</header> | |
{!this.state.search ? ( | |
<div> | |
<div className='message-pane'> | |
<div className='message-section'> | |
<ul | |
className='message-list' | |
ref={(c) => { this.messageList = c; }} | |
style={{background:pane}}> | |
<Scrollbars | |
autoHide | |
autoHideTimeout={1000} | |
autoHideDuration={200}> | |
{messageListItems} | |
</Scrollbars> | |
{this.state.showLoading && getLoadingGIF()} | |
</ul> | |
<div className='compose' style={{background:composer}}> | |
<MessageComposer | |
threadID={this.state.thread.id} | |
dream={dream} | |
textarea={this.state.textarea} /> | |
</div> | |
</div> | |
</div> | |
<DialogSection | |
{...this.props} | |
openLogin={this.state.open} | |
openSetting={this.state.showSettings} | |
openServerChange={this.state.showServerChangeDialog} | |
openHardwareChange={this.state.showHardwareChangeDialog} | |
openThemeChanger={this.state.showThemeChanger} | |
ThemeChangerComponents={components} | |
bodyStyle={bodyStyle} | |
actions={actions} | |
ServerChangeActions={serverDialogActions} | |
HardwareActions={hardwareActions} | |
onRequestClose={()=>this.handleClose} | |
onRequestCloseServerChange={()=>this.handleServerToggle.bind(this,false)} | |
onRequestCloseHardwareChange={ | |
()=>this.handleHardwareToggle.bind(this, false)} | |
onSettingsSubmit={()=>this.implementSettings} | |
onServerChange={()=>this.serverSettingChanged} | |
onHardwareSettings={()=>this.hardwareSettingChanged}/> | |
</div>) | |
: ( | |
<div className='message-pane'> | |
<div className='message-section'> | |
<ul | |
className="message-list" | |
ref={(c) => { this.messageList = c; }} | |
style={{background:pane}}> | |
<Scrollbars | |
autoHide | |
autoHideTimeout={1000} | |
autoHideDuration={200} | |
ref={(ref) => { this.scrollarea = ref; }}> | |
{messageListItems} | |
</Scrollbars> | |
</ul> | |
</div> | |
</div> | |
)} | |
</div> | |
); | |
} | |
return <div className='message-section'></div>; | |
} | |
componentDidUpdate() { | |
switch (this.state.currTheme) { | |
case 'light':{ | |
document.body.className = 'white-body'; | |
break; | |
} | |
case 'dark':{ | |
document.body.className = 'dark-body'; | |
break; | |
} | |
default: { | |
// do nothing | |
} | |
} | |
if(this.state.search){ | |
if (this.state.searchState.scrollIndex === -1 | |
|| this.state.searchState.scrollIndex === null) { | |
this._scrollToBottom(); | |
} | |
else { | |
let {markedIDs} = this.state.searchState; | |
let {markedIndices} = this.state.searchState; | |
let limit = this.state.searchState.scrollLimit; | |
let ul = this.messageList; | |
if (markedIDs && ul && limit > 0) { | |
let currentID = markedIndices[this.state.searchState.scrollIndex]; | |
this.scrollarea.content.childNodes[currentID].scrollIntoView(); | |
} | |
} | |
} | |
else{ | |
this._scrollToBottom(); | |
} | |
} | |
_scrollToBottom() { | |
let ul = this.messageList; | |
if (ul) { | |
ul.scrollTop = ul.scrollHeight; | |
} | |
} | |
_onClickPrev() { | |
let newIndex = this.state.searchState.scrollIndex + 1; | |
let indexLimit = this.state.searchState.scrollLimit; | |
let markedIDs = this.state.searchState.markedIDs; | |
let ul = this.messageList; | |
if (markedIDs && ul && newIndex < indexLimit) { | |
let currState = this.state.searchState; | |
currState.scrollIndex = newIndex; | |
currState.scrollID = markedIDs[newIndex]; | |
this.setState({ | |
searchState: currState | |
}); | |
} | |
} | |
_onClickRecent() { | |
let newIndex = this.state.searchState.scrollIndex - 1; | |
let markedIDs = this.state.searchState.markedIDs; | |
let ul = this.messageList; | |
if (markedIDs && ul && newIndex >= 0) { | |
let currState = this.state.searchState; | |
currState.scrollIndex = newIndex; | |
currState.scrollID = markedIDs[newIndex]; | |
this.setState({ | |
searchState: currState | |
}); | |
} | |
} | |
_onClickSearch() { | |
let searchState = this.state.searchState; | |
searchState.markedMsgs = this.state.messages; | |
this.setState({ | |
search: true, | |
searchState: searchState, | |
}); | |
} | |
_onClickExit(){ | |
this.setState({ | |
search: false, | |
}); | |
} | |
/** | |
* Event handler for 'change' events coming from the MessageStore | |
*/ | |
_onChange() { | |
this.setState(getStateFromStores()); | |
} | |
}; | |
Logged.muiName = 'IconMenu'; | |
MessageSection.propTypes = { | |
location: PropTypes.object, | |
history: PropTypes.object | |
}; | |
export default addUrlProps({ urlPropsQueryConfig })(MessageSection); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment