diff options
author | Christopher Speller <crspeller@gmail.com> | 2016-03-14 08:50:46 -0400 |
---|---|---|
committer | Christopher Speller <crspeller@gmail.com> | 2016-03-16 18:02:55 -0400 |
commit | 12896bd23eeba79884245c1c29fdc568cf21a7fa (patch) | |
tree | 4e7f83d3e2564b9b89d669e9f7905ff11768b11a /web/react/components/sidebar.jsx | |
parent | 29fe6a3d13c9c7aa490fffebbe5d1b5fdf1e3090 (diff) | |
download | chat-12896bd23eeba79884245c1c29fdc568cf21a7fa.tar.gz chat-12896bd23eeba79884245c1c29fdc568cf21a7fa.tar.bz2 chat-12896bd23eeba79884245c1c29fdc568cf21a7fa.zip |
Converting to Webpack. Stage 1.
Diffstat (limited to 'web/react/components/sidebar.jsx')
-rw-r--r-- | web/react/components/sidebar.jsx | 714 |
1 files changed, 0 insertions, 714 deletions
diff --git a/web/react/components/sidebar.jsx b/web/react/components/sidebar.jsx deleted file mode 100644 index 5c682d64b..000000000 --- a/web/react/components/sidebar.jsx +++ /dev/null @@ -1,714 +0,0 @@ -// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. -// See License.txt for license information. - -import NewChannelFlow from './new_channel_flow.jsx'; -import MoreDirectChannels from './more_direct_channels.jsx'; -import SidebarHeader from './sidebar_header.jsx'; -import UnreadChannelIndicator from './unread_channel_indicator.jsx'; -import TutorialTip from './tutorial/tutorial_tip.jsx'; - -import ChannelStore from '../stores/channel_store.jsx'; -import UserStore from '../stores/user_store.jsx'; -import TeamStore from '../stores/team_store.jsx'; -import PreferenceStore from '../stores/preference_store.jsx'; - -import * as AsyncClient from '../utils/async_client.jsx'; -import * as Client from '../utils/client.jsx'; -import * as Utils from '../utils/utils.jsx'; - -import Constants from '../utils/constants.jsx'; - -import {FormattedMessage, FormattedHTMLMessage} from 'mm-intl'; - -const Preferences = Constants.Preferences; -const TutorialSteps = Constants.TutorialSteps; - -const Tooltip = ReactBootstrap.Tooltip; -const OverlayTrigger = ReactBootstrap.OverlayTrigger; - -export default class Sidebar extends React.Component { - constructor(props) { - super(props); - - this.badgesActive = false; - this.firstUnreadChannel = null; - this.lastUnreadChannel = null; - - this.getStateFromStores = this.getStateFromStores.bind(this); - - this.onChange = this.onChange.bind(this); - this.onScroll = this.onScroll.bind(this); - this.updateUnreadIndicators = this.updateUnreadIndicators.bind(this); - this.handleLeaveDirectChannel = this.handleLeaveDirectChannel.bind(this); - this.handleResize = this.handleResize.bind(this); - - this.showMoreChannelsModal = this.showMoreChannelsModal.bind(this); - this.showNewChannelModal = this.showNewChannelModal.bind(this); - this.hideNewChannelModal = this.hideNewChannelModal.bind(this); - this.showMoreDirectChannelsModal = this.showMoreDirectChannelsModal.bind(this); - this.hideMoreDirectChannelsModal = this.hideMoreDirectChannelsModal.bind(this); - - this.createChannelElement = this.createChannelElement.bind(this); - this.updateTitle = this.updateTitle.bind(this); - - this.isLeaving = new Map(); - - const state = this.getStateFromStores(); - state.newChannelModalType = ''; - state.showDirectChannelsModal = false; - state.loadingDMChannel = -1; - state.windowWidth = Utils.windowWidth(); - this.state = state; - } - getTotalUnreadCount() { - let msgs = 0; - let mentions = 0; - const unreadCounts = this.state.unreadCounts; - - Object.keys(unreadCounts).forEach((chId) => { - msgs += unreadCounts[chId].msgs; - mentions += unreadCounts[chId].mentions; - }); - - return {msgs, mentions}; - } - getStateFromStores() { - const members = ChannelStore.getAllMembers(); - const currentChannelId = ChannelStore.getCurrentId(); - const currentUserId = UserStore.getCurrentId(); - - const channels = Object.assign([], ChannelStore.getAll()); - channels.sort((a, b) => a.display_name.localeCompare(b.display_name)); - - const publicChannels = channels.filter((channel) => channel.type === Constants.OPEN_CHANNEL); - const privateChannels = channels.filter((channel) => channel.type === Constants.PRIVATE_CHANNEL); - - const preferences = PreferenceStore.getCategory(Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW); - - const directChannels = []; - for (const preference of preferences) { - if (preference.value !== 'true') { - continue; - } - - const teammateId = preference.name; - - let directChannel = channels.find(Utils.isDirectChannelForUser.bind(null, teammateId)); - - // a direct channel doesn't exist yet so create a fake one - if (directChannel == null) { - directChannel = { - name: Utils.getDirectChannelName(currentUserId, teammateId), - last_post_at: 0, - total_msg_count: 0, - type: Constants.DM_CHANNEL, - fake: true - }; - } else { - directChannel = JSON.parse(JSON.stringify(directChannel)); - } - - directChannel.display_name = Utils.displayUsername(teammateId); - directChannel.teammate_id = teammateId; - directChannel.status = UserStore.getStatus(teammateId); - - directChannels.push(directChannel); - } - - directChannels.sort(this.sortChannelsByDisplayName); - - const hiddenDirectChannelCount = UserStore.getActiveOnlyProfileList(true).length - directChannels.length; - - const tutorialStep = PreferenceStore.getInt(Preferences.TUTORIAL_STEP, UserStore.getCurrentId(), 999); - - return { - activeId: currentChannelId, - members, - publicChannels, - privateChannels, - directChannels, - hiddenDirectChannelCount, - unreadCounts: JSON.parse(JSON.stringify(ChannelStore.getUnreadCounts())), - showTutorialTip: tutorialStep === TutorialSteps.CHANNEL_POPOVER, - currentTeam: TeamStore.getCurrent(), - currentUser: UserStore.getCurrentUser() - }; - } - - componentDidMount() { - ChannelStore.addChangeListener(this.onChange); - UserStore.addChangeListener(this.onChange); - UserStore.addStatusesChangeListener(this.onChange); - TeamStore.addChangeListener(this.onChange); - PreferenceStore.addChangeListener(this.onChange); - - this.updateTitle(); - this.updateUnreadIndicators(); - - window.addEventListener('resize', this.handleResize); - - if ($(window).width() > 768) { - $('.nav-pills__container').perfectScrollbar(); - } - } - shouldComponentUpdate(nextProps, nextState) { - if (!Utils.areObjectsEqual(nextState, this.state)) { - return true; - } - return false; - } - componentDidUpdate() { - this.updateTitle(); - this.updateUnreadIndicators(); - } - componentWillUnmount() { - window.removeEventListener('resize', this.handleResize); - - ChannelStore.removeChangeListener(this.onChange); - UserStore.removeChangeListener(this.onChange); - UserStore.removeStatusesChangeListener(this.onChange); - TeamStore.removeChangeListener(this.onChange); - PreferenceStore.removeChangeListener(this.onChange); - } - handleResize() { - this.setState({ - windowWidth: Utils.windowWidth(), - windowHeight: Utils.windowHeight() - }); - } - onChange() { - this.setState(this.getStateFromStores()); - } - updateTitle() { - const channel = ChannelStore.getCurrent(); - if (channel && this.state.currentTeam) { - let currentSiteName = ''; - if (global.window.mm_config.SiteName != null) { - currentSiteName = global.window.mm_config.SiteName; - } - - let currentChannelName = channel.display_name; - if (channel.type === 'D') { - const teammate = Utils.getDirectTeammate(channel.id); - if (teammate != null) { - currentChannelName = teammate.username; - } - } - - const unread = this.getTotalUnreadCount(); - const mentionTitle = unread.mentions > 0 ? '(' + unread.mentions + ') ' : ''; - const unreadTitle = unread.msgs > 0 ? '* ' : ''; - document.title = mentionTitle + unreadTitle + currentChannelName + ' - ' + this.state.currentTeam.display_name + ' ' + currentSiteName; - } - } - onScroll() { - this.updateUnreadIndicators(); - } - updateUnreadIndicators() { - const container = $(ReactDOM.findDOMNode(this.refs.container)); - - var showTopUnread = false; - var showBottomUnread = false; - - if (this.firstUnreadChannel) { - var firstUnreadElement = $(ReactDOM.findDOMNode(this.refs[this.firstUnreadChannel])); - - if (firstUnreadElement.position().top + firstUnreadElement.height() < 0) { - showTopUnread = true; - } - } - - if (this.lastUnreadChannel) { - var lastUnreadElement = $(ReactDOM.findDOMNode(this.refs[this.lastUnreadChannel])); - - if (lastUnreadElement.position().top > container.height()) { - showBottomUnread = true; - } - } - - this.setState({ - showTopUnread, - showBottomUnread - }); - } - - handleLeaveDirectChannel(channel) { - if (!this.isLeaving.get(channel.id)) { - this.isLeaving.set(channel.id, true); - - const preference = PreferenceStore.setPreference(Constants.Preferences.CATEGORY_DIRECT_CHANNEL_SHOW, channel.teammate_id, 'false'); - - // bypass AsyncClient since we've already saved the updated preferences - Client.savePreferences( - [preference], - () => { - this.isLeaving.set(channel.id, false); - }, - () => { - this.isLeaving.set(channel.id, false); - } - ); - - this.setState(this.getStateFromStores()); - } - - if (channel.id === this.state.activeId) { - Utils.switchChannel(ChannelStore.getByName(Constants.DEFAULT_CHANNEL)); - } - } - - sortChannelsByDisplayName(a, b) { - return a.display_name.localeCompare(b.display_name); - } - - showMoreChannelsModal() { - // manually show the modal because using data-toggle messes with keyboard focus when the modal is dismissed - $('#more_channels').modal({'data-channeltype': 'O'}).modal('show'); - } - - showNewChannelModal(type) { - this.setState({newChannelModalType: type}); - } - hideNewChannelModal() { - this.setState({newChannelModalType: ''}); - } - - showMoreDirectChannelsModal() { - this.setState({showDirectChannelsModal: true}); - } - hideMoreDirectChannelsModal() { - this.setState({showDirectChannelsModal: false}); - } - - createTutorialTip() { - const screens = []; - - screens.push( - <div> - <FormattedHTMLMessage - id='sidebar.tutorialScreen1' - defaultMessage='<h4>Channels</h4><p><strong>Channels</strong> organize conversations across different topics. They’re open to everyone on your team. To send private communications use <strong>Direct Messages</strong> for a single person or <strong>Private Groups</strong> for multiple people.</p>' - /> - </div> - ); - - screens.push( - <div> - <FormattedHTMLMessage - id='sidebar.tutorialScreen2' - defaultMessage='<h4>"Town Square" and "Off-Topic" channels</h4> - <p>Here are two public channels to start:</p> - <p><strong>Town Square</strong> is a place for team-wide communication. Everyone in your team is a member of this channel.</p> - <p><strong>Off-Topic</strong> is a place for fun and humor outside of work-related channels. You and your team can decide what other channels to create.</p>' - /> - </div> - ); - - screens.push( - <div> - <FormattedHTMLMessage - id='sidebar.tutorialScreen3' - defaultMessage='<h4>Creating and Joining Channels</h4> - <p>Click <strong>"More..."</strong> to create a new channel or join an existing one.</p> - <p>You can also create a new channel or private group by clicking the <strong>"+" symbol</strong> next to the channel or private group header.</p>' - /> - </div> - ); - - return ( - <TutorialTip - placement='right' - screens={screens} - overlayClass='tip-overlay--sidebar' - /> - ); - } - - createChannelElement(channel, index, arr, handleClose) { - const members = this.state.members; - const activeId = this.state.activeId; - const channelMember = members[channel.id]; - const unreadCount = this.state.unreadCounts[channel.id] || {msgs: 0, mentions: 0}; - let msgCount; - - let linkClass = ''; - if (channel.id === activeId) { - linkClass = 'active'; - } - - let rowClass = 'sidebar-channel'; - - var unread = false; - if (channelMember) { - msgCount = unreadCount.msgs + unreadCount.mentions; - unread = msgCount > 0 || channelMember.mention_count > 0; - } - - if (unread) { - rowClass += ' unread-title'; - - if (channel.id !== activeId) { - if (!this.firstUnreadChannel) { - this.firstUnreadChannel = channel.name; - } - this.lastUnreadChannel = channel.name; - } - } - - var badge = null; - if (channelMember) { - if (unreadCount.mentions) { - badge = <span className='badge pull-right small'>{unreadCount.mentions}</span>; - this.badgesActive = true; - } - } else if (this.state.loadingDMChannel === index && channel.type === 'D') { - badge = ( - <img - className='channel-loading-gif pull-right' - src='/static/images/load.gif' - /> - ); - } - - if (msgCount > 0) { - rowClass += ' has-badge'; - } - - // set up status icon for direct message channels - var status = null; - if (channel.type === 'D') { - var statusIcon = ''; - if (channel.status === 'online') { - statusIcon = Constants.ONLINE_ICON_SVG; - } else if (channel.status === 'away') { - statusIcon = Constants.AWAY_ICON_SVG; - } else { - statusIcon = Constants.OFFLINE_ICON_SVG; - } - status = ( - <span - className='status' - dangerouslySetInnerHTML={{__html: statusIcon}} - /> - ); - } - - var icon = null; - if (channel.type === 'O') { - icon = <div className='status'><i className='fa fa-globe'></i></div>; - } else if (channel.type === 'P') { - icon = <div className='status'><i className='fa fa-lock'></i></div>; - } - - // set up click handler to switch channels (or create a new channel for non-existant ones) - var handleClick = null; - var href = '#'; - - if (!channel.fake) { - handleClick = function clickHandler(e) { - if (e.target.attributes.getNamedItem('data-close')) { - handleClose(channel); - } else { - Utils.switchChannel(channel); - } - - e.preventDefault(); - }; - } else if (channel.fake) { - // It's a direct message channel that doesn't exist yet so let's create it now - var otherUserId = Utils.getUserIdFromChannelName(channel); - - if (this.state.loadingDMChannel === -1) { - handleClick = function clickHandler(e) { - e.preventDefault(); - - if (e.target.attributes.getNamedItem('data-close')) { - handleClose(channel); - } else { - this.setState({loadingDMChannel: index}); - - Client.createDirectChannel(channel, otherUserId, - (data) => { - this.setState({loadingDMChannel: -1}); - AsyncClient.getChannel(data.id); - Utils.switchChannel(data); - }, - () => { - this.setState({loadingDMChannel: -1}); - window.location.href = '/' + this.state.currentTeam.name; - } - ); - } - }.bind(this); - } - } - - let closeButton = null; - const removeTooltip = ( - <Tooltip id='remove-dm-tooltip'> - <FormattedMessage - id='sidebar.removeList' - defaultMessage='Remove from list' - /> - </Tooltip> - ); - if (handleClose && !badge) { - closeButton = ( - <OverlayTrigger - delayShow={1000} - placement='top' - overlay={removeTooltip} - > - <span - className='btn-close' - data-close='true' - > - {'×'} - </span> - </OverlayTrigger> - ); - - rowClass += ' has-close'; - } - - let tutorialTip = null; - if (this.state.showTutorialTip && channel.name === Constants.DEFAULT_CHANNEL) { - tutorialTip = this.createTutorialTip(); - } - - return ( - <li - key={channel.name} - ref={channel.name} - className={linkClass} - > - <a - className={rowClass} - href={href} - onClick={handleClick} - > - {icon} - {status} - {channel.display_name} - {badge} - {closeButton} - </a> - {tutorialTip} - </li> - ); - } - render() { - // Check if we have all info needed to render - if (this.state.currentTeam == null || this.state.currentUser == null) { - return (<div/>); - } - - this.badgesActive = false; - - // keep track of the first and last unread channels so we can use them to set the unread indicators - this.firstUnreadChannel = null; - this.lastUnreadChannel = null; - - // create elements for all 3 types of channels - const publicChannelItems = this.state.publicChannels.map(this.createChannelElement); - - const privateChannelItems = this.state.privateChannels.map(this.createChannelElement); - - const directMessageItems = this.state.directChannels.map((channel, index, arr) => { - return this.createChannelElement(channel, index, arr, this.handleLeaveDirectChannel); - }); - - // update the favicon to show if there are any notifications - var link = document.createElement('link'); - link.type = 'image/x-icon'; - link.rel = 'shortcut icon'; - link.id = 'favicon'; - if (this.badgesActive) { - link.href = '/static/images/favicon/redfavicon-16x16.png'; - } else { - link.href = '/static/images/favicon/favicon-16x16.png'; - } - var head = document.getElementsByTagName('head')[0]; - var oldLink = document.getElementById('favicon'); - if (oldLink) { - head.removeChild(oldLink); - } - head.appendChild(link); - - var directMessageMore = null; - if (this.state.hiddenDirectChannelCount > 0) { - directMessageMore = ( - <li key='more'> - <a - href='#' - onClick={this.showMoreDirectChannelsModal} - > - <FormattedMessage - id='sidebar.more' - defaultMessage='More ({count})' - values={{ - count: this.state.hiddenDirectChannelCount - }} - /> - </a> - </li> - ); - } - - let showChannelModal = false; - if (this.state.newChannelModalType !== '') { - showChannelModal = true; - } - - const createChannelTootlip = ( - <Tooltip id='new-channel-tooltip' > - <FormattedMessage - id='sidebar.createChannel' - defaultMessage='Create new channel' - /> - </Tooltip> - ); - const createGroupTootlip = ( - <Tooltip id='new-group-tooltip'> - <FormattedMessage - id='sidebar.createGroup' - defaultMessage='Create new group' - /> - </Tooltip> - ); - - const above = ( - <FormattedMessage - id='sidebar.unreadAbove' - defaultMessage='Unread post(s) above' - /> - ); - - const below = ( - <FormattedMessage - id='sidebar.unreadBelow' - defaultMessage='Unread post(s) below' - /> - ); - - return ( - <div - className='sidebar--left' - id='sidebar-left' - > - <NewChannelFlow - show={showChannelModal} - channelType={this.state.newChannelModalType} - onModalDismissed={this.hideNewChannelModal} - /> - <MoreDirectChannels - show={this.state.showDirectChannelsModal} - onModalDismissed={this.hideMoreDirectChannelsModal} - /> - - <SidebarHeader - teamDisplayName={this.state.currentTeam.display_name} - teamName={this.state.currentTeam.name} - teamType={this.state.currentTeam.type} - currentUser={this.state.currentUser} - /> - - <UnreadChannelIndicator - show={this.state.showTopUnread} - extraClass='nav-pills__unread-indicator-top' - text={above} - /> - <UnreadChannelIndicator - show={this.state.showBottomUnread} - extraClass='nav-pills__unread-indicator-bottom' - text={below} - /> - - <div - ref='container' - className='nav-pills__container' - onScroll={this.onScroll} - > - <ul className='nav nav-pills nav-stacked'> - <li> - <h4> - <FormattedMessage - id='sidebar.channels' - defaultMessage='Channels' - /> - <OverlayTrigger - delayShow={500} - placement='top' - overlay={createChannelTootlip} - > - <a - className='add-channel-btn' - href='#' - onClick={this.showNewChannelModal.bind(this, 'O')} - > - {'+'} - </a> - </OverlayTrigger> - </h4> - </li> - {publicChannelItems} - <li> - <a - href='#' - className='nav-more' - onClick={this.showMoreChannelsModal} - > - <FormattedMessage - id='sidebar.moreElips' - defaultMessage='More...' - /> - </a> - </li> - </ul> - - <ul className='nav nav-pills nav-stacked'> - <li> - <h4> - <FormattedMessage - id='sidebar.pg' - defaultMessage='Private Groups' - /> - <OverlayTrigger - delayShow={500} - placement='top' - overlay={createGroupTootlip} - > - <a - className='add-channel-btn' - href='#' - onClick={this.showNewChannelModal.bind(this, 'P')} - > - {'+'} - </a> - </OverlayTrigger> - </h4> - </li> - {privateChannelItems} - </ul> - <ul className='nav nav-pills nav-stacked'> - <li> - <h4> - <FormattedMessage - id='sidebar.direct' - defaultMessage='Direct Messages' - /> - </h4> - </li> - {directMessageItems} - {directMessageMore} - </ul> - </div> - </div> - ); - } -} - -Sidebar.defaultProps = { -}; -Sidebar.propTypes = { -}; |