PLT-4815 Refactor 'More Channels' modal into the new modal pattern (#4742)

* Refactor 'More Channels' modal into the new modal pattern

* Fix unit test

* Readded CSS changes
Этот коммит содержится в:
Joram Wilander
2016-12-15 11:40:46 -05:00
коммит произвёл enahum
родитель c35b95709e
Коммит 7f48a7fc9d
15 изменённых файлов: 197 добавлений и 198 удалений

Просмотреть файл

@@ -43,6 +43,8 @@ export default class UserList extends React.Component {
this.search = this.search.bind(this); this.search = this.search.bind(this);
this.loadComplete = this.loadComplete.bind(this); this.loadComplete = this.loadComplete.bind(this);
this.searchTimeoutId = 0;
const stats = TeamStore.getStats(this.props.params.team); const stats = TeamStore.getStats(this.props.params.team);
this.state = { this.state = {
@@ -148,14 +150,21 @@ export default class UserList extends React.Component {
const options = {}; const options = {};
options[UserSearchOptions.ALLOW_INACTIVE] = true; options[UserSearchOptions.ALLOW_INACTIVE] = true;
searchUsers( clearTimeout(this.searchTimeoutId);
term,
this.props.params.team, this.searchTimeoutId = setTimeout(
options, () => {
(users) => { searchUsers(
this.setState({loading: true, search: true, users}); term,
loadTeamMembersForProfilesList(users, this.props.params.team, this.loadComplete); this.props.params.team,
} options,
(users) => {
this.setState({loading: true, search: true, users});
loadTeamMembersForProfilesList(users, this.props.params.team, this.loadComplete);
}
);
},
Constants.SEARCH_TIMEOUT_MILLISECONDS
); );
} }

Просмотреть файл

@@ -13,6 +13,7 @@ import {searchUsers} from 'actions/user_actions.jsx';
import * as AsyncClient from 'utils/async_client.jsx'; import * as AsyncClient from 'utils/async_client.jsx';
import * as UserAgent from 'utils/user_agent.jsx'; import * as UserAgent from 'utils/user_agent.jsx';
import Constants from 'utils/constants.jsx';
import React from 'react'; import React from 'react';
import {Modal} from 'react-bootstrap'; import {Modal} from 'react-bootstrap';
@@ -32,6 +33,7 @@ export default class ChannelInviteModal extends React.Component {
this.search = this.search.bind(this); this.search = this.search.bind(this);
this.term = ''; this.term = '';
this.searchTimeoutId = 0;
const channelStats = ChannelStore.getStats(props.channel.id); const channelStats = ChannelStore.getStats(props.channel.id);
const teamStats = TeamStore.getCurrentStats(); const teamStats = TeamStore.getCurrentStats();
@@ -113,13 +115,20 @@ export default class ChannelInviteModal extends React.Component {
return; return;
} }
searchUsers( clearTimeout(this.searchTimeoutId);
term,
TeamStore.getCurrentId(), this.searchTimeoutId = setTimeout(
{not_in_channel_id: this.props.channel.id}, () => {
(users) => { searchUsers(
this.setState({search: true, users}); term,
} TeamStore.getCurrentId(),
{not_in_channel_id: this.props.channel.id},
(users) => {
this.setState({search: true, users});
}
);
},
Constants.SEARCH_TIMEOUT_MILLISECONDS
); );
} }

Просмотреть файл

@@ -13,6 +13,7 @@ import {removeUserFromChannel} from 'actions/channel_actions.jsx';
import * as AsyncClient from 'utils/async_client.jsx'; import * as AsyncClient from 'utils/async_client.jsx';
import * as UserAgent from 'utils/user_agent.jsx'; import * as UserAgent from 'utils/user_agent.jsx';
import Constants from 'utils/constants.jsx';
import React from 'react'; import React from 'react';
import {Modal} from 'react-bootstrap'; import {Modal} from 'react-bootstrap';
@@ -33,6 +34,7 @@ export default class ChannelMembersModal extends React.Component {
this.nextPage = this.nextPage.bind(this); this.nextPage = this.nextPage.bind(this);
this.term = ''; this.term = '';
this.searchTimeoutId = 0;
const stats = ChannelStore.getStats(props.channel.id); const stats = ChannelStore.getStats(props.channel.id);
@@ -128,13 +130,20 @@ export default class ChannelMembersModal extends React.Component {
return; return;
} }
searchUsers( clearTimeout(this.searchTimeoutId);
term,
TeamStore.getCurrentId(), this.searchTimeoutId = setTimeout(
{in_channel_id: this.props.channel.id}, () => {
(users) => { searchUsers(
this.setState({search: true, users}); term,
} TeamStore.getCurrentId(),
{in_channel_id: this.props.channel.id},
(users) => {
this.setState({search: true, users});
}
);
},
Constants.SEARCH_TIMEOUT_MILLISECONDS
); );
} }

Просмотреть файл

@@ -27,6 +27,8 @@ export default class MemberListTeam extends React.Component {
this.search = this.search.bind(this); this.search = this.search.bind(this);
this.loadComplete = this.loadComplete.bind(this); this.loadComplete = this.loadComplete.bind(this);
this.searchTimeoutId = 0;
const stats = TeamStore.getCurrentStats(); const stats = TeamStore.getCurrentStats();
this.state = { this.state = {
@@ -86,14 +88,21 @@ export default class MemberListTeam extends React.Component {
return; return;
} }
searchUsers( clearTimeout(this.searchTimeoutId);
term,
TeamStore.getCurrentId(), this.searchTimeoutId = setTimeout(
{}, () => {
(users) => { searchUsers(
this.setState({loading: true, search: true, users, term, teamMembers: Object.assign([], TeamStore.getMembersInTeam())}); term,
loadTeamMembersForProfilesList(users, TeamStore.getCurrentId(), this.loadComplete); TeamStore.getCurrentId(),
} {},
(users) => {
this.setState({loading: true, search: true, users, term, teamMembers: Object.assign([], TeamStore.getMembersInTeam())});
loadTeamMembersForProfilesList(users, TeamStore.getCurrentId(), this.loadComplete);
}
);
},
Constants.SEARCH_TIMEOUT_MILLISECONDS
); );
} }

Просмотреть файл

@@ -1,8 +1,6 @@
// Copyright (c) 2015 Mattermost, Inc. All Rights Reserved. // Copyright (c) 2015 Mattermost, Inc. All Rights Reserved.
// See License.txt for license information. // See License.txt for license information.
import $ from 'jquery';
import NewChannelFlow from './new_channel_flow.jsx';
import SearchableChannelList from './searchable_channel_list.jsx'; import SearchableChannelList from './searchable_channel_list.jsx';
import ChannelStore from 'stores/channel_store.jsx'; import ChannelStore from 'stores/channel_store.jsx';
@@ -13,11 +11,11 @@ import Constants from 'utils/constants.jsx';
import * as AsyncClient from 'utils/async_client.jsx'; import * as AsyncClient from 'utils/async_client.jsx';
import {joinChannel, searchMoreChannels} from 'actions/channel_actions.jsx'; import {joinChannel, searchMoreChannels} from 'actions/channel_actions.jsx';
import {FormattedMessage} from 'react-intl';
import {browserHistory} from 'react-router/es6';
import React from 'react'; import React from 'react';
import PureRenderMixin from 'react-addons-pure-render-mixin'; import PureRenderMixin from 'react-addons-pure-render-mixin';
import {Modal} from 'react-bootstrap';
import {FormattedMessage} from 'react-intl';
import {browserHistory} from 'react-router/es6';
const CHANNELS_CHUNK_SIZE = 50; const CHANNELS_CHUNK_SIZE = 50;
const CHANNELS_PER_PAGE = 50; const CHANNELS_PER_PAGE = 50;
@@ -29,7 +27,8 @@ export default class MoreChannels extends React.Component {
this.onChange = this.onChange.bind(this); this.onChange = this.onChange.bind(this);
this.handleJoin = this.handleJoin.bind(this); this.handleJoin = this.handleJoin.bind(this);
this.handleNewChannel = this.handleNewChannel.bind(this); this.handleHide = this.handleHide.bind(this);
this.handleExit = this.handleExit.bind(this);
this.nextPage = this.nextPage.bind(this); this.nextPage = this.nextPage.bind(this);
this.search = this.search.bind(this); this.search = this.search.bind(this);
@@ -38,8 +37,7 @@ export default class MoreChannels extends React.Component {
this.searchTimeoutId = 0; this.searchTimeoutId = 0;
this.state = { this.state = {
channelType: '', show: true,
showNewChannelModal: false,
search: false, search: false,
channels: null, channels: null,
serverError: null serverError: null
@@ -47,23 +45,24 @@ export default class MoreChannels extends React.Component {
} }
componentDidMount() { componentDidMount() {
const self = this;
ChannelStore.addChangeListener(this.onChange); ChannelStore.addChangeListener(this.onChange);
AsyncClient.getMoreChannelsPage(0, CHANNELS_CHUNK_SIZE * 2);
$(this.refs.modal).on('shown.bs.modal', () => {
AsyncClient.getMoreChannelsPage(0, CHANNELS_CHUNK_SIZE * 2);
});
$(this.refs.modal).on('show.bs.modal', (e) => {
const button = e.relatedTarget;
self.setState({channelType: $(button).attr('data-channeltype')});
});
} }
componentWillUnmount() { componentWillUnmount() {
ChannelStore.removeChangeListener(this.onChange); ChannelStore.removeChangeListener(this.onChange);
} }
handleHide() {
this.setState({show: false});
}
handleExit() {
if (this.props.onModalDismissed) {
this.props.onModalDismissed();
}
}
onChange(force) { onChange(force) {
if (this.state.search && !force) { if (this.state.search && !force) {
return; return;
@@ -83,11 +82,12 @@ export default class MoreChannels extends React.Component {
joinChannel( joinChannel(
channel, channel,
() => { () => {
$(this.refs.modal).modal('hide');
browserHistory.push(TeamStore.getCurrentTeamRelativeUrl() + '/channels/' + channel.name); browserHistory.push(TeamStore.getCurrentTeamRelativeUrl() + '/channels/' + channel.name);
if (done) { if (done) {
done(); done();
} }
this.handleHide();
}, },
(err) => { (err) => {
this.setState({serverError: err.message}); this.setState({serverError: err.message});
@@ -98,11 +98,6 @@ export default class MoreChannels extends React.Component {
); );
} }
handleNewChannel() {
$(this.refs.modal).modal('hide');
this.setState({showNewChannelModal: true});
}
search(term) { search(term) {
if (term === '') { if (term === '') {
this.onChange(true); this.onChange(true);
@@ -135,7 +130,7 @@ export default class MoreChannels extends React.Component {
<button <button
type='button' type='button'
className='btn btn-primary channel-create-btn' className='btn btn-primary channel-create-btn'
onClick={this.handleNewChannel} onClick={this.props.handleNewChannel}
> >
<FormattedMessage <FormattedMessage
id='more_channels.create' id='more_channels.create'
@@ -167,58 +162,38 @@ export default class MoreChannels extends React.Component {
} }
return ( return (
<div <Modal
className='modal fade more-channel__modal' dialogClassName='more-modal more-public-channels'
id='more_channels' show={this.state.show}
ref='modal' onHide={this.handleHide}
tabIndex='-1' onExited={this.handleExit}
role='dialog'
aria-hidden='true'
> >
<div className='modal-dialog'> <Modal.Header closeButton={true}>
<div className='modal-content'> <Modal.Title>
<div className='modal-header'> <FormattedMessage
<button id='more_channels.title'
type='button' defaultMessage='More Channels'
className='close' />
data-dismiss='modal' </Modal.Title>
> {createNewChannelButton}
<span aria-hidden='true'>{'×'}</span> </Modal.Header>
<span className='sr-only'> <Modal.Body>
<FormattedMessage <SearchableChannelList
id='more_channels.close' channels={this.state.channels}
defaultMessage='Close' channelsPerPage={CHANNELS_PER_PAGE}
/> nextPage={this.nextPage}
</span> search={this.search}
</button> handleJoin={this.handleJoin}
<h4 className='modal-title'> noResultsText={createChannelHelpText}
<FormattedMessage />
id='more_channels.title' {serverError}
defaultMessage='More Channels' </Modal.Body>
/> </Modal>
</h4>
{createNewChannelButton}
<NewChannelFlow
show={this.state.showNewChannelModal}
channelType={this.state.channelType}
onModalDismissed={() => this.setState({showNewChannelModal: false})}
/>
</div>
<div className='modal-body'>
<SearchableChannelList
channels={this.state.channels}
channelsPerPage={CHANNELS_PER_PAGE}
nextPage={this.nextPage}
search={this.search}
handleJoin={this.handleJoin}
noResultsText={createChannelHelpText}
/>
{serverError}
</div>
</div>
</div>
</div>
); );
} }
} }
MoreChannels.propTypes = {
onModalDismissed: React.PropTypes.func,
handleNewChannel: React.PropTypes.func
};

Просмотреть файл

@@ -35,6 +35,8 @@ export default class MoreDirectChannels extends React.Component {
this.nextPage = this.nextPage.bind(this); this.nextPage = this.nextPage.bind(this);
this.search = this.search.bind(this); this.search = this.search.bind(this);
this.searchTimeoutId = 0;
this.state = { this.state = {
users: null, users: null,
loadingDMChannel: -1, loadingDMChannel: -1,
@@ -168,19 +170,26 @@ export default class MoreDirectChannels extends React.Component {
teamId = TeamStore.getCurrentId(); teamId = TeamStore.getCurrentId();
} }
searchUsers( clearTimeout(this.searchTimeoutId);
term,
teamId, this.searchTimeoutId = setTimeout(
{}, () => {
(users) => { searchUsers(
for (let i = 0; i < users.length; i++) { term,
if (users[i].id === UserStore.getCurrentId()) { teamId,
users.splice(i, 1); {},
break; (users) => {
for (let i = 0; i < users.length; i++) {
if (users[i].id === UserStore.getCurrentId()) {
users.splice(i, 1);
break;
}
}
this.setState({search: true, users});
} }
} );
this.setState({search: true, users}); },
} Constants.SEARCH_TIMEOUT_MILLISECONDS
); );
} }

Просмотреть файл

@@ -32,7 +32,6 @@ import GetPublicLinkModal from 'components/get_public_link_modal.jsx';
import GetTeamInviteLinkModal from 'components/get_team_invite_link_modal.jsx'; import GetTeamInviteLinkModal from 'components/get_team_invite_link_modal.jsx';
import EditPostModal from 'components/edit_post_modal.jsx'; import EditPostModal from 'components/edit_post_modal.jsx';
import DeletePostModal from 'components/delete_post_modal.jsx'; import DeletePostModal from 'components/delete_post_modal.jsx';
import MoreChannelsModal from 'components/more_channels.jsx';
import TeamSettingsModal from 'components/team_settings_modal.jsx'; import TeamSettingsModal from 'components/team_settings_modal.jsx';
import RemovedFromChannelModal from 'components/removed_from_channel_modal.jsx'; import RemovedFromChannelModal from 'components/removed_from_channel_modal.jsx';
import ImportThemeModal from 'components/user_settings/import_theme_modal.jsx'; import ImportThemeModal from 'components/user_settings/import_theme_modal.jsx';
@@ -181,7 +180,6 @@ export default class NeedsTeam extends React.Component {
<LeaveTeamModal/> <LeaveTeamModal/>
<ImportThemeModal/> <ImportThemeModal/>
<TeamSettingsModal/> <TeamSettingsModal/>
<MoreChannelsModal/>
<EditPostModal/> <EditPostModal/>
<DeletePostModal/> <DeletePostModal/>
<RemovedFromChannelModal/> <RemovedFromChannelModal/>

Просмотреть файл

@@ -167,7 +167,7 @@ export default class SearchableChannelList extends React.Component {
return ( return (
<div className='filtered-user-list'> <div className='filtered-user-list'>
<div className='filter-row'> <div className='filter-row'>
<div className='col-sm-6'> <div className='col-sm-12'>
<input <input
ref='filter' ref='filter'
className='form-control filter-textbox' className='form-control filter-textbox'

Просмотреть файл

@@ -4,8 +4,6 @@
import UserList from 'components/user_list.jsx'; import UserList from 'components/user_list.jsx';
import * as Utils from 'utils/utils.jsx'; import * as Utils from 'utils/utils.jsx';
import Constants from 'utils/constants.jsx';
const KeyCodes = Constants.KeyCodes;
import $ from 'jquery'; import $ from 'jquery';
import React from 'react'; import React from 'react';
@@ -21,8 +19,6 @@ export default class SearchableUserList extends React.Component {
this.nextPage = this.nextPage.bind(this); this.nextPage = this.nextPage.bind(this);
this.previousPage = this.previousPage.bind(this); this.previousPage = this.previousPage.bind(this);
this.doSearch = this.doSearch.bind(this); this.doSearch = this.doSearch.bind(this);
this.onSearchBoxKeyPress = this.onSearchBoxKeyPress.bind(this);
this.onSearchBoxChange = this.onSearchBoxChange.bind(this);
this.nextTimeoutId = 0; this.nextTimeoutId = 0;
@@ -71,20 +67,6 @@ export default class SearchableUserList extends React.Component {
} }
} }
onSearchBoxKeyPress(e) {
if (e.charCode === KeyCodes.ENTER) {
e.preventDefault();
this.doSearch();
}
}
onSearchBoxChange(e) {
if (e.target.value === '') {
this.props.search(''); // clear search
this.setState({page: 0, search: false});
}
}
render() { render() {
let nextButton; let nextButton;
let previousButton; let previousButton;
@@ -158,28 +140,14 @@ export default class SearchableUserList extends React.Component {
return ( return (
<div className='filtered-user-list'> <div className='filtered-user-list'>
<div className='filter-row'> <div className='filter-row'>
<div className='col-xs-9 col-sm-5'> <div className='col-xs-12'>
<input <input
ref='filter' ref='filter'
className='form-control filter-textbox' className='form-control filter-textbox'
placeholder={Utils.localizeMessage('filtered_user_list.search', 'Press enter to search')} placeholder={Utils.localizeMessage('filtered_user_list.search', 'Search users')}
onKeyPress={this.onSearchBoxKeyPress} onInput={this.doSearch}
onChange={this.onSearchBoxChange}
/> />
</div> </div>
<div className='col-xs-3 col-sm-2 filter-button'>
<button
type='button'
className='btn btn-primary'
onClick={this.doSearch}
disabled={this.props.users == null}
>
<FormattedMessage
id='filtered_user_list.searchButton'
defaultMessage='Search'
/>
</button>
</div>
<div className='col-sm-12'> <div className='col-sm-12'>
<span className='member-count pull-left'>{count}</span> <span className='member-count pull-left'>{count}</span>
</div> </div>

Просмотреть файл

@@ -5,6 +5,7 @@ import $ from 'jquery';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import NewChannelFlow from './new_channel_flow.jsx'; import NewChannelFlow from './new_channel_flow.jsx';
import MoreDirectChannels from './more_direct_channels.jsx'; import MoreDirectChannels from './more_direct_channels.jsx';
import MoreChannels from 'components/more_channels.jsx';
import SidebarHeader from './sidebar_header.jsx'; import SidebarHeader from './sidebar_header.jsx';
import UnreadChannelIndicator from './unread_channel_indicator.jsx'; import UnreadChannelIndicator from './unread_channel_indicator.jsx';
import TutorialTip from './tutorial/tutorial_tip.jsx'; import TutorialTip from './tutorial/tutorial_tip.jsx';
@@ -19,7 +20,6 @@ import * as AsyncClient from 'utils/async_client.jsx';
import * as Utils from 'utils/utils.jsx'; import * as Utils from 'utils/utils.jsx';
import * as ChannelUtils from 'utils/channel_utils.jsx'; import * as ChannelUtils from 'utils/channel_utils.jsx';
import * as ChannelActions from 'actions/channel_actions.jsx'; import * as ChannelActions from 'actions/channel_actions.jsx';
import * as UserAgent from 'utils/user_agent.jsx';
import Constants from 'utils/constants.jsx'; import Constants from 'utils/constants.jsx';
@@ -53,6 +53,7 @@ export default class Sidebar extends React.Component {
this.handleLeaveDirectChannel = this.handleLeaveDirectChannel.bind(this); this.handleLeaveDirectChannel = this.handleLeaveDirectChannel.bind(this);
this.showMoreChannelsModal = this.showMoreChannelsModal.bind(this); this.showMoreChannelsModal = this.showMoreChannelsModal.bind(this);
this.hideMoreChannelsModal = this.hideMoreChannelsModal.bind(this);
this.showNewChannelModal = this.showNewChannelModal.bind(this); this.showNewChannelModal = this.showNewChannelModal.bind(this);
this.hideNewChannelModal = this.hideNewChannelModal.bind(this); this.hideNewChannelModal = this.hideNewChannelModal.bind(this);
this.showMoreDirectChannelsModal = this.showMoreDirectChannelsModal.bind(this); this.showMoreDirectChannelsModal = this.showMoreDirectChannelsModal.bind(this);
@@ -72,6 +73,7 @@ export default class Sidebar extends React.Component {
const state = this.getStateFromStores(); const state = this.getStateFromStores();
state.newChannelModalType = ''; state.newChannelModalType = '';
state.showDirectChannelsModal = false; state.showDirectChannelsModal = false;
state.showMoreChannelsModal = false;
state.loadingDMChannel = -1; state.loadingDMChannel = -1;
this.state = state; this.state = state;
} }
@@ -340,13 +342,11 @@ export default class Sidebar extends React.Component {
} }
showMoreChannelsModal() { showMoreChannelsModal() {
// manually show the modal because using data-toggle messes with keyboard focus when the modal is dismissed this.setState({showMoreChannelsModal: true});
$('#more_channels').modal({'data-channeltype': 'O'}).modal('show'); }
$('#more_channels').on('shown.bs.modal', () => {
if (!UserAgent.isMobile()) { hideMoreChannelsModal() {
$('#more_channels input').focus(); this.setState({showMoreChannelsModal: false});
}
});
} }
showNewChannelModal(type) { showNewChannelModal(type) {
@@ -552,6 +552,7 @@ export default class Sidebar extends React.Component {
</li> </li>
); );
} }
render() { render() {
// Check if we have all info needed to render // Check if we have all info needed to render
if (this.state.currentTeam == null || this.state.currentUser == null) { if (this.state.currentTeam == null || this.state.currentUser == null) {
@@ -721,12 +722,24 @@ export default class Sidebar extends React.Component {
if (this.state.showDirectChannelsModal) { if (this.state.showDirectChannelsModal) {
moreDirectChannelsModal = ( moreDirectChannelsModal = (
<MoreDirectChannels <MoreDirectChannels
show={true}
onModalDismissed={this.hideMoreDirectChannelsModal} onModalDismissed={this.hideMoreDirectChannelsModal}
/> />
); );
} }
let moreChannelsModal;
if (this.state.showMoreChannelsModal) {
moreChannelsModal = (
<MoreChannels
onModalDismissed={this.hideMoreChannelsModal}
handleNewChannel={() => {
this.hideMoreChannelsModal();
this.showNewChannelModal(Constants.OPEN_CHANNEL);
}}
/>
);
}
return ( return (
<div <div
className='sidebar--left' className='sidebar--left'
@@ -739,6 +752,7 @@ export default class Sidebar extends React.Component {
onModalDismissed={this.hideNewChannelModal} onModalDismissed={this.hideNewChannelModal}
/> />
{moreDirectChannelsModal} {moreDirectChannelsModal}
{moreChannelsModal}
<SidebarHeader <SidebarHeader
teamDisplayName={this.state.currentTeam.display_name} teamDisplayName={this.state.currentTeam.display_name}

Просмотреть файл

@@ -1259,7 +1259,7 @@
"filtered_user_list.countTotal": "{count} {count, plural, =0 {0 members} one {member} other {members}} of {total} total", "filtered_user_list.countTotal": "{count} {count, plural, =0 {0 members} one {member} other {members}} of {total} total",
"filtered_user_list.countTotalPage": "{startCount, number} - {endCount, number} {count, plural, =0 {0 members} one {member} other {members}} of {total} total", "filtered_user_list.countTotalPage": "{startCount, number} - {endCount, number} {count, plural, =0 {0 members} one {member} other {members}} of {total} total",
"filtered_user_list.member": "Member", "filtered_user_list.member": "Member",
"filtered_user_list.search": "Press enter to search", "filtered_user_list.search": "Search users",
"filtered_user_list.searchButton": "Search", "filtered_user_list.searchButton": "Search",
"filtered_user_list.show": "Filter:", "filtered_user_list.show": "Filter:",
"filtered_user_list.team_only": "Members of this Team", "filtered_user_list.team_only": "Members of this Team",

Просмотреть файл

@@ -483,6 +483,7 @@
.filter-row { .filter-row {
@include clearfix; @include clearfix;
margin: 5px 0 10px; margin: 5px 0 10px;
width: 300px;
} }
.member-count { .member-count {

Просмотреть файл

@@ -75,12 +75,6 @@
} }
.app__body { .app__body {
.more-modal {
.filter-row {
width: 330px;
}
}
.edit-modal-body { .edit-modal-body {
.custom-textarea { .custom-textarea {
max-height: 30vh; max-height: 30vh;
@@ -1172,6 +1166,19 @@
@media screen and (max-width: 640px) { @media screen and (max-width: 640px) {
.app__body { .app__body {
.modal {
.more-modal {
.modal-body {
max-height: calc(100vh - 62px);
padding-bottom: 5px;
}
.more-modal__list {
max-height: calc(100vh - 230px);
}
}
}
.post { .post {
.open { .open {
> .dropdown-menu__content { > .dropdown-menu__content {
@@ -1329,10 +1336,13 @@
@media screen and (max-width: 550px) { @media screen and (max-width: 550px) {
.app__body { .app__body {
.more-modal { .more-modal {
.filter-row {
width: 100%;
}
&.more-direct-channels { &.more-direct-channels {
.filter-row { .filter-row {
padding-bottom: 50px; padding-bottom: 50px;
width: 100%;
} }
.member-show { .member-show {
@@ -1391,22 +1401,6 @@
} }
.app__body { .app__body {
.more-modal {
.modal-body {
padding-bottom: 5px;
}
.more-modal__list {
max-height: calc(100vh - 260px);
}
&.more-direct-channels {
.more-modal__list {
max-height: calc(100vh - 295px);
}
}
}
.modal { .modal {
&.more-channel__modal { &.more-channel__modal {
.more-modal__list { .more-modal__list {

Просмотреть файл

@@ -4,6 +4,8 @@
import AppDispatcher from '../dispatcher/app_dispatcher.jsx'; import AppDispatcher from '../dispatcher/app_dispatcher.jsx';
import EventEmitter from 'events'; import EventEmitter from 'events';
import TeamStore from 'stores/team_store.jsx';
var Utils; var Utils;
import {ActionTypes, Constants} from 'utils/constants.jsx'; import {ActionTypes, Constants} from 'utils/constants.jsx';
const NotificationPrefs = Constants.NotificationPrefs; const NotificationPrefs = Constants.NotificationPrefs;
@@ -233,24 +235,25 @@ class ChannelStoreClass extends EventEmitter {
return this.myChannelMembers; return this.myChannelMembers;
} }
storeMoreChannels(channels) { storeMoreChannels(channels, teamId = TeamStore.getCurrentId()) {
const newChannels = {}; const newChannels = {};
for (let i = 0; i < channels.length; i++) { for (let i = 0; i < channels.length; i++) {
newChannels[channels[i].id] = channels[i]; newChannels[channels[i].id] = channels[i];
} }
this.moreChannels = Object.assign({}, this.moreChannels, newChannels); this.moreChannels[teamId] = Object.assign({}, this.moreChannels[teamId], newChannels);
} }
removeMoreChannel(channelId) { removeMoreChannel(channelId, teamId = TeamStore.getCurrentId()) {
Reflect.deleteProperty(this.moreChannels, channelId); Reflect.deleteProperty(this.moreChannels[teamId], channelId);
} }
getMoreChannels() { getMoreChannels(teamId = TeamStore.getCurrentId()) {
return Object.assign({}, this.moreChannels); return Object.assign({}, this.moreChannels[teamId]);
} }
getMoreChannelsList() { getMoreChannelsList(teamId = TeamStore.getCurrentId()) {
return Object.keys(this.moreChannels).map((cid) => this.moreChannels[cid]); const teamChannels = this.moreChannels[teamId] || {};
return Object.keys(teamChannels).map((cid) => teamChannels[cid]);
} }
storeStats(stats) { storeStats(stats) {

Просмотреть файл

@@ -863,7 +863,8 @@ export const Constants = {
MENTION_SPECIAL: 'mention.special', MENTION_SPECIAL: 'mention.special',
DEFAULT_NOTIFICATION_DURATION: 5000, DEFAULT_NOTIFICATION_DURATION: 5000,
STATUS_INTERVAL: 60000, STATUS_INTERVAL: 60000,
AUTOCOMPLETE_TIMEOUT: 100 AUTOCOMPLETE_TIMEOUT: 100,
SEARCH_TIMEOUT_MILLISECONDS: 100
}; };
export default Constants; export default Constants;